Asynchronous Rendering of TAJAX Areas / Table Views
I have already briefly mentioned asynchronous rendering of the tables here:
Parallelization in Web UI – Part 2
Since then I have simplified a solution to a certain extent, but I forgot to make a post about it 🙂 . A new solution does not require you to use createFastRowsCallback function (which, in fact, should receive a kind of crazy input, that you have to create on your own).
Instead we will build a normal HTML-based response. It can be doe for ANY Tajax area, including the tables.
So, what is the difference?
And the changes are:
1. When building a view, we start it from our own TAJAX area (<tajax:areaid=”myTajaxArea” >).
2. Moreover, we need to store its name in the controller class (controller->gr_ajax_area = page_context->element_at_top_of_stack( ).).
3. As a callback function, we are using our own one. (function UpdateMyTable(reqObj)).
<%@page language=”abap” %> ” Conversion Cnode SelectionMode to Tag data: lv_table_bee type ref to cl_chtmlb_config_cellerator. if controller->gv_config_table is initial ” Create Table ” Store the link ” Post AJAX call to update content %> <script type=“text/javascript“> cl_wd_utilities=>get_otr_text_by_alias( ‘CRM_BSP_UI_FRAME_RECOBJ/LOADING’ ). endif. ” Get the link ” Render html element |
4. In IF_CRM_WEB_CALLBACK~HANDLE_REQUEST method we are using a new method CREATE_TABLE_VIEW_HTML_NEW, which returns an inner HTML of our TAJAX Area.
method create_table_view_html_new.
” Variables data: lv_attribute_path type string, lv_model_name type string.
” Strucures data: ls_area_content type crms_tajax_area_content.
” References data: lo_page type ref to cl_bsp_ctrl_adapter, lo_view_manager type ref to cl_bsp_wd_view_manager, lo_view_controller type ref to cl_bsp_wd_view_controller, lo_model type ref to if_bsp_model_binding, lo_context_node_tv type ref to cl_bsp_wd_context_node_tv.
” Field symbols field-symbols: <fs_page> type bsprtip.
” Create page instance read table cl_bsp_context=>c_page_instances with key page_name = cl_bsp_wd_appl_controller=>appl_controller_name assigning <fs_page>.
” Rendering if sy–subrc is initial and <fs_page>–instance is bound. lo_page ?= <fs_page>–instance. lo_view_manager ?= lo_page->m_adaptee. lo_view_controller ?= ir_controller. lo_view_manager->render( iv_root_view = lo_view_controller ). endif.
” Get model call method cl_bsp_model=>if_bsp_model_util~split_binding_expression exporting binding_expression = iv_binding_string importing attribute_path = lv_attribute_path model_name = lv_model_name. try. lo_model ?= ir_controller->get_model( lv_model_name ). lo_context_node_tv ?= lo_model. catch: cx_root. exit. endtry.
“Build table lo_context_node_tv->build_table( ).
” Get AJAX Area Content By ID call method lo_view_controller->retrieve_ajax_area_content exporting iv_page_id = ir_controller->component_id iv_area_id = iv_ajax_area_id importing es_content_info = ls_area_content er_used_controller = lo_view_controller.
ev_html = ls_area_content–area_content.
endmethod.
|
5. We send back this inner HTML code as a part of JSON response. (Here we use a table, as probably several areas or individual fields can be processed in one request).
if lv_html is not initial. “ABAP to JSON ” Set Response |
And the picture to prove that this is working.
Run simple! No crazy concatenated HTML strings!
P.S. Sorry, standard SAP’s formatting is lost again. Do not know how to keep it.
BR, Dima
Cool stuff, Dima!
I just have few suggestions if you please.
1. I suppose you would like to put last "image" as a gif to provide a quick result look of you work as you did in Asynchronous Saved Search Fetch. Right now it is a jpg file. Could you please correct it?
2. It's quite easy to figure out what save_ajax_area method exactly is (just to store bsp element to later retrieve its id, am I right?). But it might be better to provide its code or just to describe it fully in your blog post. If it's just for the reason to store (tajax area) element id, why don't you store the id in public controller's attribute?
Hi Andrei,
Thanks for proposals, i have updated it accordingly.
BR, Dima
Hi Dima,
Great, thank you!
It'd be good to remove save_ajax_area reference from the text as well 🙂
Also I want to share my "lessons learned" (that I've noticed during implementation of a table using your solution):
1. 1 = 1 in the page - in that case ajax call will be performed quiet often (any rendering of the page will cause the call)
What I did: comment 1 = 1 line in the page and clear gv_config_table and gr_ajax_area (last one - just in case) in DO_CLEANUP_CONTEXT method of view controller class. This also allowed to decrease number of back-end calls and to correctly handle navigation from one object to another similar object. The last one is a scenario when such ajax-table implemented for a table in assignment block of (for example) business partner and you navigate from one to another using Recent Items.
2. If a corresponding collection will be empty after fill_context_node ( as a result of a search performed or get_related_entities call in there) then "Loading..." text will be still displayed in the table in UI.
What I did: in IF_CRM_WEB_CALLBACK~HANDLE_REQUEST method before the call of CREATE_TABLE_VIEW_HTML_NEW add a line:
lr_controller->gr_config_table->emptytabletext = 'No result found'. "TEXT-ett.
to reset emtytabletext back to the original one.
Agree. But this is just a try-and-fail sample, so it should be fine. Thanks for your comments and voting!
No complaints, just my thoughts and lessons. May be it will help someone to figure out what is going on asynchronously 🙂 Thank you for the blog post!
Hi,
The solution looks fantastic and I basically got it working. There is however one thing which I cannot make to work: whenever I click on a row (to select it) nothing happens. No roundtrip is triggered, nothing. This issue only occurs when the page is rendered via a callback. When the page is rendered "normally" (through a normal callback, e.g. after clicking on a paging in the table) the row selection does work.
I have the impression that none of the javascript events are triggered or at least they don't trigger a roundtrip (row selection, click on header to apply filter, ...)
Does anyone else have experienced this problem?
Thanks,
Joost