
4. AJAX
Concept
AJAX (short for asynchronous JavaScript and XML) is a set of web development techniques utilizing many web technologies used on the client-side to create asynchronous Web applications. With AJAX, web applications can send data to and retrieve from a server asynchronously (in the background) without interfering with the display and behavior of the existing page. By decoupling the data interchange layer from the presentation layer, AJAX allows for web pages, and by extension web applications, to change content dynamically without the need to reload the entire page. Data can be retrieved using the XMLHttpRequest object.
AJAX is not a technology, but a group of technologies. HTML and CSS can be used in combination to mark up and style information. The DOM is accessed with JavaScript to dynamically display – and allow the user to interact with – the information presented. JavaScript and the XMLHttpRequestobject provide a method for exchanging data asynchronously between browser and server to avoid full page reloads.
For more information, please refer to the Wiki’ and W3Schools’ pages: https://en.wikipedia.org/wiki/Ajax_(programming) and http://www.w3schools.com/ajax/
AJAX in SAP CRM WebUI
As mentioned above some of the AJAX features are implemented in the standard CRM. One of the nice examples, where you can do a reverse engineering, is the Recent Items in CRM WebUI.
View: CRM_BSP_RECOBJ/RecentObjects
In this case, the AJAX call is implemented, right on the BSP page: RecentObjects.htm
<!--this code performs a callback to refresh the items list. Only executed the first time when the BOL objects are not loaded yet--> |
In this example, it is using relatively old asynchronous value fetch (AVF) functionality. However, in newer releases, after SAP Note: 2181937, the call looks like below:
thShortCutMgr.fetch('<%= controller->COMPONENT_ID %>','CL_CRM_BSP__RECENTOBJECT0_IMPL','display'); |
All the mentioned standard JS functions can be found in one of the JS files of THTMLB_SCRIPTS BSP application, e.g. scripts_areaframe.js, scripts_deltahandling_client.js. You can also search for the needed function right in the browser, e.g. in Chrome, activate Developer Tools (F12) à Sources à Menu à Search all Files (Ctrl + Shift + F).
How it works. A certain function (e.g. thAVFMgr.fetch, thShortCutMgr.fetch and many others) builds a proper AJAX URL, containing all necessary parameters. Then the function thtmlbAJAXCall.callBackend(AJAXUrl,CallBackEvent);is executed. The first parameter is our AJAX URL and the second is the call-back function that is registered to receive the result from the AJAX call.
Typical parameters that you need to provide to the back-end are the following: service handler, callback handler, DOM element id, sometimes type of the element.
Service Handler
Service handler, it’s the ICF service that you call on the backend. WebUI is using the standard service: /default_host/sap/webcuif/uif_callback, which has only one handler - CL_CRM_WEB_UTILITY.
Callback Handler
Callback handler, it’s the class that implements a callback method, which will be called in the AJAX call. This class should implement the interface IF_CRM_WEB_CALLBACK. And the mandatory callback method is IF_CRM_WEB_CALLBACK~HANDLE_REQUEST. For the JS object thAVFMgr, its callbackhandler is hardcoded in the JS file and depend on the callback JS function:
case "onRecentItemsRefresh": if(!trigger) { return; } var ajaxURL = newSessionURL.URL + "/webcuif/uif_callback?crm_handler=CL_CRM_BSP__RECENTOBJECT0_IMPL"; ajaxURL += "&crm_controller=" + encodeURIComponent(trigger.id) + thtmlbBuildRequestTicketQuery(); } |
DOM Element ID
When the AJAX callback handler is executed, it sends the HTML response back to the frontend. On the frontend, a corresponding JS function receives the response (reqObject) and processes it. Finally it needs to find a proper DOM element in order to do some actions with it. That’s when you need a DOM Element ID.
var myelement = document.getElementById(elementID); |
See more: http://www.w3schools.com/js/js_htmldom_elements.asp
AJAX Call
When all parameters are known, you can perform an AJAX call. In WebUI a special THTMLB object is used for this.
thtmlbAJAXCall.callBackend(ajaxURL, ajaxCallbackFunction); |
You should be careful with visibility of the elements through different iframes and also in time.
JS Callback Function
You need a callback function to receive the response from your AJAX call, process it and update the corresponding DOM element. Below you can find an extract of a function used for asynchronous value fetch.
fetch: function(trigger, avf_event, csvSourceFields, rowIndex, customRef, csvTargetFields){ … thtmlbAJAXCall.callBackend(ajaxURL, this.update); … } update: function(reqObject) { … var responseText = reqObject.request.responseText; var responseBlocks = responseText.split(";"); for(var i=0, len=responseBlocks.length; i<len; i++) { if(!responseBlocks[i]) { continue; } var blockParts = responseBlocks[i].split(","); if(blockParts.length < 4) { continue; } var tagclassname = blockParts[0]; var elementid = blockParts[1]; var attributeName = blockParts[2]; var payload = thtmlbDecodeBASE64(blockParts[3]); var payloadValue = thtmlb_decode_html(payload); var targetElement = thtmlbGetElement(elementid); … case 'tooltip': if (targetElement.title != payloadValue) { targetElement.title = payloadValue; } … } |
Storing your JS Files
When developing your JS you need to make sure it is visible for your applications. In case you want to place a simple script to your page, you can do it right on the BSP page.
<!—Here you want to store some Javascript --> </script> |
You can also store it as a MIME object within your BSP application and include it on the page.
<script type="text/javascript" src="/sap/bc/bsp/sap/z<bspcmp>/scripts.js"></script> |
For relatively big applications or if you want your JS code to be visible for the whole WebUI framework, you can store the reference to your JS file in eth table WCFC_ADD_JS.
IMG à Customer Relationship Management à UI Framework à UI Framework Definition à Define Path for JS Files
Note: Last option is tested only in SAP CRM 7.0 EHP3.
Simple case
Let us practice first on a simple case, lets update a simple object link (<thtmlb:link>). As usual, we need to create a WebUI component, a view containing the link and a viewset.
When working with AJAX in WebUI you have to generate the view content via corresponding FACTORY methods.
<%@page language="abap" %> |
In this case I just copied the standard JS AVF functionality (object thAVFMgr) into my own namespace and did desired modifications. You can also notice down that our DOM element is identified right on the page and the building of the right URL is a task for the copied JavaScript.
Here I am using my view controller class as a callback handler. This means that it must implement callback method: IF_CRM_WEB_CALLBACK~HANDLE_REQUEST. Update JS function (this.update) has not been changed.
method if_crm_web_callback~handle_request. lr_controller->gv_thtmlb_element_link->m_page_context ). lv_attribute_type ',' lv_html ',' lv_link_tag->id into lv_response. |
How does it look like:
3 seconds later…
HTTPWatch trace:
It takes only 300 ms to build a page and 3 seconds later the link is updated.
Table Rendering
In WebUI most of the data is presented in tables, and therefore the option that is more desirable would be to render such kind of BSP elements. This topic however has been already described on SDN already, so see more at: http://scn.sap.com/community/crm/webclient-ui-framework/blog/2015/09/03/asynchronous-rendering-of-ta... . But here we will consider an option without any modification to SAP standard objects.
So, as usual, we need our WEBUI component, view set and the view. But also we need a context node, a value node in our case.
Our page TableView.htm looks like below:
<%@page language="abap" %> thtmlbCCelleratorManager.createFastRowsCallback); |
You can notice that in our case we perform an AJAX call directly (thtmlbAJAXCall.callBackend); the task to build a proper URL is addressed to ABAP method CREATE_AJAX_URL; and we use a standard callback function thtmlbCCelleratorManager.createFastRowsCallback to process the AJAX response.
How to build a proper URL for AJAX call? If you are going to use the standard AJAX service handler, there are many things that you need to consider: a handler class, a controller id, security session token, etc. But all this is considered in the method CL_CRM_WEB_UTILITY=> CREATE_SERVICE_URL. So finally our method looks very simple:
method create_ajax_url. |
In this case, we again use view controller class as a callback handler.
Next what we need is to implement IF_CRM_WEB_CALLBACK~HANDLE_REQUEST method. We do it in a very similar way as described here: http://scn.sap.com/community/crm/webclient-ui-framework/blog/2015/09/03/asynchronous-rendering-of-ta.... However, in our example, we are getting the data we need via parameter IR_CONTROLLER and therefore we do not need to change the standard SAP coding.
method if_crm_web_callback~handle_request. |
Method CREATE_TABLE_VIEW_HTML is implemented in exactly the same way as it was described on SDN already. I just repeat it here for consistency.
method create_table_view_html. “ strucures “ references “ field symbols
"Create AJAX content
` ], "fixedRightRows": [ ` lv_fixed_right_rows ` ], "markedRows": [ ` lv_marked_rows ` ], "tableId": [ '` iv_table_id `' ], "rowIds": [ ` lv_row_ids ` ]}` into ev_html. |
In the method FILL_CONTEXT_NODE we just populate our context node.
method fill_context_node. |
How does it look like:
3 seconds after…
Note that all your GET-methods are taken into consideration and you can navigate normally as you would do it in the normal WebUI table.
HTTPWatch trace:
It takes only 300 ms to build a page and 3 seconds later the table is updated.
P.S. See a second, better solution here: Asynchronous Rendering of TAJAX Areas / Table Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |