Skip to Content
Technical Articles
Author's profile photo Oblomov Dev

abap2UI5 – (2/3) Output of Tables & Selection-Screens

This blog post focuses on the output of tables and selection-screens. We will also add a toolbar and make the table editable. This is the second blog post of the blog series which introduces the abap2UI5 Project. All project information can be found here:

Repository on GitHub

News on Twitter

Blog Series

(1/3) ABAP2UI5 – Development of UI5 Apps in pure ABAP
This blog post focuses on how we can use ABAP2UI5 to develop applications in general
(2/3) ABAP2UI5 – Output of Tables & Selection-Screens (this blog post)
Examples to display lists and tables with an ABAP2UI5 application are explained here.
(3/3) ABAP2UI5 – Demo apps (coming soon)
Some full working demo apps are introduced in this blog post.

If you are interested in the technical background, take a look at this first blog post: abap2UI5 – Development of UI5 Selection Screens in pure ABAP

Introduction

Let’s take a look to the classic sap-gui way to display tables in ABAP first:

TYPES: BEGIN OF t_flight,
         carrid TYPE s_carr_id,
         connid TYPE s_conn_id,
         fldate TYPE s_date,
         price TYPE s_price,
       END OF t_flight.

DATA: it_flight TYPE STANDARD TABLE OF t_flight.

SELECT carrid connid fldate price FROM sflight INTO TABLE it_flight.

DATA: gr_flight TYPE REF TO cl_gui_alv_grid.
CREATE OBJECT gr_flight
  EXPORTING
    i_parent = cl_gui_container=>screen0.

gr_flight->set_table_for_first_display(
  EXPORTING
    i_structure_name = 'T_FLIGHT'
  CHANGING
    it_outtab = it_flight ).

Around of 25 lines of ABAP are needed and you get a UI with a table output. That is very efficient! And with only a few lines more you can also add buttons, inputs and interactions.

When we now try to bring this example to a non-sap-gui environment we need to start with Fiori Elements/RAP or develop an UI5 freestyle application. The first way needs a lot of DDL and CDS artifacts, the second way needs javascript knowledge. Both ways do not fulfill the one page abap source code idea.

The code of abap2UI5 for this example looks like this:

CLASS z2ui5_cl_app_demo_03 DEFINITION PUBLIC.

  PUBLIC SECTION.
    INTERFACES z2ui5_if_app.

TYPES: BEGIN OF t_flight,
         carrid TYPE s_carr_id,
         connid TYPE s_conn_id,
         fldate TYPE s_date,
         price TYPE s_price,
       END OF t_flight.
   DATA t_flight TYPE STANDARD TABLE OF t_flight.

ENDCLASS.

CLASS z2ui5_cl_app_demo_03 IMPLEMENTATION.

  METHOD z2ui5_if_app~controller.

    CASE client->get( )-lifecycle_method.

      WHEN client->cs-lifecycle_method-on_init.
        SELECT carrid connid fldate price FROM sflight INTO TABLE t_flight.

      WHEN client->cs-lifecycle_method-on_rendering.

        data(view) = client->factory_view( ).
        view->page( )->list( items = view->_bind_one_way( t_tab )
                  )->standard_list_item(
                        title       = '{CARRID}'
                        description = '{CONNID}'
                        info        = '{FLDATE}'  ).

    ENDCASE.
  ENDMETHOD.
ENDCLASS.

As you can see, abap2UI5 needs nearly the same amount of lines and you get a ready to use UI5 application:

PICTURE

Most important is the data binding:

"set table and container
DATA(tab) = page->scroll_container( '70%' 
                    )->table( items = view->_bind_one_way( t_tab ) ).

In contrast for example to the text control we can not write the value of the attribute directly into the XML because the table is a deep data model. Therefore it must be written into the View Model of the UI5 View. But Abap2UI5 takes automatically care of this, you just need to use the method bind_one_way and put your table in it. The data is then transformed to a JSON Table and send to the frontend as a part of the UI5 View Model.

Let’s extend now the functionality of this example with a toolbar.

Toolbar

The abap2UI5 output of a table with toolbar looks like this:

So far the view definition is the same as in the first example, we just cahnged the list control with a table control and added a toolbar with two buttons:

"set table and container
DATA(tab) = page->scroll_container( '70%' )->table( view->_bind_one_way( t_tab ) ).

"set toolbar
tab->header_toolbar( )->overflow_toolbar(
        )->title( 'title of the table'
             )->toolbar_spacer(
             )->button( text = 'Sort' press = view->_event( 'BUTTON_SORT' )
             )->button( text = 'Post' press = view->_event( 'BUTTON_POST' ) ).

"set header
tab->columns(
            )->column( )->text( 'Title' )->get_parent(
            )->column( )->text( 'Color' )->get_parent(
            )->column( )->text( 'Info' )->get_parent(
            )->column( )->text( 'Description' )->get_parent(
            )->column( )->text( 'Checkbox' ).

"set content
tab->items( )->column_list_item( )->cells(
           )->text( '{TITLE}'
           )->text( '{VALUE}'
           )->text( '{INFO}'
           )->text( '{DESCR}'
           )->checkbox( '{CHECKBOX}' ).

We set the column definition manually, it is no problem to do this automatic with RTTS. We will see this in an example for a table maintenance app in the last blog post of this introduction.

Next we want to add the functionality to select table entries.

Selection Modes

(coming soon)

 

Next let’s see how we can make the table editable.

Editable

Demo:

Demo%20Editable%20Table

Demo Editable Table

The code looks very similar to the first example:

LINK

