Change Color of the Label and Input field in UI for Form View – Part 1
In CRM UI it is possible to customize the fields and labels so that the properties of fields or labels can be adjusted as we want. It is able to change the following properties of a field or label:
- Color.
- Border of text field.
- Type of input text field (Password).
- Alignment, etc.
To set the properties you should have a little knowledge of html tags. The iterator class should be created for changing the property. The iterator class is triggered for each of the label and field that has to be displayed in the UI. Ex: Assume you have two fields ID and Name, iterator class is called twice for each of the fields, i.e., one for label and input field. So iterator is called 4 times.
Procedure:
Step 1: Assume we have a BSP Application. Create a form view with a value node called ‘COUNTRY’, with four attributes.
Step 2: Create a Z Class in SE24, say ZL_THTMLB_FORM_ITERATOR_SAMPLE. Add an interface IF_CHTMLB_FORM_ITERATOR.
Step 3: Implement the method RENDER_CELL_START of interface IF_CHTMLB_FORM_ITERATOR.
METHOD if_chtmlb_form_iterator~render_cell_start.
DATA: lv_bee TYPE REF TO cl_bsp_bee_table.
DATA: lv_html TYPE string.
* Create the replacement element
CREATE OBJECT lv_bee.
* Check whether this class is called for label or input field
IF iv_element_name = ‘label’.
* Set the color of the label to red using the style tag
” Here ‘C1_W1_V2_V5_thtmlb_label_4’ is the ID for the label ‘Name’
lv_html = ‘<style> label#C1_W1_V2_V5_thtmlb_label_4{ color:#FF0000; } </style>’.
ELSEIF iv_element_name = ‘inputfield’.
* Set the color of input field to red
” Here ‘C1_W1_V2_V5_country_countryname’ is the ID for input field
lv_html = ‘<style> input#C1_W1_V2_V5_country_countryname{ border-color:red;} </style>’.
ENDIF.
* Add the new html code
lv_bee->add_html( html = lv_html level = 1 ).
lv_bee->add_bee( bee = iv_element_bee level = 2 ).
* Return the new html
ev_replacement_bee = lv_bee.
ENDMETHOD.
Here I am changing the color of attribute country name. Now the question is how to get ID’s of label and input field. Follow the next step.
Step 4: Open the standard method IF_BSP_ELEMENT~DO_AT_BEGINNING of class CL_THTMLB_LABEL. This method gets called for each of the labels that is going to be displayed in the UI.
Put breakpoint at this method at line 16 (right after the method me->resolve_model_binding( ).). Watch the values of me->for and me->id variables.
In my UI I have four fields, so this method gets called for four times.
For attribute Country ID
For attribute Country Code
For attribute Country Name
For attribute Country Language
ME->ID holds the label ID. This ID should be used in RENDER_CELL_START method.
Note: In the same way to find the ID for the input fields, debug the method IF_BSP_ELEMENT~DO_AT_BEGINNING of class CL_THTMLB_INPUTFIELD. Check the field ME->ID. Even this method gets called for each of the field.
Step 5: Change the HTM file of form view to set the iterator.
Make the change as shown in the snap.
Line 6 -> Define a reference variable of the class which you created earlier.
Line 9 -> Create object.
Line 11 -> Set the iterator.
For Changing other properties of the input field or label: Change Property of the Label and Input field in UI for Form View – Part 2
Snapshot:
Hi,
Just wanted to recommend this excellent blog post from Andrei Vishnevsky who came up with what I find to be a better solution to achieve the same result (i.e. without turning your configurable html view into a static page because you hardcoded the field IDs):
Form Iterator and How It Should Be Cooked
Sorry,
Nicolas.
Hi,
I agree with Andrei Vishnevsky and even I have tried with his solution. I had a requirement where the border color of input field and font color of label should be changed to red. But with that solution I was not able to change the border color of the input field to red color. So I tried with my own solution.
Regards,
Satish D R
Hi Satish,
Thanks! Good to know that you read Andrei's document first. I would have mentioned it in your blog post, explaining the limitations of his method then 😉
Regards,
Nicolas.
Hi Nicolas,
May I know the limitations of this method?
Regards,
Satish D R
Hello, Satish.
I will try to explain limitations which are in your solution.
First, as Nick mentioned, you use static id for the element. E.g. constant. But you've mentioned that standard use resolve_binding method. And this is the case. Because id is dynamic. It may depend on the way user reach your view/element or settings (sequence) in navigation bar profile. The better way is to use IV_ELEMENT_BEE->IF_BSP_ELEMENT~ID. It has exact id of the element.
Second limitation is that in the code snippet you've provided you did not check any parameters to make sure that this is exact cell which you need (i.e. Country). You're applying your code to any cell on the view. To overcome this limitation it's better to check IV_BINDING_STRING to make sure you're dealing with the exact field.
IMHO, the use case which is described in this blog duplicates the use case # 1 in my blog post.
Hi Andrei,
Thanks for your better solutions. I tried with your solutions. IV_ELEMENT_BEE->IF_BSP_ELEMENT~ID is an interface so I used casting. I faced a problem with getting the ID of the label. But using the same procedure I got ID for inputfield.
I declared two reference variable lr_label and lr_inputfield of type CL_THTMLB_LABEL and CL_THTMLB_INPUTFIELD respectively.
My logic:
CASE iv_binding_string.
WHEN '//COUNTRY/COUNTRYNAME'.
IF iv_element_name = 'label'.
lr_label ?= iv_element_bee.
lv_id = lr_label->if_bsp_element~id.
ELSEIF iv_elemet_name = 'inputfield'.
lr_inputfield ?= iv_element_bee.
lv_id = lr_inputfield->if_bsp_element~id.
ENDIF.
ENDCASE.
When processing for the label I got empty value in lr_label->if_bsp_element~id, but while processing inputfield, I got correct ID.
Why it is so? Am I going wrong somewhere?
Regards,
Satish
Satish,
in your post you've actually mentioned the answer to your question. Where do you get the id in your scenario? Correct. In method resolve_model_binding. So why don't you call this method in render_cell_start for the label? No problem. But most likely you'll get a short dump saying that there is a NULL reference. It's because the label doesn't have m_page_context at this point yet. And it can not generate the id because of this (giving the dump). But it can be fixed. Just pass the page as an importing parameter to your iterator object while creating it. Something like:
where iv_page is type ref to IF_BSP_PAGE. Then in CONSTRUCTOR you can store the page context in a class attribute, for example, gv_page_context (as type ref to IF_BSP_PAGE_CONTEXT):
Then in RENDER_CELL_START:
after this lv_label->id has a valid id.
Hi Satish,
I'm very sorry but I was in a meeting when I received the notification for your last question. .. And I forgot to answer once the meeting was over. Apologize.
Anyway I couldn't have answered anything better than what has just been said (thanks for your participation Andrei!).
Cheers,
Nick.
Hi Nicolas,
Thanks for your support.
Regards,
Satish
Hi Satish
Thanks for the blog . It is really helpful.
I have a doubt .
You are setting iterator class instance in the layout of form view. That is fine and working.
Suppose if we try to change the color of FIELD ( ie., column ) in result view ( SEARCH component ) created by wizard ( Ehp1 ) , there is no HTM page for this view.
Then where to pass the iterator instance ???
Do you have any idea on this . I tried a lot but couldn't get any solution.
Regards
Dinesh Gurram
Hi Dinesh,
Create an reference variable in the implementation class of that view.
Say: gr_iterator TYPE REF TO your_zclass_name.
In DO_PREPARE_OUTPUT create the object.
CREATE OBJECT gr_iterator.
Implement the zclass using the interface IF_HTMLB_TABLEVIEW_ITERATOR.
Now implement the method IF_HTMLB_TABLEVIEW_ITERATOR~RENDER_CELL_START in the same way.
Regards,
Satish
Hi Satish
Thanks for the reply
I tried in that way but couldn't succeed. Because here we are just getting the instance of the Zclass but we are not setting that instance anywhere so unable to get the required output. .
Setting the iterator class instance is the major problem here from my side . .
Hi Dinesh,
Forgot to mention that point.
In HTM file of the result view there is a tag chtmlb:configCellerator which describes the properties of its view. So you can use this tag to set the iterator using the attribute "iterator". Just add "iterator" attribute to this tag along with other attributes.
<chtmlb:configCellerator iterator = "<%= controller->gr_iterator %>" />
Regards,
Satish
Hi Satish
My question is that if the search page is created through wizard ( Ehp1 ) then there will be no HTM page for the view ( Both Search view & Result view ) .
Here the problem starts that where to set the iterator instance . .
Hope i am clear this time
Regards
Dinesh Gurram
Hi Dinesh,
For the form view you can set in DO_PREPARE_OUPUT method:
IF iv_first_time = abap_true.
CREATE OBJECT gr_form_iterator.
cl_chtmlb_config=>set_iterator( gr_form_iterator ).
ENDIF.
For the table view you can set only using the tag that is found in HTM file.
Regards,
Satish