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” %>
 
<%@extension name=”thtmlb” prefix=”thtmlb” %>
 
<%@extension name=”chtmlb” prefix=”chtmlb” %>
 
<%@extension name=”bsp” prefix=”bsp” %>
 
<%@extension name=”tajax” prefix=”tajax” %>
  <script language=
javascripttype=“text/javascript>
  function UpdateMyTable(reqObj)
  {
  
var responseText = reqObj.request.responseText;
  
var obj = JSON.parse(responseText);
  
var fnum = obj.TEXT.length;
  
for (var i = 0; i < fnum; i++) {
   
var elem = document.getElementById(obj.TEXT[i].NAME);
     if (elem){
      elem.innerHTML = obj.TEXT[i].VALUE;
     }
   }
  }
  </script>
  <tajax:area id=
myTajaxArea>
    </br>
    <b>Here the
area begins!</b>
    </br>
   
<%
   
” Save Top AJAX Area Reference
    controller
->gr_ajax_area = page_context->element_at_top_of_stack( ) .
   
   
Conversion Cnode SelectionMode to Tag
   
data: lv_cellerator_selectionmode type string,
    lv_cellerator_editmode  type
string,
    lv_cellerator_selectioncolumn
type string.
    cl_thtmlb_util
=>translate_selection_mode(
   
exporting
    iv_selection_mode   
= SOMEDATA->SELECTION_MODE
    iv_all_rows_editable
= space
   
importing
    ev_selection_mode  
= lv_cellerator_selectionmode
    ev_edit_mode       
= lv_cellerator_editmode
    ev_selection_column
= lv_cellerator_selectioncolumn ).
   
   
   
data: lv_table_bee type ref to cl_chtmlb_config_cellerator.
   
   
if controller->gv_config_table is initial
   
or 1 = 1.
   
   
” Create Table
   
call method cl_chtmlb_config_cellerator=>factory
   
exporting
   
id                    = controller->gc_table_id
    downloadToExcel      
= ‘TRUE’
    editMode             
= ‘NONE’ lv_cellerator_editmode
    onRowSelection       
= ‘select’
    personalizable       
= ‘TRUE’
    selectedRowIndex     
= somedata->selected_index
    selectedRowIndexTable
= somedata->selection_tab
    selectionColumn      
= lv_cellerator_selectioncolumn
    selectionMode        
= lv_cellerator_selectionmode
   
table                 = somedata->table
    _table               
= ‘//SOMEDATA/Table’
    usage                
= ‘EDITLIST’
    visibleFirstRow      
= somedata->visible_first_row_index
    visibleRowCount      
= ‘6’
    width                
= ‘100%’
    xml                  
= controller->configuration_descr->get_config_data( )
    receiving
    element      
= lv_table_bee.
   
   
Store the link
    controller
->gv_config_table ?= lv_table_bee.
   
   
”   Post AJAX call to update content  %>

      <script type=“text/javascript>
          thtmlbAJAXCall.callBackend(
“<%= controller->create_ajax_url( ) %>”,UpdateMyTable);
        </script>
   
<%
   

    lv_table_bee
->emptytabletext =

                 cl_wd_utilities=>get_otr_text_by_alias( ‘CRM_BSP_UI_FRAME_RECOBJ/LOADING’ ).
 
   
endif.
   
   
” Get the link
    lv_table_bee ?= controller
->gv_config_table.
   
   
” Render html element
    lv_table_bee
->if_bsp_bee~render( _m_page_context ).
   
%>
    </br>
    <b>Here the
area ends!</b>
    </br>
  </tajax:area>

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 sysubrc 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_contentarea_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).


               
call method create_table_view_html_new
                 
exporting
                    ir_server        
= ir_server
                    ir_controller    
= ir_controller
                    iv_binding_string
= ‘//SOMEDATA/TABLE’
                    iv_ajax_area_id  
= lr_controller->gr_ajax_area->id
                 
importing
                    ev_html          
= lv_html.
 
               
if lv_html is not initial.
                  ls_field_list
name  = lr_controller->gr_ajax_area->id.
                  ls_field_list
value = lv_html.
                 
append ls_field_list to lt_field_list.
               
endif.
 
               
“ABAP to JSON
                lr_writer
= cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
               
call transformation id source text = lt_field_list[] result xml lr_writer.
                lv_json
= lr_writer->get_output( ).
 
 
               
” Set Response
                ir_server
->response->set_data( lv_json ).
                ir_server
->response->set_header_field( name  = ‘content-type’
                                                      
value = ‘text/xml’ ).

And the picture to prove that this is working.

output_nFIVXG.gif

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

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

  1. Andrey Vishnevskiy

    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?

    (0) 
      1. Andrey Vishnevskiy

        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’. “TEXTett.

        to reset emtytabletext back to the original one.

        (0) 

Leave a Reply