Conditional formatting for Tables in WebUI
In comments to one of my blog posts I indicated that conditional formatting in tables was quite awaited feature for me. There are plenty of scenarios when we need to highlight or indicate or distinguish something in tables in WebUI. And previous tricks were quite difficult to implement.
Just take a look at these discussions:
How to set particular column or cell color of result view in CRM WEB UI ?
How to set background color of cell to red
I expected that standard implementation would finally take into account already existed P_STYLE and/or P_CLASS changing parameters from IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_CELL_START method. But it does not. I’ve already described the issue with table iterator and those parameters in this message
And here is the good news. As mentioned in SAP User Interface Technologies – Road Map (page 25) “Conditional formatting for Tables” is already available. Partially I think… Now it’s much easier to format tables based on some conditions. But “formatting” here means only table cell coloring. I was really surprised because I (again) expected more flexibility in formatting like an option to set styles or CSS classes to cells or rows. Yes, setting background color covers most of the needs. But “coloring” is not “formatting”.
To be completely sure that there is nothing else in shortly upcoming SPs I raised OSS message and received the oficial answer:
As per development there’s no new development considered regarding “Conditional Formatting of the cellerator’s cells” at this current time and there is no further information concerning the topic.
So how to do conditional formatting? The note 1937399 – Conditional formatting of the table cells introduces this feature. Need to admit that this feature is available starting from SAP CRM 7.0 Ehp1. How-To Guide is attached to the note. With this note we get one more property for table cell. Property name is
if_bsp_wd_model_setter_getter=>fp_bgcolor (or simply ‘backgroundColor’). We need to return color name or RGB hexcode as a string (for example ‘pink’ or ‘#FFC0CB’).
So some GET_P method should simply look like:
METHOD get_p_<your_cell>.
IF iv_property EQ if_bsp_wd_model_setter_getter=>fp_bgcolor
AND <your_condition>.
rv_value = 'pink'. " or '#FFC0CB'
ENDIF.
ENDMETHOD.
The result is:
Cool! But what about a row? Certainly we can go and define as many GET_P methods to return this property as many attributes we have. And implement new GET_P method for each and every new attribute we add in the future.
Here I would suggest another way.
- Define static attribute in your context node class which represents table of pairs ‘index; color’ for buffering.
- Redefine GET_P_T_TABLE method of your context node class (inherited from CL_BSP_WD_CONTEXT_NODE_TV class).
- Handle the backgroundColor property in this method passing all other properties to super-method.
- For each new index trigger your condition and store the result in the index-color table.
- Retrieve the color from the table if possible.
Here is a code example:
METHOD get_p_t_table.
DATA: lr_current TYPE REF TO if_bol_bo_property_access.
FIELD-SYMBOLS: <fs_color> TYPE zts_color.
IF iv_property = if_bsp_wd_model_setter_getter=>fp_bgcolor.
READ TABLE gt_colors ASSIGNING <fs_color> WITH KEY index = iv_index.
IF <fs_color> IS NOT ASSIGNED.
APPEND INITIAL LINE TO gt_colors ASSIGNING <fs_color>.
<fs_color>-index = iv_index.
lr_current = me->get_bo_by_index(
iv_index = iv_index
iv_change_focus = abap_false ).
IF lr_current IS BOUND.
* There are some logic and conditions
* Here it's based on current line entity in zcl_util_misc=>get_color as an example
<fs_color>-color = zcl_util_misc=>get_color( lr_current ).
ENDIF.
ENDIF.
rv_value = <fs_color>-color.
ELSE.
CALL METHOD super->get_p_t_table
EXPORTING
component = component
iv_index = iv_index
iv_property = iv_property
iv_display_mode = iv_display_mode
RECEIVING
rv_value = rv_value.
ENDIF.
ENDMETHOD.
Where types and attribute are defined as:
PRIVATE SECTION.
TYPES:
BEGIN OF zts_color,
index TYPE i,
color TYPE string,
END OF zts_color .
TYPES:
ztt_color TYPE TABLE OF zts_color .
DATA gt_colors TYPE ztt_color .
Also we have to clean up gt_colors somewhere after completing the output. Because otherwise there will be issues during next rendering. For example when sorting is applied to this UI table. I used method CLEAR_LAST_LINE in context node class which is also inherited from CL_BSP_WD_CONTEXT_NODE_TV. It’s called from handler of CL_BSP_WD_VIEW_CONTROLLER~OUTPUT_RENDERED event and satisfied my needs.
And here is the result:
Sure enough, it’s easier and much better than previous approaches. But still there is a lack of flexibility… Anyway it should cover most of requirements. At least I hope so.
Awsme will try it today!
Hi Andrei,
Really nice info. Thanks for this.
Thanks for sharing!!
Hi Andrei,
Thanks for very informative blog!
We had an issue with iterator for a table view when we upgraded to from CRM 7.0 to CRM 7.0 EhP2. The table entries were displaying HTML tags instead of changing the font color. The iterator code was adding <htmlb:textView> with HTML code into the cells. Even with encoding forced this was displaying HTML tags.
When we raised an OSS message we were suggested with the note which you have mentioned in the blog. Since it was a critical issue we went ahead with implementing BSP HTML BEE method instead. I now think I should have gone ahead with SAP's suggestion 🙁 instead.
Regards,
Mahesh
Hello Mahesh.
It's always better to follow an SAP's suggestion I think. Implementation of mentioned note took me a few minutes. Another hour to implement the method and provide a color back and test it. Playing with iterator was always quite painful. I prefer to work with bsp-elements and avoid plain HTML there (I suppose you mean this under "BSP HTML BEE").
Hi Andrei,
I couldn't agree with you more! With Iterators the code looked very much clumsy and more over the standard approach seems to be very easy to implement.
Regards,
Mahesh
Hi Andrei Vishnevsky
It's very useful information and marketing activity planner. Thanks for sharing
Nice one! Thank you!
Hi,
I tried this one but does not work. its show this error.
FP_BGCOLOR is unknown.
Hi Gezim,
You might have to implement note 1937399 to get FP_BGCOLOR property.
Thanks,
Ritu
Thank you Ritu
Hi Andrei Vishnevsky
Nice blog, i was trying to do similar but want to open external web link based on different value in column cell. Could you please suggest/guide how to achieve that.
- L.Will
Hello Lisha,
I see you've already opened a discussion. It's a correct way to ask questions not related to a blog topic directly. And you already got an answer there as well. But I proposed my vision for a solution of your question there 🙂
Great! Thank you for sharing.
I have a problem with the AET added Table View, when I click edit button. In the method GET_P_T_TABLE, the backgroundcolour property is not handled. I have checked few AET Tables ( View ) and they all behave the same.
The Objective is to set the color of the row while the view is in edit mode.
Please assist.
Regards,
Keketso
Hi Andrei Vishnevsky,
Got stuck with a unique requirement where I need to display TextView in the child record of Tree View. I achieved the requirement simply by implementing GET_P* method of child attribute but the issue I am facing is text is getting restricted to first column only.
Could you please help me in this.
Thanks!
Sonu