Handling Time-Out Scenario in Web Dynpro ABAP
There is a common requirement given by client wherein, they expect to display some logical message to end-user if application page is kept idle for a defined time i.e. instead of application throwing TIME OUT error, giving any of the following utilities:
- Navigation to information page,
- Email the screen data to agent,
- Auto-Save functionality, etc.…
Will restrict my blog just to give you glimpse of the approach which can be followed, and how a re-usable component can be developed and to be used across different WDA applications, with minimal changes done to main WDA application.
Consider a scenario where-in user have entered data in 30+ fields and before saving the content he went away from his PC. Now on return, when tried to SAVE the data, application came up with TIME OUT dump. Gist of the story is, data is lost and now he has to re-enter the same. Now just think, maybe after 25 minutes of ideal time, we can send the entered data to concern user on his email and display some informative message on screen or Auto-save, etc.… (based on requirement), his efforts to recollect the data can be reduced and your application will be user friendly.
Note1: Proposing this approach based on the assumption that there is no standard solution available for this. I have referred to many blogs on SDN but everyone suggest that standard functionality is not available.
Note2: Re-Usable Component will be good in case of Information Page Navigation or Email Functionality. But for Auto Save it is better to implement the logic to trigger Auto Save in Main Application Component itself as this is more specific to application, things will be complex or messy in case if we tried to use Re-usable component.
- How effectively/efficiently we can do development with minimal changes to existing application
Good understanding on
- Web Dynpro ABAP
- Try to use re-usable component, but there are scenarios i.e. achieving AUTO-SAVE, where we might have to check properties of UI element, before triggering SAVE method/FM, based on how application is designed.
- WDDOBEFOREACTION method of all the views is called if there is any action triggered in one of the view.
Creating Re-Usable Component
Create a component having logic of identifying the time-out and performing the task of EMAIL/NAVIGATION/AUTO-SAVE etc in the same.
We should ensure that we are making least changes to the existing Component (our actual application).
Inside re-usable WDC, we will have following important pointers:
a. View (Layout)
Create a UI element (TIMEDTRIGGER), which is having 2 important properties DELAY and ONACTION, i.e. after every DELAY time ONACTION will be trigger.
Binding of DELAY property is done with context node, whose initial value will be set in DOMODIFY method and will keep changing in other methods based on requirement.
b. Used WebDynpo Components
Create ‘Component Use’ for WDC (Main Application Component) in Re-usable WDC, then navigate to View (REFRESH_VIEW) Controller and add reference of ‘Component Use’ (Main Application Component), navigate to Context and there add Context Node (from Main Application Component).
The Node which we are bringing from ‘Main Application Component’ is the one having actual application related data, example: Personnel Information data/Address data/Bank data, please refer to below screen shot.
c. Global Variables
Define 2 global variable inside VIEW CONTROLLER.
GV_CURRENT_DATE_TIME: used for storing Current Date Time
GV_LAST_ACTION_DATE_TIME: used for storing Last Action Date Time
d. Context Node
Create a Context node/attribute, as shown in below screen shot, which will be used for binding ‘Delay’ property of TIMEDTRIGGER UI Element.
e. Hook Methods
This method will be used to identify the action name (action triggered based on some action taken on UI Element), which have triggered this method.
From WD_THIS we can get API_CONTROLLER using method WD_GET_API( ).
From API_CONTROLLER we can be reference of ACTION using method GET_CURRENT_ACTION_INFO ( ).
Here you will get name of ACTION which have triggered this method.
METHOD wddobeforeaction . DATA lo_api_controller TYPE REF TO if_wd_view_controller. DATA ls_wdapi_action TYPE wdapi_action. lo_api_controller = wd_this->wd_get_api( ). ls_wdapi_action = lo_api_controller->get_current_action_info( ). IF ls_wdapi_action-action_name NE 'TIME_TO_CHECK'. CONCATENATE sy-datum sy-uzeit INTO wd_this->gv_last_action_date_time. ENDIF. ENDMETHOD.
This method will be used to INITIALIZE values of Global variables and DELAY context attribute.
METHOD wddomodifyview . DATA lo_nd_delay TYPE REF TO if_wd_context_node. DATA lv_delay TYPE i. IF first_time EQ abap_true. "Setting the initial value of CURRENT TIME/LAST ACTION TIME CONCATENATE sy-datum sy-uzeit INTO wd_this->gv_current_date_time. CONCATENATE sy-datum sy-uzeit INTO wd_this->gv_last_action_date_time. "Setting initial value of Delay... "Additionally, we might have to put some condition based on application... Since this is re-usable "component and so we have to take care of from which Application this is triggering and according "we have to set the value of DELAY context-attribute wd_this->get_delay( EXPORTING iv_triggered_from = 'INITIALIZE' IMPORTING ev_delay = lv_delay ). lo_nd_delay = wd_context->get_child_node( name = wd_this->wdctx_delay ). lo_nd_delay->set_attribute( name = 'DELAY' value = lv_delay ). ENDIF. ENDMETHOD.
f. Custom Method/Event:
This method will help in calculating Delay time i.e. time is which TIMEDTRIGGERD action is getting invoked
In this method, basically you will set the value of DELAY.
GET_DELAY() method is invoked from DO_MODIFY or ONACTIONTIME_TO_CHECK method. Intention here again is to manage the delay value based on some conditions. Please change the code inside this method as per requirement.
This method will be responsible for calculating the difference of CURRENT_TIME and TIME_WHEN_LAST_ACTION_WAS_TAKEN, and based on the difference i.e. if it crosses threshold time EMAIL/ NAVIGATION/AUTO-SAVE etc., will be performed.
METHOD onactiontime_to_check. DATA lv_last_action_date_timestamp TYPE timestamp. DATA lv_current_date_timestamp TYPE timestamp. DATA lv_time_difference TYPE i. DATA lo_nd_delay TYPE REF TO if_wd_context_node. DATA lv_delay TYPE i. "Getting the value of CURRENT TIME and LAST ACTION TIME lv_last_action_date_timestamp = wd_this->gv_last_action_date_time. CONCATENATE sy-datum sy-uzeit INTO wd_this->gv_current_date_time. lv_current_date_timestamp = wd_this->gv_current_date_time. "Calculating difference between CURRENT TIME and LAST ACTION TIME CALL FUNCTION 'TIMECALC_DIFF' EXPORTING timestamp1 = lv_last_action_date_timestamp timestamp2 = lv_current_date_timestamp timezone = 'UTC' IMPORTING difference = lv_time_difference. "If Difference Time exceeds TIME OUT (here TIME OUT is hardcoded to 900), then we will have to "perform some action (Navigating to some other screen/EMAIL etc…). IF lv_time_difference GT 900 "Write Code for EMAIL or Navigation etc. --> Start "Here you may read the context node (of Main Application (refer to section 'Used WebDynpo "Components')) having actual application data and may prepare email body and trigger email… "Additionally can navigate to some informative screen, which says that your application have "TIMEDOUT and application content is forwarded to your email… "Write Code for EMAIL or Navigation etc.--> End "Getting value of DELAY and setting value of DELAY attribute --> Start wd_this->get_delay( EXPORTING iv_triggered_from = 'TIME_TO_CHECK' IMPORTING ev_delay = lv_delay ). lo_nd_delay = wd_context->get_child_node( name = wd_this->wdctx_delay ). lo_nd_delay->set_attribute( name = 'DELAY' value = lv_delay ). " Getting value of DELAY and setting value of DELAY attribute --> End ENDIF. ENDMETHOD.
Development inside Main Application Component
a. Used WebDynpo Components
Create ‘Component Use’ for WDC (Re-Usable Component).
b. View (Layout)
Create a UI element VIEW_UI_ELEMENT_CONTAINER, that is intended to hold view created in Re-Usable component.
Since the view (inside Re-usable component) contains only TIMEDTRIGGER UI element and so nothing will be visible to end-user when application is rendered.
Screen shot below depicts the same.
c. Context Node
In case if Context Nodes holding application data i.e. Personal Information data/Address data/Bank data etc.… are not Interface node, then you should change it to Interface node.