This is the second blog post of a blog series which introduces the abap2UI5 Project. It focuses on the output of lists and tables. All project information can be found on GitHub and Twitter:
Repository and Installation with ABAPGit |
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 – Lists, Tables, Toolbar and editable (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 pure 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 and the organisation of BAS development environemnts or deployment processes.
Both ways do not fullfill the one page 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.
Abap2UI5 needs a few more lines, but the code is also in ABAP OO for that 😉
Toolbar
The abap2UI5 output of a table with toolbar in a scroll container looks like this:
So far the view definition is the same as in the first blog post, when we defined a selection screen. We just use the table control instead. Similar to a fieldcat the column definition is set.:
"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}' ).
It would be no problem to do some RTTS and to encapsulate, that everything is set automatically and in a generic way like in CL_SALV_TABLE, but like in the first blog post explained abap2Ui5 just wants to give the basic functionality.
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.
Next let’s see how we can make the table editable.
Selection Modes
(coming soon)
Editable
Demo:
The code looks very similar to the first example:
CLASS z2ui5_cl_app_demo_11 DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES z2ui5_if_app.
TYPES:
BEGIN OF ty_row,
title TYPE string,
value TYPE string,
descr TYPE string,
icon TYPE string,
info TYPE string,
checkbox TYPE abap_bool,
END OF ty_row.
DATA t_tab TYPE STANDARD TABLE OF ty_row WITH EMPTY KEY.
DATA check_editable_active TYPE abap_bool.
ENDCLASS.
CLASS Z2UI5_CL_APP_DEMO_11 IMPLEMENTATION.
METHOD z2ui5_if_app~controller.
CASE client->get( )-lifecycle_method.
WHEN client->cs-lifecycle_method-on_init.
check_editable_active = abap_false.
t_tab = REDUCE #( INIT ret = VALUE #( ) FOR n = 1 WHILE n < 10 NEXT ret =
VALUE #( BASE ret ( title = 'Hans' value = 'red' info = 'completed' descr = 'this is a description' checkbox = abap_true ) ) ).
WHEN client->cs-lifecycle_method-on_event.
CASE client->get( )-event.
WHEN 'BUTTON_EDIT'.
check_editable_active = xsdbool( check_editable_active = abap_false ).
ENDCASE.
WHEN client->cs-lifecycle_method-on_rendering.
DATA(view) = client->factory_view( ).
DATA(page) = view->page( title = 'Example - ZZ2UI5_CL_APP_DEMO_11' nav_button_tap = view->_event_display_id( client->get( )-id_prev_app ) ).
DATA(tab) = page->table( view->_bind( t_tab ) ).
"set toolbar
tab->header_toolbar( )->overflow_toolbar(
)->title( 'title of the table'
)->toolbar_spacer(
)->button(
text = SWITCH #( check_editable_active WHEN abap_true THEN 'display' ELSE 'edit' )
press = view->_event( 'BUTTON_EDIT' ) ).
"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 columns
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.
ENDCASE.
ENDMETHOD.
ENDCLASS.
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.
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!