I have a simple example to take you through the dynamic programming. This involves dynamic creation of Contexts and UI elements. In the example we will maintain a simple list, a list of American presidents. The list will be shown on a table UI element. We will be able add to the list any number of presidents we want.
We can create as many new input UI element as the user wants.
The addition process is not by creating new empty editable rows in the table but creating new text input UI elements that we create as required.
The layout for the screen is as below:
And the context:
The user enters the number of new presidents she wants to add and clicks the add button. The action add will do the followings:
- Read the value of number.
- Reset the number back to 1.
- Remove previous text input UI element if there are any
- Create new context to capture text input
- Add text input UI element
1) & 2) should be easy. The new text input UI elements that are created are within a group container UI element. For 3) removing UI elements we just have to remove the group container.method ONACTIONADD .* Refresh screen with new president additions* Get number of new cohort addins to createget_new_additions( ).* Reset new additionsreset_new_addition( ).* Remove group cohort from layoutremove_group_presidents( ).* Manage dynamic contextsmanage_dynamic_contexts( ).* Add new text input UI elementswd_this->add_new_president_group( ).endmethod.
The input fields need to be tied to a context attribute. We have the following context design that needs to be created dynamically.method REMOVE_GROUP_PRESIDENTS .DATA l_o_container TYPE REF TO cl_wd_uielement_container.l_o_container ?= wd_this->o_view->get_element( 'ROOTUIELEMENTCONTAINER' ).l_o_container->remove_child( id = 'GRP_PRESIDENT01' ).l_o_container->remove_child( id = 'HG_PRESIDENT01' ). “Horizontal Gutterendmethod.
For 4) we create the context dynamically and also store the context names in an internal table for management.
Some comments about parameters of the method ADD_NEW_CHILD_NODE of the interface IF_WD_CONTEXT_NODE_INFO. Option IS_MANDATORY is same as Selection property of context = 1..1. Option IS_STATIC needs to be false otherwise we won’t be able to delete it later.METHOD manage_dynamic_contexts .
DATA l_str_node_name TYPE string.DATA l_parent_node_info TYPE REF TO if_wd_context_node_info.DATA l_child_node_info TYPE REF TO if_wd_context_node_info.DATA l_cohort_number(6).
DATA l_str_cohort_name TYPE string.DATA l_attr_info TYPE wdr_context_attribute_info.* Access the parent nodel_parent_node_info = wd_context->get_node_info( ).delete_existing_nodes( l_parent_node_info ).l_attr_info-name = 'NAME'.l_attr_info-type_name = 'STRING'.
DO wd_this->new_additions TIMES.
WRITE sy-index TO l_cohort_number.CONDENSE l_cohort_number.CONCATENATE 'PRESIDENT' l_cohort_number INTO l_str_cohort_name.* add new node for each presidentCALL METHOD l_parent_node_info->add_new_child_nodeEXPORTING* SUPPLY_METHOD =* SUPPLY_OBJECT =* DISPOSE_METHODS =* DISPOSE_OBJECT =name = l_str_cohort_nameis_mandatory = abap_true* IS_MANDATORY_SELECTION = ABAP_TRUEis_multiple = abap_falseis_multiple_selection = abap_falseis_singleton = abap_trueis_initialize_lead_selection = abap_trueis_static = abap_falseRECEIVINGchild_node_info = l_child_node_info.CALL METHOD l_child_node_info->add_attributeEXPORTINGattribute_info = l_attr_info.APPEND l_str_cohort_name TO wd_this->t_dynamic_nodes.
ENDDO.ENDMETHOD.
The last thing 5) to do is to add the new text input UI elements. At this point we have the number of contexts created and the dynamic names assigned to it in an internal table. We will go through that table and create text input UI for each of these contexts. All these text input elements are inserted into a group UI element that is created first. For adding a UI element you need to assign layout data which should be same as the container layout. Each input is label UI + text input UI contained in transparent container UI element.
Once the user has added the Presidents, she will click on the button save. That will read the entries from the dynamic context and add it to the table to be displayed. The action will also do the cleanup of removing the dynamic contexts and the UI elements. Finally a message is relayed to say that list has been updated.METHOD add_new_president_group .
DATA l_president_count TYPE i.DATA l_president_number(6).
DATA l_str_president_number TYPE string.DATA l_str_president_name TYPE string.DATA l_str_bind_text TYPE string.DATA l_str_input_text TYPE string.DATA l_node_president TYPE REF TO if_wd_context_node.DATA l_o_group TYPE REF TO cl_wd_group.DATA l_o_caption TYPE REF TO cl_wd_caption.DATA l_o_container TYPE REF TO cl_wd_uielement_container.DATA l_o_t_cont TYPE REF TO cl_wd_transparent_container.DATA l_o_t_cont_bottom TYPE REF TO cl_wd_transparent_container.DATA l_o_input_field TYPE REF TO cl_wd_input_field.DATA l_o_label TYPE REF TO cl_wd_label.DATA l_cell_backgroup TYPE wdui_cell_bg_design VALUE '00'.DATA l_str_path TYPE string.DATA l_number_of_children TYPE i.DATA l_o_hg TYPE REF TO cl_wd_horizontal_gutter.* Get access to the rootl_o_container ?= wd_this->o_view->get_element( 'ROOTUIELEMENTCONTAINER' ).DATA:
elem_president TYPE REF TO if_wd_context_element.* Add presidentsLOOP AT wd_this->t_dynamic_nodes INTO l_str_president_name.
AT FIRST.* Create new groupCALL METHOD cl_wd_group=>new_groupEXPORTINGid = 'GRP_PRESIDENT01'RECEIVINGcontrol = l_o_group.* Add layout data to group which should be same the* container in which group isCALL METHOD cl_wd_flow_data=>new_flow_dataEXPORTINGelement = l_o_group.* Add new layout to groupCALL METHOD cl_wd_flow_layout=>new_flow_layoutEXPORTINGcontainer = l_o_group.l_o_caption = cl_wd_caption=>new_caption( text = 'New presidents' ).l_o_group->set_header( the_header = l_o_caption ).ENDAT.* Build the Node name using counterl_president_count = l_president_count + 1.WRITE l_president_count TO l_president_number.CONDENSE l_president_number.l_str_president_number = l_president_number.* Get the node from namel_node_president = wd_context->get_child_node( name = l_str_president_name ).CALL METHOD l_node_president->get_pathEXPORTINGwithoutcontroller = abap_trueRECEIVINGpath = l_str_path.CONCATENATE l_str_path 'NAME' INTO l_str_path SEPARATED BY '.'.
* Create input field UICONCATENATE 'IF_PRESIDENT_DESC' l_president_number INTO l_str_input_text.CALL METHOD cl_wd_input_field=>new_input_fieldEXPORTINGid = l_str_input_textRECEIVINGcontrol = l_o_input_field.* Bind the value to the contextCALL METHOD l_o_input_field->bind_valueEXPORTINGpath = l_str_path.CALL METHOD cl_wd_flow_data=>new_flow_dataEXPORTINGelement = l_o_input_field.* transparent container to house the presidentl_o_t_cont = cl_wd_transparent_container=>new_transparent_container( ).* For each new centre toggle background colourIF l_cell_backgroup = '00'.
l_cell_backgroup = '01'. " Fill1
ELSE.
l_cell_backgroup = '00'. " Transparent
ENDIF.* Add layout data to containerCALL METHOD cl_wd_flow_data=>new_flow_dataEXPORTINGcell_design = l_cell_backgroupelement = l_o_t_cont.CALL METHOD cl_wd_flow_layout=>new_flow_layoutEXPORTINGcontainer = l_o_t_cont.* Create element labell_o_label = cl_wd_label=>new_label( text = l_str_president_number label_for = l_str_input_text ).CALL METHOD cl_wd_flow_data=>new_flow_dataEXPORTINGelement = l_o_label.l_o_t_cont->add_child( the_child = l_o_label ).l_o_t_cont->add_child( the_child = l_o_input_field ).l_o_group->add_child( the_child = l_o_t_cont ).AT LAST.CALL METHOD l_o_container->number_of_childrenRECEIVINGnumber = l_number_of_children.* Add a horizontal gutter for separationCALL METHOD cl_wd_horizontal_gutter=>new_horizontal_gutterEXPORTINGid = 'HG_PRESIDENT01'rule_type = cl_wd_horizontal_gutter=>e_rule_type-noneRECEIVINGcontrol = l_o_hg.CALL METHOD cl_wd_flow_data=>new_flow_dataEXPORTINGelement = l_o_hg.l_o_container->add_child( index = l_number_of_children the_child = l_o_group ).l_number_of_children = l_number_of_children + 1.l_o_container->add_child( index = l_number_of_children the_child = l_o_hg ).ENDAT.ENDLOOP.ENDMETHOD.
The removal of context is done as:METHOD onactionsave .
DATA l_president_node TYPE REF TO if_wd_context_node.DATA lst_president TYPE if_v_screen01=>element_presidents .DATA lt_presidents TYPE TABLE OF if_v_screen01=>element_presidents.DATA lst_data TYPE REF TO data.DATA:
node_president_ref TYPE REF TO if_wd_context_node,elem_president_ref TYPE REF TO if_wd_context_element.* Get current table contents of cust refnode_president_ref = wd_context->get_child_node( name = if_v_screen01=>wdctx_presidents ).node_president_ref->get_static_attributes_table(IMPORTINGtable = lt_presidents ).DATA l_parent_node_info TYPE REF TO if_wd_context_node_info.DATA l_str_president_name TYPE string.DATA l_ref(3) TYPE n.FIELD-SYMBOLS <lst_president> TYPE if_v_screen01=>element_presidents.
* Access the parent nodel_parent_node_info = wd_context->get_node_info( ).* Add the new presidents in the cust ref tableLOOP AT wd_this->t_dynamic_nodes INTO l_str_president_name.
l_president_node = wd_context->get_child_node( name = l_str_president_name ).l_president_node->get_attribute(EXPORTINGname = 'NAME'IMPORTINGvalue = lst_president-name ).CHECK lst_president-name IS NOT INITIAL.APPEND lst_president TO lt_presidents.
ENDLOOP.node_president_ref->bind_table(EXPORTINGnew_items = lt_presidents ).* Delete added president nodesdelete_existing_nodes( l_parent_node_info ).* Remove group presidentremove_group_presidents( ).* Reset new additionsreset_new_addition( ).* get message managerDATA: l_current_controller TYPE REF TO if_wd_controller,l_message_manager TYPE REF TO if_wd_message_manager.l_current_controller ?= wd_this->wd_get_api( ).CALL METHOD l_current_controller->get_message_managerRECEIVINGmessage_manager = l_message_manager.* report messageCALL METHOD l_message_manager->report_successEXPORTINGmessage_text = 'Changes Saved'.ENDMETHOD.
METHOD delete_existing_nodes .
DATA l_str_node_name TYPE string.* Delete any existing nodes firstLOOP AT wd_this->t_dynamic_nodes INTO l_str_node_name.
CALL METHOD i_parent_node_info->remove_child_nodeEXPORTINGname = l_str_node_name.ENDLOOP.CLEAR wd_this->t_dynamic_nodes[].ENDMETHOD.
No comments:
Post a Comment