There is a difference in the column definition, when the editable function is activated we use input controls instead of text controls:

 IF check_editable_active = abap_true.

      tab->items( )->column_list_item( )->cells(
              )->input( '{TITLE}'
              )->input( '{VALUE}'
              )->input( '{INFO}'
              )->input( '{DESCR}'
              )->checkbox( selected = '{CHECKBOX}' enabled = abap_true ).

 ELSE.
      tab->items( )->column_list_item( )->cells(
             )->text( '{TITLE}'
             )->text( '{VALUE}'
             )->text( '{INFO}'
             )->text( '{DESCR}'
             )->checkbox( '{CHECKBOX}' ).
ENDIF.

Furthermore we need to make sure that abap2UI5 sends back the updated values to the server. Therefore we have to use a different data binding compared to the first example:

DATA(tab) = page->table( items = view->_bind( t_tab ) ).

With the method _bind( ) abap2UI5 creates a two way binding with this table. That means first the data is transformed to a JSON Model and send to the frontend. Second with every request it is also send back to the backend. So make sure your table t_tab is a public attribute that abap2UI5 can assign it from outside and update the values.

Runtime

The request processing for two-way-binding with tables has higher costs than one-way-binding, because after every request there is a JSON to ABAP mapping processed to update the edited table. Therefore only use two-way-binding when it is really needed and maybe don’t make ten thousands of entries editable at once. But who knows a user who edits 10.000 entries at the same time? And there is no UI5 control which renders so many entries anyway.

Last we want to add a selection screen to our example.

Selection-Screens

DEMO

Example%20View

DATA(page) = view->page( title = 'Example - ZZ2UI5_CL_APP_DEMO_02' nav_button_tap = view->_event_display_id( client->get( )-id_prev_app ) ).

DATA(grid) = page->grid( 'L6 M12 S12' )->content( 'l' ).

grid->simple_form('Input' )->content( 'f'
        )->label( 'Input with value help'
        )->input(
            value       = view->_bind( screen-colour )
            placeholder = 'fill in your favorite colour'
            suggestion_items = view->_bind_one_way( mt_suggestion ) )->get(
            )->suggestion_items( )->get(
                )->list_item( text = '{VALUE}' additional_text = '{DESCR}' ).

grid->simple_form('Time Inputs' )->content( 'f'
        )->label( 'Date'
        )->date_picker( view->_bind( screen-date )

        )->label( 'Date and Time'
        )->date_time_picker( view->_bind( screen-date_time )

        )->label( 'Time Begin/End'
        )->time_picker( view->_bind( screen-time_start )
        )->time_picker( view->_bind( screen-time_end ) ).

page->grid( default_span  = 'L12 M12 S12' )->content( 'l'
       )->simple_form('Input with select options' )->content( 'f'

    )->label( 'Checkbox'
    )->checkbox(
         selected = view->_bind( screen-check_is_active )
         text     = 'this is a checkbox'
         enabled  = abap_true

    )->label( 'Combobox'
    )->combobox(
         selectedkey = view->_bind( screen-combo_key )
         items      = view->_bind_one_way( VALUE ty_t_combo(
             ( key = 'BLUE'  text = 'green' )
             ( key = 'GREEN' text = 'blue'  )
             ( key = 'BLACK' text = 'red'   )
             ( key = 'GRAY'  text = 'gray'  ) )
         ) )->get( )->item( key = '{KEY}' text = '{TEXT}'
        )->get_parent( )->get_parent(

    )->label( 'Segmented Button'
    )->segmented_button( view->_bind( screen-segment_key ) )->get(
        )->items( )->get(
             )->segmented_button_item( key = 'BLUE'  icon = 'sap-icon://accept'       text = 'blue'
             )->segmented_button_item( key = 'GREEN' icon = 'sap-icon://add-favorite' text = 'green'
             )->segmented_button_item( key = 'BLACK' icon = 'sap-icon://attachment'   text = 'black'
       )->get_parent( )->get_parent(

    )->label( 'Switch disabled'
    )->switch( enabled = abap_false    customtexton = 'A' customtextoff = 'B'
    )->label( 'Switch accept/reject'
    )->switch( state = screen-check_switch_01 customtexton = 'on'  customtextoff = 'off' type = 'AcceptReject'
    )->label( 'Switch normal'
    )->switch( state = screen-check_switch_02 customtexton = 'YES' customtextoff = 'NO' ).

page->footer( )->overflow_toolbar(
         )->link(
             text = 'Go to Source Code'
             href = client->get( )-s_request-url_source_code
         )->toolbar_spacer(
         )->button(
             text  = 'Clear'
             press = view->_event( 'BUTTON_CLEAR' )
             type  = 'Reject'
             icon  = 'sap-icon://delete'
         )->button(
             text  = 'Send to Server'
             press = view->_event( 'BUTTON_SEND' )
             type  = 'Success' ).

 

In this example you can see that you need 70 lines of code for a view. Maybe that seems to be a lot for a single view and the generating process is very technical. But again abap2UI5 just wants to provide the basic layer and functionality to create UI5 applications so that the system footprint of abap2UI5 stays very small. Apart from this every user can build useful wrappers around the view rendering.

Summary

Abap2UI5 provides a quick and easy way to display tables and lists. Also the use of toolbars or including an editable function is no problem. These two example are very basic, you can add a lot more controls to the view to make the table output more beautiful or extend the whole functionality of the app.

A lot more controls to display table data can be added to abap2UI5 in the future, for example the sap.ui.table or the timeline control. In addition the functionality of selected rows and sending this events back to the server can be part of it in the future.

Feel free to install this project and try out the examples and demos. For news and improvements follow this project on Twitter or take a look to the GitHub repository.

Your comments, questions and wishes are welcome, create an issue or leave a comment.

Thanks for reading!

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.