So we would have to implement our own progress indicator by creating a WebDynpro component using UI elements TimedTrigger and ProgressIndicator. UI element TimedTrigger is an invisible element which when placed on a view, triggers an event every given number of seconds. This is an expensive UI element to have as it creates additional burden on the server, but we have no choice so we will use this. UI element ProgressIndicator is used to show a progress bar. So the idea is to split big job into chunks that can be done in small amount of time (less than the time out period). Every time TimedTrigger fires an event we process the next available chunk of work and set the progress bar and so on.
The calling WD component will use this component for displaying the progress bar and getting a timed wake up call. The calling WD will already have the dataset ready. It would decide how many chunks the dataset will be needed divide into. So once the user triggers the action this progress indicator (PI) WD component is called in a dialog window. The calling WD subscribes to the PI WD event of timed trigger so that it wakes up to send next chunk of data. Using the assistance class of PI WD the calling WD will set the percentage of data completion as well so that the progress bar will keep on increasing.
Let’s see what we need to create in this PI WD component:
Methods of the Component Controller
ACTION_KEEP_ALIVE | call from timed trigger |
GET_MODEL | Return the model class |
INIT_PROG_VIEW | Initialise progress view |
RAISE_WINDOW_CLOSE | Raise event for window closed |
SET_PERCENTAGE | Set percentage complete |
SET_PROGRESS_MSG | Set progress message |
ACTION_KEEP_ALIVE
METHOD action_keep_alive . set_percentage( ). wd_this->fire_keep_alive_evt( ).
GET_MODEL
METHOD get_model . r_o_model = wd_assist.
INIT_PROG_VIEW
method INIT_PROG_VIEW . wd_assist->set_percent_comp( 0 ). wd_this->set_percentage( ). wd_this->set_progress_msg( ).
RAISE_WINDOW_CLOSE
METHOD raise_window_close . wd_this->fire_window_close_evt( ).
SET_PERCENTAGE
METHOD set_percentage . * navigate from <CONTEXT> to <PROGRESS> via lead selection lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ). * get element via lead selection lo_el_progress = lo_nd_progress->get_element( ). lv_percent = wd_assist->get_percent_comp( ). * get single attribute lo_el_progress->set_attribute( EXPORTING name = `PERCENT` value = lv_percent ).
The assistance class has these methods:SET_PROGRESS_MSG
METHOD set_progress_msg . * navigate from <CONTEXT> to <PROGRESS> via lead selection lo_nd_progress = wd_context->get_child_node( name = wd_this->wdctx_progress ). * get element via lead selection lo_el_progress = lo_nd_progress->get_element( ). lv_message = wd_assist->get_progress_msg( ). * get single attribute lo_el_progress->set_attribute( EXPORTING name = `MESSAGE` value = lv_message ).
GET_PROGRESS_MSG | Get the progress message |
SET_PROGRESS_MSG | Set the message in the progress bar |
SET_PERCENT_COMP | Returns the percentage done |
GET_PERCENT_COMP | Returns the percentage done |
These are just getter and setter methods for the filling the Context variables. The calling WD component can set the percentage and message to be displayed. The PI WD will read these values and set in the context.
Usage
Let’s look at the usage of the progress indicator in a example WD component. Create a new WD where we will use the PI WD component. Add the PI WD component in the properties.In the component controller properties add it as used component comptroller.
Subscribe to the events of the PI WD component.
This catches events for timed trigger and window close in case user cancels before 100% completion of the process.
We are here just incrementing the percentage by 10% each time the trigger is activated. But in real situation one would increment to the next dataset that is planned to be processed. The percentage will be according to that.CATCH_TIMED_TRIGGER
METHOD catch_timed_trigger . DATA l_percentage TYPE i. l_percentage = wd_this->o_zcl_rc_library->get_percent_comp( ). IF l_percentage >= 100. wd_this->o_progress_window->close( ). ENDIF. l_percentage = l_percentage + 10. wd_this->o_zcl_rc_library->set_percent_comp( l_percentage ). ENDMETHOD.
If the progress window is closed before all data has been processed you can alert the user that with that error.CATCH_WINDOW_CLOSE
METHOD catch_window_close . * killed in between CHECK wd_this->flag_action_start = abap_true. " Action is killed " ERROR * get message manager DATA lo_api_controller TYPE REF TO if_wd_controller. DATA lo_message_manager TYPE REF TO if_wd_message_manager. lo_api_controller ?= wd_this->wd_get_api( ). lo_message_manager = lo_api_controller->get_message_manager( ). * report message lo_message_manager->report_error_message( message_text = 'Window cancelled before process completion' ). * Clear variables CASE wd_this->action. WHEN 1. " Validate WHEN 2. " Action WHEN OTHERS. ENDCASE. ENDMETHOD.
Let’s look at the component controllers methods.
This will initialise the PI WD component and get the assistance class handler.WDDOINIT
METHOD wddoinit . DATA lo_cmp_usage TYPE REF TO if_wd_component_usage. lo_cmp_usage = wd_this->wd_cpuse_zwdrc_progress_window( ). lo_cmp_usage->create_component( ). ENDIF. DATA lo_interfacecontroller TYPE REF TO ziwci_wdrc_progress_window . lo_interfacecontroller = wd_this->wd_cpifc_zwdrc_progress_window( ). wd_this->o_zcl_rc_library = lo_interfacecontroller->get_model( ). ENDMETHOD.
We have a simple example which has a button that will launch the progress window.
The action attached to the button is:
Here the real application would start the working of whatever transaction was planned. The progress window is further opened as:ONACTIONCALL_PROGRESS
METHOD onactioncall_progress . wd_comp_controller->open_progress_window( ). ENDMETHOD.
Here the window W_MAIN of PI WD component is being called. The title is set and so is the message that will come in the message bar.OPEN_PROGRESS_WINDOW
METHOD open_progress_window . DATA lo_componentinterface TYPE REF TO if_wd_component_usage. lo_componentinterface = wd_this->wd_cpuse_zwdrc_progress_window( ). DATA lo_interface TYPE REF TO ziwci_wdrc_progress_window. lo_interface = wd_this->wd_cpifc_zwdrc_progress_window( ). wd_this->o_zcl_rc_library->set_progress_msg( 'We are doing it '). wd_this->o_zcl_rc_library->set_percent_comp( 0 ). DATA lo_cont TYPE REF TO if_wd_controller. * if_wd_controller = lo_interface->wd_get_api( ). DATA lo_api_componentcontroller TYPE REF TO if_wd_component. lo_api_componentcontroller = wd_this->wd_get_api( ). DATA l_window_manager TYPE REF TO if_wd_window_manager. l_window_manager = lo_api_componentcontroller->get_window_manager( ). wd_this->o_progress_window = l_window_manager->create_window_for_cmp_usage( interface_view_name = 'W_MAIN' component_usage_name = 'ZWDRC_PROGRESS_WINDOW' title = 'We are doing it' * close_in_any_case = ABAP_TRUE * message_display_mode = message_display_mode ). * wd_this->o_progress_window->set_window_title( title = 'Test' ). wd_this->o_progress_window->open( ). ENDMETHOD.
Here is the example of the output:
10% done