diff --git a/AGENTS.md b/AGENTS.md index e7b2f7d9..a6d436a4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1256,7 +1256,7 @@ already on every system the sample runs on. Today that is borrowed as *a name that exists*, not used as an API: the sample only reads its shape, never its rows, and if the framework ever changes the table the sample changes the string. Say that in the sample, as 061 does. Data a sample needs -for its own sake is built in ABAP — `VALUE #( ( … ) ( … ) )` in `on_init( )` — +for its own sake is built in ABAP — `VALUE #( ( … ) ( … ) )` in `model_init( )` — never selected from the dictionary. - Follow the [SAP ABAP Style Guide](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md). @@ -1290,14 +1290,14 @@ never selected from the dictionary. - Max 1 consecutive blank line inside a method body. - Always add 1 blank line **before** an `IF` block — **except** when the method is a pure dispatcher (its only purpose is to jump to other methods, with no own logic before the `IF`). In that case, omit the blank line between the opening assignment and the `IF`. - Always add 1 blank line **before** `ELSEIF` and `ELSE`. - - In setup methods (`on_init` and similar), add 1 blank line between the last data assignment and the first non-assignment statement (e.g. before `view_display( )`): + - In setup methods (`model_init` and similar), add 1 blank line between the last data assignment and the first non-assignment statement (e.g. before a `data_read( )`): ```abap - METHOD on_init. + METHOD model_init. price = `1234`. currency = `EUR`. - view_display( ). + data_read( ). ENDMETHOD. ``` @@ -1693,11 +1693,13 @@ Write everything directly in `main` — no method encapsulation needed. Count on ### Larger apps — canonical template -When the logic no longer fits inside `main`, always extract exactly `on_init` and `on_event` as the first step — never use other method names for this purpose. `main` then becomes a pure dispatcher that calls these two methods. Only add further methods (`view_display`, `data_read`, etc.) when they are actually needed. +When the logic no longer fits inside `main`, extract `view_display`, `on_event` and - where the app seeds data - `model_init`, under exactly these names. `main` then becomes a pure dispatcher. Only add further methods (`data_read`, etc.) when they are actually needed. + +**One order, in the declarations and in the implementation:** `main`, `view_display`, `on_event`, the event handlers and helpers, and `model_init` last. A reader meets what the app shows first, then what it does, and the seed data - usually the longest and least interesting part - at the end. `model_init` only seeds: the `check_on_init( )` branch of `main` calls it and then `view_display( )`. (Until 2026-11 the first extraction was called `on_init` and displayed the view itself; samples-controls always used `model_init`, and the three repositories read alike now. An `on_init` remains only where the init path does more than seed and display - apps 004, 081, 381, 382, 421, 501, 543.) In the `check_on_navigated( )` branch the dispatcher calls `view_display( )` directly — the app state survived the serialization, only the view must be re-displayed. Extract a dedicated `on_navigation` method only when the app additionally needs to process results from the called sub-app (via `get_app_prev( )`) before re-displaying. -**Never create a pass-through method with only one statement.** If an extracted method (e.g. `on_init`) would contain only a single call, replace the method call in the dispatcher with that single call directly — and omit the pass-through method entirely. For example, if `on_init` would only call `view_display( )`, write `view_display( )` directly in the `IF client->check_on_init( ).` branch instead. +**Never create a pass-through method with only one statement.** If an extracted method (e.g. `model_init`) would contain only a single call, replace the method call in the dispatcher with that single call directly — and omit the pass-through method entirely. For example, if `model_init` would only call `data_read( )`, write `data_read( )` directly in the `IF client->check_on_init( ).` branch instead. ### Event handler sub-methods @@ -1713,11 +1715,11 @@ CLASS z2ui5_cl_app_xxx DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. " first call: load data, display view - METHODS on_event. " user triggered an event METHODS view_display. " build and render the view + METHODS on_event. " user triggered an event METHODS data_read. " SELECT from database METHODS data_update. " INSERT / UPDATE / DELETE + METHODS model_init. " first call: seed what the app starts with PRIVATE SECTION. ENDCLASS. @@ -1728,7 +1730,8 @@ CLASS z2ui5_cl_app_xxx IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -1738,10 +1741,11 @@ CLASS z2ui5_cl_app_xxx IMPLEMENTATION. ENDMETHOD. - METHOD on_init. + METHOD view_display. - data_read( ). - view_display( ). + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( ). + " ... + client->view_display( view->stringify( ) ). ENDMETHOD. @@ -1765,25 +1769,24 @@ CLASS z2ui5_cl_app_xxx IMPLEMENTATION. ENDMETHOD. - METHOD view_display. + METHOD data_read. - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( ). - " ... - client->view_display( view->stringify( ) ). + " SELECT ... ENDMETHOD. - METHOD data_read. + METHOD data_update. - " SELECT ... + " INSERT / UPDATE / DELETE ... ENDMETHOD. - METHOD data_update. + METHOD model_init. - " INSERT / UPDATE / DELETE ... + " the values the app starts with ... + data_read( ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_004.clas.abap b/src/z2ui5_cl_smp_app_004.clas.abap index 333ab3bf..992c14a1 100644 --- a/src/z2ui5_cl_smp_app_004.clas.abap +++ b/src/z2ui5_cl_smp_app_004.clas.abap @@ -43,14 +43,6 @@ CLASS z2ui5_cl_smp_app_004 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - view_main_display( ). - client->message_box_display( `app started, init values set` ). - - ENDMETHOD. - - METHOD on_event. CASE client->get_event( ). @@ -77,6 +69,14 @@ CLASS z2ui5_cl_smp_app_004 IMPLEMENTATION. ENDMETHOD. + METHOD on_init. + + view_main_display( ). + client->message_box_display( `app started, init values set` ). + + ENDMETHOD. + + METHOD view_main_display. view_main = `MAIN`. diff --git a/src/z2ui5_cl_smp_app_006.clas.abap b/src/z2ui5_cl_smp_app_006.clas.abap index f5364497..e3243843 100644 --- a/src/z2ui5_cl_smp_app_006.clas.abap +++ b/src/z2ui5_cl_smp_app_006.clas.abap @@ -18,9 +18,8 @@ CLASS z2ui5_cl_smp_app_006 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS refresh_data. PRIVATE SECTION. @@ -33,7 +32,8 @@ CLASS z2ui5_cl_smp_app_006 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + refresh_data( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -43,41 +43,6 @@ CLASS z2ui5_cl_smp_app_006 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - refresh_data( ). - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - " the sorted table reaches the view with the model push - no re-render - " of the 10,000 rows is needed - CASE client->get_event( ). - WHEN `SORT_ASCENDING`. - SORT t_tab BY count ASCENDING. - client->message_toast_display( `sort ascending` ). - WHEN `SORT_DESCENDING`. - SORT t_tab BY count DESCENDING. - client->message_toast_display( `sort descending` ). - ENDCASE. - - ENDMETHOD. - - - METHOD refresh_data. - - t_tab = VALUE #( FOR i = 1 UNTIL i > 10000 ( - count = i - value = `red` - descr = `this is a description` - checkbox = abap_true ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -158,4 +123,31 @@ CLASS z2ui5_cl_smp_app_006 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + " the sorted table reaches the view with the model push - no re-render + " of the 10,000 rows is needed + CASE client->get_event( ). + WHEN `SORT_ASCENDING`. + SORT t_tab BY count ASCENDING. + client->message_toast_display( `sort ascending` ). + WHEN `SORT_DESCENDING`. + SORT t_tab BY count DESCENDING. + client->message_toast_display( `sort descending` ). + ENDCASE. + + ENDMETHOD. + + + METHOD refresh_data. + + t_tab = VALUE #( FOR i = 1 UNTIL i > 10000 ( + count = i + value = `red` + descr = `this is a description` + checkbox = abap_true ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_008.clas.abap b/src/z2ui5_cl_smp_app_008.clas.abap index 61ae4a43..d5ccffc2 100644 --- a/src/z2ui5_cl_smp_app_008.clas.abap +++ b/src/z2ui5_cl_smp_app_008.clas.abap @@ -9,8 +9,8 @@ CLASS z2ui5_cl_smp_app_008 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -30,29 +30,6 @@ CLASS z2ui5_cl_smp_app_008 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - WHEN `BUTTON_MESSAGE_BOX_SY`. - " only the message key - message_box_display( ) reads the text from - " T100 itself, exactly as it does for the BAPIRET2 structure below - DATA(ls_msg_sy) = VALUE symsg( msgty = `I` msgid = `NET` msgno = `001` ). - client->message_box_display( ls_msg_sy ). - WHEN `BUTTON_MESSAGE_BOX_BAPIRET`. - DATA(ls_msg_bapiret) = VALUE bapiret2( id = `NET` number = `001` ). - client->message_box_display( ls_msg_bapiret ). - WHEN `BUTTON_MESSAGE_BOX_CX_ROOT`. - TRY. - DATA(lv_val) = 1 / 0. - client->message_box_display( |{ lv_val }| ). - CATCH cx_root INTO DATA(x). - client->message_box_display( x ). - ENDTRY. - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -98,4 +75,27 @@ CLASS z2ui5_cl_smp_app_008 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + WHEN `BUTTON_MESSAGE_BOX_SY`. + " only the message key - message_box_display( ) reads the text from + " T100 itself, exactly as it does for the BAPIRET2 structure below + DATA(ls_msg_sy) = VALUE symsg( msgty = `I` msgid = `NET` msgno = `001` ). + client->message_box_display( ls_msg_sy ). + WHEN `BUTTON_MESSAGE_BOX_BAPIRET`. + DATA(ls_msg_bapiret) = VALUE bapiret2( id = `NET` number = `001` ). + client->message_box_display( ls_msg_bapiret ). + WHEN `BUTTON_MESSAGE_BOX_CX_ROOT`. + TRY. + DATA(lv_val) = 1 / 0. + client->message_box_display( |{ lv_val }| ). + CATCH cx_root INTO DATA(x). + client->message_box_display( x ). + ENDTRY. + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_009.clas.abap b/src/z2ui5_cl_smp_app_009.clas.abap index 0b0f77a3..c407ca42 100644 --- a/src/z2ui5_cl_smp_app_009.clas.abap +++ b/src/z2ui5_cl_smp_app_009.clas.abap @@ -49,9 +49,9 @@ CLASS z2ui5_cl_smp_app_009 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. DATA t_employees TYPE ty_t_employee. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS popup_value_suggestion. METHODS popup_value_employee. @@ -65,7 +65,8 @@ CLASS z2ui5_cl_smp_app_009 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -75,94 +76,6 @@ CLASS z2ui5_cl_smp_app_009 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_suggestion = VALUE #( - ( descr = `this is the color Green` value = `GREEN` ) - ( descr = `this is the color Blue` value = `BLUE` ) - ( descr = `this is the color Black` value = `BLACK` ) - ( descr = `this is the color Grey` value = `GREY` ) - ( descr = `this is the color Blue2` value = `BLUE2` ) - ( descr = `this is the color Blue3` value = `BLUE3` ) ). - - t_cities = VALUE #( - ( value = `London` descr = `London` ) - ( value = `Paris` descr = `Paris` ) - ( value = `Rome` descr = `Rome` ) ). - - t_employees = VALUE #( - ( city = `London` name = `Tom` lastname = `lastname1` nr = `00001` ) - ( city = `London` name = `Tom2` lastname = `lastname2` nr = `00002` ) - ( city = `London` name = `Tom3` lastname = `lastname3` nr = `00003` ) - ( city = `London` name = `Tom4` lastname = `lastname4` nr = `00004` ) - ( city = `Rome` name = `Michaela1` lastname = `lastname5` nr = `00005` ) - ( city = `Rome` name = `Michaela2` lastname = `lastname6` nr = `00006` ) - ( city = `Rome` name = `Michaela3` lastname = `lastname7` nr = `00007` ) - ( city = `Rome` name = `Michaela4` lastname = `lastname8` nr = `00008` ) - ( city = `Paris` name = `Hermine1` lastname = `lastname9` nr = `00009` ) - ( city = `Paris` name = `Hermine2` lastname = `lastname10` nr = `00010` ) - ( city = `Paris` name = `Hermine3` lastname = `lastname11` nr = `00011` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `POPUP_TABLE_VALUE`. - t_suggestion_sel = t_suggestion. - popup_value_suggestion( ). - WHEN `POPUP_TABLE_VALUE_CUSTOM`. - t_employees_sel = VALUE #( ). - popup_value_employee( ). - WHEN `SEARCH`. - t_employees_sel = t_employees. - - IF s_screen-city IS NOT INITIAL. - DELETE t_employees_sel WHERE city <> s_screen-city. - ENDIF. - popup_value_employee( ). - WHEN `POPUP_TABLE_VALUE_CUSTOM_CONTINUE`. - " the selection is counted on a copy - deleting from the bound table - " itself emptied the open popup's list when nothing was selected - DATA(t_chosen_employee) = t_employees_sel. - DELETE t_chosen_employee WHERE selkz = abap_false. - - IF lines( t_chosen_employee ) = 1. - - s_screen-name = t_chosen_employee[ 1 ]-name. - s_screen-lastname = t_chosen_employee[ 1 ]-lastname. - client->message_toast_display( `value selected` ). - client->popup_destroy( ). - - ELSE. - client->message_toast_display( `please select exactly one employee` ). - ENDIF. - WHEN `POPUP_TABLE_VALUE_CONTINUE`. - DATA(t_chosen_color) = t_suggestion_sel. - DELETE t_chosen_color WHERE selkz = abap_false. - - IF lines( t_chosen_color ) = 1. - - s_screen-color_02 = t_chosen_color[ 1 ]-value. - client->message_toast_display( `value selected` ). - client->popup_destroy( ). - - ELSE. - client->message_toast_display( `please select exactly one color` ). - ENDIF. - WHEN `BUTTON_SEND`. - client->message_box_display( `success - values sent to the server` ). - WHEN `BUTTON_CLEAR`. - s_screen = VALUE #( ). - client->message_box_display( `View initialized` ). - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -259,6 +172,61 @@ CLASS z2ui5_cl_smp_app_009 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `POPUP_TABLE_VALUE`. + t_suggestion_sel = t_suggestion. + popup_value_suggestion( ). + WHEN `POPUP_TABLE_VALUE_CUSTOM`. + t_employees_sel = VALUE #( ). + popup_value_employee( ). + WHEN `SEARCH`. + t_employees_sel = t_employees. + + IF s_screen-city IS NOT INITIAL. + DELETE t_employees_sel WHERE city <> s_screen-city. + ENDIF. + popup_value_employee( ). + WHEN `POPUP_TABLE_VALUE_CUSTOM_CONTINUE`. + " the selection is counted on a copy - deleting from the bound table + " itself emptied the open popup's list when nothing was selected + DATA(t_chosen_employee) = t_employees_sel. + DELETE t_chosen_employee WHERE selkz = abap_false. + + IF lines( t_chosen_employee ) = 1. + + s_screen-name = t_chosen_employee[ 1 ]-name. + s_screen-lastname = t_chosen_employee[ 1 ]-lastname. + client->message_toast_display( `value selected` ). + client->popup_destroy( ). + + ELSE. + client->message_toast_display( `please select exactly one employee` ). + ENDIF. + WHEN `POPUP_TABLE_VALUE_CONTINUE`. + DATA(t_chosen_color) = t_suggestion_sel. + DELETE t_chosen_color WHERE selkz = abap_false. + + IF lines( t_chosen_color ) = 1. + + s_screen-color_02 = t_chosen_color[ 1 ]-value. + client->message_toast_display( `value selected` ). + client->popup_destroy( ). + + ELSE. + client->message_toast_display( `please select exactly one color` ). + ENDIF. + WHEN `BUTTON_SEND`. + client->message_box_display( `success - values sent to the server` ). + WHEN `BUTTON_CLEAR`. + s_screen = VALUE #( ). + client->message_box_display( `View initialized` ). + ENDCASE. + + ENDMETHOD. + + METHOD popup_value_suggestion. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( @@ -380,4 +348,35 @@ CLASS z2ui5_cl_smp_app_009 IMPLEMENTATION. ENDMETHOD. + + METHOD model_init. + + t_suggestion = VALUE #( + ( descr = `this is the color Green` value = `GREEN` ) + ( descr = `this is the color Blue` value = `BLUE` ) + ( descr = `this is the color Black` value = `BLACK` ) + ( descr = `this is the color Grey` value = `GREY` ) + ( descr = `this is the color Blue2` value = `BLUE2` ) + ( descr = `this is the color Blue3` value = `BLUE3` ) ). + + t_cities = VALUE #( + ( value = `London` descr = `London` ) + ( value = `Paris` descr = `Paris` ) + ( value = `Rome` descr = `Rome` ) ). + + t_employees = VALUE #( + ( city = `London` name = `Tom` lastname = `lastname1` nr = `00001` ) + ( city = `London` name = `Tom2` lastname = `lastname2` nr = `00002` ) + ( city = `London` name = `Tom3` lastname = `lastname3` nr = `00003` ) + ( city = `London` name = `Tom4` lastname = `lastname4` nr = `00004` ) + ( city = `Rome` name = `Michaela1` lastname = `lastname5` nr = `00005` ) + ( city = `Rome` name = `Michaela2` lastname = `lastname6` nr = `00006` ) + ( city = `Rome` name = `Michaela3` lastname = `lastname7` nr = `00007` ) + ( city = `Rome` name = `Michaela4` lastname = `lastname8` nr = `00008` ) + ( city = `Paris` name = `Hermine1` lastname = `lastname9` nr = `00009` ) + ( city = `Paris` name = `Hermine2` lastname = `lastname10` nr = `00010` ) + ( city = `Paris` name = `Hermine3` lastname = `lastname11` nr = `00011` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_011.clas.abap b/src/z2ui5_cl_smp_app_011.clas.abap index 9e53a95d..d8694cc8 100644 --- a/src/z2ui5_cl_smp_app_011.clas.abap +++ b/src/z2ui5_cl_smp_app_011.clas.abap @@ -17,7 +17,8 @@ CLASS z2ui5_cl_smp_app_011 DEFINITION PUBLIC. editable TYPE abap_bool, checkbox TYPE abap_bool, END OF ty_s_row. - DATA t_tab TYPE STANDARD TABLE OF ty_s_row WITH EMPTY KEY. + DATA t_tab TYPE STANDARD TABLE OF ty_s_row WITH EMPTY KEY. + DATA edit_button_text TYPE string VALUE `edit`. PROTECTED SECTION. DATA check_editable_active TYPE abap_bool. @@ -32,6 +33,43 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_011 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + + check_editable_active = abap_false. + t_tab = VALUE #( + ( title = `entry 01` value = `red` info = `completed` descr = `this is a description` checkbox = abap_true ) + ( title = `entry 02` value = `blue` info = `completed` descr = `this is a description` checkbox = abap_true ) + ( title = `entry 03` value = `green` info = `completed` descr = `this is a description` checkbox = abap_true ) + ( title = `entry 04` value = `orange` info = `completed` descr = `` checkbox = abap_true ) + ( title = `entry 05` value = `grey` info = `completed` descr = `this is a description` checkbox = abap_true ) + ( title = `` value = `` info = `` descr = `` checkbox = abap_false ) ). + + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + + ELSEIF client->check_on_event( `BUTTON_EDIT` ). + check_editable_active = xsdbool( check_editable_active = abap_false ). + LOOP AT t_tab REFERENCE INTO DATA(lr_tab). + lr_tab->editable = check_editable_active. + ENDLOOP. + edit_button_text = SWITCH #( check_editable_active WHEN abap_true THEN `display` ELSE `edit` ). + + ELSEIF client->check_on_event( `BUTTON_DELETE` ). + DELETE t_tab WHERE selkz = abap_true. + + ELSEIF client->check_on_event( `BUTTON_ADD` ). + + INSERT VALUE #( editable = check_editable_active ) INTO TABLE t_tab. + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -76,7 +114,7 @@ CLASS z2ui5_cl_smp_app_011 IMPLEMENTATION. )->a( n = `icon` v = `sap-icon://add` )->tag( `Button` )->a( n = `press` v = client->_event( `BUTTON_EDIT` ) - )->a( n = `text` t = SWITCH #( check_editable_active WHEN abap_true THEN `display` ELSE `edit` ) + )->a( n = `text` v = client->_bind( edit_button_text ) )->a( n = `tooltip` v = `Switch the cells between display and edit mode` )->a( n = `icon` v = `sap-icon://edit` )->end( @@ -127,43 +165,4 @@ CLASS z2ui5_cl_smp_app_011 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - - check_editable_active = abap_false. - t_tab = VALUE #( - ( title = `entry 01` value = `red` info = `completed` descr = `this is a description` checkbox = abap_true ) - ( title = `entry 02` value = `blue` info = `completed` descr = `this is a description` checkbox = abap_true ) - ( title = `entry 03` value = `green` info = `completed` descr = `this is a description` checkbox = abap_true ) - ( title = `entry 04` value = `orange` info = `completed` descr = `` checkbox = abap_true ) - ( title = `entry 05` value = `grey` info = `completed` descr = `this is a description` checkbox = abap_true ) - ( title = `` value = `` info = `` descr = `` checkbox = abap_false ) ). - - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - - ELSEIF client->check_on_event( `BUTTON_EDIT` ). - check_editable_active = xsdbool( check_editable_active = abap_false ). - LOOP AT t_tab REFERENCE INTO DATA(lr_tab). - lr_tab->editable = check_editable_active. - ENDLOOP. - " the button text (edit / display) is rendered from the protected flag, - " not bound - the model push alone would leave it saying `edit` - view_display( ). - - ELSEIF client->check_on_event( `BUTTON_DELETE` ). - DELETE t_tab WHERE selkz = abap_true. - - ELSEIF client->check_on_event( `BUTTON_ADD` ). - - INSERT VALUE #( editable = check_editable_active ) INTO TABLE t_tab. - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_012.clas.abap b/src/z2ui5_cl_smp_app_012.clas.abap index 5f8d29b3..c35ebefd 100644 --- a/src/z2ui5_cl_smp_app_012.clas.abap +++ b/src/z2ui5_cl_smp_app_012.clas.abap @@ -11,8 +11,8 @@ CLASS z2ui5_cl_smp_app_012 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_navigation. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS popup_decide. METHODS popup_info. @@ -22,61 +22,15 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_012 IMPLEMENTATION. - METHOD on_navigation. - - IF check_popup = abap_true. + METHOD z2ui5_if_app~main. - check_popup = abap_false. - DATA(app) = CAST z2ui5_cl_smp_app_020( client->get_app_prev( ) ). - client->message_toast_display( |{ app->event } pressed| ). + me->client = client. + IF client->check_on_navigated( ). + on_navigation( ). + ELSEIF client->check_on_event( ). + on_event( ). ENDIF. - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `BUTTON_POPUP_01`. - popup_decide( ). - client->view_destroy( ). - WHEN `POPUP_DECIDE_CONTINUE`. - client->popup_destroy( ). - view_display( ). - client->message_toast_display( `continue pressed` ). - WHEN `POPUP_DECIDE_CANCEL`. - client->popup_destroy( ). - view_display( ). - client->message_toast_display( `cancel pressed` ). - WHEN `BUTTON_POPUP_02`. - view_display( ). - popup_decide( ). - WHEN `BUTTON_POPUP_03`. - popup_info( ). - WHEN `BUTTON_POPUP_04`. - popup_decide( ). - WHEN `BUTTON_POPUP_05`. - check_popup = abap_true. - client->view_destroy( ). - client->nav_app_call( z2ui5_cl_smp_app_020=>factory( - i_text = `(new app) this is a popup to decide, the text is sent from the previous app and the answer will be sent back` - i_cancel_text = `Cancel` - i_cancel_event = `POPUP_DECIDE_CANCEL` - i_confirm_text = `Continue` - i_confirm_event = `POPUP_DECIDE_CONTINUE` - ) ). - WHEN `BUTTON_POPUP_06`. - check_popup = abap_true. - client->nav_app_call( z2ui5_cl_smp_app_020=>factory( - i_text = `(new app) this is a popup to decide, the text is sent from the previous app and the answer will be sent back` - i_cancel_text = `Cancel` - i_cancel_event = `POPUP_DECIDE_CANCEL` - i_confirm_text = `Continue` - i_confirm_event = `POPUP_DECIDE_CONTINUE` ) ). - ENDCASE. - ENDMETHOD. @@ -153,6 +107,69 @@ CLASS z2ui5_cl_smp_app_012 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `BUTTON_POPUP_01`. + popup_decide( ). + client->view_destroy( ). + WHEN `POPUP_DECIDE_CONTINUE`. + client->popup_destroy( ). + " BUTTON_POPUP_01 destroyed the view behind the popup - nothing is + " left for a model push to update, so the view is built again + view_display( ). + client->message_toast_display( `continue pressed` ). + WHEN `POPUP_DECIDE_CANCEL`. + client->popup_destroy( ). + " as above: the view may have been destroyed when the popup opened + view_display( ). + client->message_toast_display( `cancel pressed` ). + WHEN `BUTTON_POPUP_02`. + " the rebuild is the subject of this button: the background is + " rendered again while the popup opens + view_display( ). + popup_decide( ). + WHEN `BUTTON_POPUP_03`. + popup_info( ). + WHEN `BUTTON_POPUP_04`. + popup_decide( ). + WHEN `BUTTON_POPUP_05`. + check_popup = abap_true. + client->view_destroy( ). + client->nav_app_call( z2ui5_cl_smp_app_020=>factory( + i_text = `(new app) this is a popup to decide, the text is sent from the previous app and the answer will be sent back` + i_cancel_text = `Cancel` + i_cancel_event = `POPUP_DECIDE_CANCEL` + i_confirm_text = `Continue` + i_confirm_event = `POPUP_DECIDE_CONTINUE` + ) ). + WHEN `BUTTON_POPUP_06`. + check_popup = abap_true. + client->nav_app_call( z2ui5_cl_smp_app_020=>factory( + i_text = `(new app) this is a popup to decide, the text is sent from the previous app and the answer will be sent back` + i_cancel_text = `Cancel` + i_cancel_event = `POPUP_DECIDE_CANCEL` + i_confirm_text = `Continue` + i_confirm_event = `POPUP_DECIDE_CONTINUE` ) ). + ENDCASE. + + ENDMETHOD. + + + METHOD on_navigation. + + IF check_popup = abap_true. + + check_popup = abap_false. + DATA(app) = CAST z2ui5_cl_smp_app_020( client->get_app_prev( ) ). + client->message_toast_display( |{ app->event } pressed| ). + ENDIF. + + view_display( ). + + ENDMETHOD. + + METHOD popup_decide. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( @@ -201,16 +218,4 @@ CLASS z2ui5_cl_smp_app_012 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_navigated( ). - on_navigation( ). - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_019.clas.abap b/src/z2ui5_cl_smp_app_019.clas.abap index dbcac3d7..4b77ce7d 100644 --- a/src/z2ui5_cl_smp_app_019.clas.abap +++ b/src/z2ui5_cl_smp_app_019.clas.abap @@ -29,6 +29,39 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_019 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + + sel_mode = `None`. + t_tab = VALUE #( descr = `this is a description` + ( title = `title_01` value = `value_01` ) + ( title = `title_02` value = `value_02` ) + ( title = `title_03` value = `value_03` ) + ( title = `title_04` value = `value_04` ) + ( title = `title_05` value = `value_05` ) ). + view_display( ). + + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `BUTTON_SEGMENT_CHANGE` ). + + client->message_toast_display( `Selection Mode changed` ). + " the Table's mode is written into the view at render time: the new + " mode takes a fresh Table, which reads its selection from SELKZ again + view_display( ). + + ELSEIF client->check_on_event( `BUTTON_READ_SEL` ). + + t_tab_sel = t_tab. + DELETE t_tab_sel WHERE selkz <> abap_true. + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -140,36 +173,4 @@ CLASS z2ui5_cl_smp_app_019 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - - sel_mode = `None`. - t_tab = VALUE #( descr = `this is a description` - ( title = `title_01` value = `value_01` ) - ( title = `title_02` value = `value_02` ) - ( title = `title_03` value = `value_03` ) - ( title = `title_04` value = `value_04` ) - ( title = `title_05` value = `value_05` ) ). - view_display( ). - - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( `BUTTON_SEGMENT_CHANGE` ). - - client->message_toast_display( `Selection Mode changed` ). - view_display( ). - - ELSEIF client->check_on_event( `BUTTON_READ_SEL` ). - - t_tab_sel = t_tab. - DELETE t_tab_sel WHERE selkz <> abap_true. - view_display( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_020.clas.abap b/src/z2ui5_cl_smp_app_020.clas.abap index bea1bd27..978ae4f6 100644 --- a/src/z2ui5_cl_smp_app_020.clas.abap +++ b/src/z2ui5_cl_smp_app_020.clas.abap @@ -29,18 +29,6 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_020 IMPLEMENTATION. - METHOD factory. - - result = NEW #( ). - result->text = i_text. - result->cancel_text = i_cancel_text. - result->cancel_event = i_cancel_event. - result->confirm_text = i_confirm_text. - result->confirm_event = i_confirm_event. - - ENDMETHOD. - - METHOD z2ui5_if_app~main. IF client->check_on_navigated( ). @@ -85,4 +73,16 @@ CLASS z2ui5_cl_smp_app_020 IMPLEMENTATION. ENDMETHOD. + + METHOD factory. + + result = NEW #( ). + result->text = i_text. + result->cancel_text = i_cancel_text. + result->cancel_event = i_cancel_event. + result->confirm_text = i_confirm_text. + result->confirm_event = i_confirm_event. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_024.clas.abap b/src/z2ui5_cl_smp_app_024.clas.abap index 1487a769..d94d24bf 100644 --- a/src/z2ui5_cl_smp_app_024.clas.abap +++ b/src/z2ui5_cl_smp_app_024.clas.abap @@ -12,8 +12,8 @@ CLASS z2ui5_cl_smp_app_024 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -27,6 +27,8 @@ CLASS z2ui5_cl_smp_app_024 IMPLEMENTATION. me->client = client. IF client->check_on_navigated( ). + " more than a re-display: the app this one called can hand an event + " back with nav_app_leave( event = ... ), and it arrives on this branch " abap2ui5lint-disable-next-line handler-without-event -- handed over by z2ui5_cl_smp_app_025 with nav_app_leave( event = ... ) IF client->get_event( ) = `CALL_PREVIOUS_APP_INPUT_RETURN`. @@ -44,33 +46,6 @@ CLASS z2ui5_cl_smp_app_024 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `CALL_NEW_APP`. - client->nav_app_call( NEW z2ui5_cl_smp_app_025( ) ). - - WHEN `CALL_NEW_APP_VIEW`. - DATA(app) = NEW z2ui5_cl_smp_app_025( ). - app->show_view = `SECOND`. - client->nav_app_call( app ). - - WHEN `CALL_NEW_APP_READ`. - DATA(app_next) = NEW z2ui5_cl_smp_app_025( ). - app_next->input_previous_set = input. - client->nav_app_call( app_next ). - - WHEN `CALL_NEW_APP_EVENT`. - app_next = NEW z2ui5_cl_smp_app_025( ). - app_next->event_backend = `NEW_APP_EVENT`. - client->nav_app_call( app_next ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -131,4 +106,31 @@ CLASS z2ui5_cl_smp_app_024 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `CALL_NEW_APP`. + client->nav_app_call( NEW z2ui5_cl_smp_app_025( ) ). + + WHEN `CALL_NEW_APP_VIEW`. + DATA(app) = NEW z2ui5_cl_smp_app_025( ). + app->show_view = `SECOND`. + client->nav_app_call( app ). + + WHEN `CALL_NEW_APP_READ`. + DATA(app_next) = NEW z2ui5_cl_smp_app_025( ). + app_next->input_previous_set = input. + client->nav_app_call( app_next ). + + WHEN `CALL_NEW_APP_EVENT`. + app_next = NEW z2ui5_cl_smp_app_025( ). + app_next->event_backend = `NEW_APP_EVENT`. + client->nav_app_call( app_next ). + + ENDCASE. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_025.clas.abap b/src/z2ui5_cl_smp_app_025.clas.abap index 757305ee..0c9936c3 100644 --- a/src/z2ui5_cl_smp_app_025.clas.abap +++ b/src/z2ui5_cl_smp_app_025.clas.abap @@ -4,6 +4,7 @@ CLASS z2ui5_cl_smp_app_025 DEFINITION PUBLIC. INTERFACES z2ui5_if_app. DATA input TYPE string. + DATA input_previous TYPE string. " abap2ui5lint-disable unbound-public-attribute -- set by the calling app z2ui5_cl_smp_app_024 before nav_app_call( ) DATA input_previous_set TYPE string. DATA show_view TYPE string. @@ -11,11 +12,10 @@ CLASS z2ui5_cl_smp_app_025 DEFINITION PUBLIC. " abap2ui5lint-enable PROTECTED SECTION. - DATA input_previous TYPE string. - DATA client TYPE REF TO z2ui5_if_client. + DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -28,6 +28,9 @@ CLASS z2ui5_cl_smp_app_025 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). + " nothing is seeded here: the calling app z2ui5_cl_smp_app_024 set the + " public attributes before nav_app_call( ) - the start only reports + " the event it was handed IF event_backend = `NEW_APP_EVENT`. client->message_box_display( `new app called and event NEW_APP_EVENT raised` ). ENDIF. @@ -42,32 +45,6 @@ CLASS z2ui5_cl_smp_app_025 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `BUTTON_READ_PREVIOUS`. - DATA(app_024) = CAST z2ui5_cl_smp_app_024( client->get_app_prev( ) ). - input_previous = app_024->input2. - client->message_toast_display( `data of previous app read` ). - view_display( ). - - WHEN `SHOW_VIEW_MAIN`. - show_view = `MAIN`. - view_display( ). - - WHEN `SHOW_VIEW_SECOND`. - show_view = `SECOND`. - view_display( ). - - WHEN `BACK_WITH_EVENT`. - client->nav_app_leave( event = `CALL_PREVIOUS_APP_INPUT_RETURN` ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -109,7 +86,7 @@ CLASS z2ui5_cl_smp_app_025 IMPLEMENTATION. )->tag( `Label` )->a( n = `text` v = `Data of previous app` )->tag( `Input` - )->a( n = `value` t = input_previous + )->a( n = `value` v = client->_bind( input_previous ) )->a( n = `enabled` b = abap_false )->tag( `Button` )->a( n = `press` v = client->_event( `BUTTON_READ_PREVIOUS` ) @@ -152,4 +129,32 @@ CLASS z2ui5_cl_smp_app_025 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `BUTTON_READ_PREVIOUS`. + DATA(app_024) = CAST z2ui5_cl_smp_app_024( client->get_app_prev( ) ). + input_previous = app_024->input2. + client->message_toast_display( `data of previous app read` ). + + WHEN `SHOW_VIEW_MAIN`. + show_view = `MAIN`. + " a different set of controls, not a changed value: the other view + " has to be built + view_display( ). + + WHEN `SHOW_VIEW_SECOND`. + show_view = `SECOND`. + " as above: the second view is a different set of controls + view_display( ). + + WHEN `BACK_WITH_EVENT`. + client->nav_app_leave( event = `CALL_PREVIOUS_APP_INPUT_RETURN` ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_026.clas.abap b/src/z2ui5_cl_smp_app_026.clas.abap index c0a240d3..0322c0bf 100644 --- a/src/z2ui5_cl_smp_app_026.clas.abap +++ b/src/z2ui5_cl_smp_app_026.clas.abap @@ -53,37 +53,6 @@ CLASS z2ui5_cl_smp_app_026 IMPLEMENTATION. ENDMETHOD. - METHOD popover_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` ). - view->ele( `Popover` - )->a( n = `title` v = `Popover Title` - )->a( n = `placement` t = placement - )->ele( `footer` - )->ele( `OverflowToolbar` - )->tag( `ToolbarSpacer` - )->tag( `Button` - )->a( n = `press` v = client->_event( `BUTTON_CANCEL` ) - )->a( n = `text` v = `Cancel` - )->tag( `Button` - )->a( n = `press` v = client->_event( `BUTTON_CONFIRM` ) - )->a( n = `text` v = `Confirm` - )->a( n = `type` v = `Emphasized` - )->end( - )->end( - )->tag( `Text` - )->a( n = `text` v = `make an input here:` - )->tag( `Input` - )->a( n = `value` v = client->_bind( input ) ). - - client->popover_display( xml = view->stringify( ) by_id = id ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -152,4 +121,35 @@ CLASS z2ui5_cl_smp_app_026 IMPLEMENTATION. ENDMETHOD. + + METHOD popover_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` ). + view->ele( `Popover` + )->a( n = `title` v = `Popover Title` + )->a( n = `placement` t = placement + )->ele( `footer` + )->ele( `OverflowToolbar` + )->tag( `ToolbarSpacer` + )->tag( `Button` + )->a( n = `press` v = client->_event( `BUTTON_CANCEL` ) + )->a( n = `text` v = `Cancel` + )->tag( `Button` + )->a( n = `press` v = client->_event( `BUTTON_CONFIRM` ) + )->a( n = `text` v = `Confirm` + )->a( n = `type` v = `Emphasized` + )->end( + )->end( + )->tag( `Text` + )->a( n = `text` v = `make an input here:` + )->tag( `Input` + )->a( n = `value` v = client->_bind( input ) ). + + client->popover_display( xml = view->stringify( ) by_id = id ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_028.clas.abap b/src/z2ui5_cl_smp_app_028.clas.abap index f8a241a5..3af61ee3 100644 --- a/src/z2ui5_cl_smp_app_028.clas.abap +++ b/src/z2ui5_cl_smp_app_028.clas.abap @@ -23,8 +23,8 @@ CLASS z2ui5_cl_smp_app_028 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS start_timer. PRIVATE SECTION. @@ -48,58 +48,6 @@ CLASS z2ui5_cl_smp_app_028 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - counter = 1. - running = abap_true. - t_tab = VALUE #( - ( title = |entry{ counter }| - info = `completed` - descr = `this is a description` - icon = `sap-icon://account` ) ). - - start_timer( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `TIMER_FINISHED`. - counter = counter + 1. - INSERT VALUE #( - title = |entry{ counter }| - info = `completed` - descr = `this is a description` - icon = `sap-icon://account` ) - INTO TABLE t_tab. - - IF counter < 3. - start_timer( ). - ELSE. - running = abap_false. - client->message_toast_display( `timer deactivated` ). - ENDIF. - - WHEN `RESTART`. - on_init( ). - - ENDCASE. - - ENDMETHOD. - - - METHOD start_timer. - - client->follow_up_action( - val = z2ui5_if_client=>cs_event-start_timer - t_arg = VALUE #( ( `TIMER_FINISHED` ) ( `2000` ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -145,4 +93,56 @@ CLASS z2ui5_cl_smp_app_028 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `TIMER_FINISHED`. + counter = counter + 1. + INSERT VALUE #( + title = |entry{ counter }| + info = `completed` + descr = `this is a description` + icon = `sap-icon://account` ) + INTO TABLE t_tab. + + IF counter < 3. + start_timer( ). + ELSE. + running = abap_false. + client->message_toast_display( `timer deactivated` ). + ENDIF. + + WHEN `RESTART`. + on_init( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + counter = 1. + running = abap_true. + t_tab = VALUE #( + ( title = |entry{ counter }| + info = `completed` + descr = `this is a description` + icon = `sap-icon://account` ) ). + + start_timer( ). + + ENDMETHOD. + + + METHOD start_timer. + + client->follow_up_action( + val = z2ui5_if_client=>cs_event-start_timer + t_arg = VALUE #( ( `TIMER_FINISHED` ) ( `2000` ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_045.clas.abap b/src/z2ui5_cl_smp_app_045.clas.abap index 2e513e23..9f65588a 100644 --- a/src/z2ui5_cl_smp_app_045.clas.abap +++ b/src/z2ui5_cl_smp_app_045.clas.abap @@ -31,22 +31,6 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_045 IMPLEMENTATION. - METHOD refresh_data. - - " rebuilt from scratch on every call - it runs on the init AND on every - " filter press, and without the reset each press appended another 1000 - " rows before the filter deleted the ones it did not want - t_tab = VALUE #( ). - DO 1000 TIMES. - DATA(ls_row) = VALUE ty_s_row( count = sy-index value = `red` - info = COND #( WHEN sy-index < 50 THEN `completed` ELSE `uncompleted` ) - descr = `this is a description` checkbox = abap_true ). - INSERT ls_row INTO TABLE t_tab. - ENDDO. - - ENDMETHOD. - - METHOD z2ui5_if_app~main. me->client = client. @@ -157,4 +141,20 @@ CLASS z2ui5_cl_smp_app_045 IMPLEMENTATION. ENDMETHOD. + + METHOD refresh_data. + + " rebuilt from scratch on every call - it runs on the init AND on every + " filter press, and without the reset each press appended another 1000 + " rows before the filter deleted the ones it did not want + t_tab = VALUE #( ). + DO 1000 TIMES. + DATA(ls_row) = VALUE ty_s_row( count = sy-index value = `red` + info = COND #( WHEN sy-index < 50 THEN `completed` ELSE `uncompleted` ) + descr = `this is a description` checkbox = abap_true ). + INSERT ls_row INTO TABLE t_tab. + ENDDO. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_052.clas.abap b/src/z2ui5_cl_smp_app_052.clas.abap index ad405b84..4d7dbd4b 100644 --- a/src/z2ui5_cl_smp_app_052.clas.abap +++ b/src/z2ui5_cl_smp_app_052.clas.abap @@ -36,55 +36,20 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_052 IMPLEMENTATION. - METHOD popover_display. - - DATA(lo_popover) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` - )->a( n = `xmlns:form` v = `sap.ui.layout.form` ). - - DATA(popover) = lo_popover->ele( `Popover` - )->a( n = `title` t = |abap2UI5 - Popover - { mv_product }| - )->a( n = `placement` v = `Right` - )->a( n = `contentWidth` v = `20rem` ). - - popover->ele( n = `SimpleForm` ns = `form` - )->a( n = `layout` v = `ColumnLayout` - )->a( n = `editable` b = abap_false - )->ele( n = `content` ns = `form` - )->tag( `Label` - )->a( n = `text` v = `Product` - )->tag( `Text` - )->a( n = `text` t = mv_product - )->tag( `Label` - )->a( n = `text` v = `info2` - )->tag( `Text` - )->a( n = `text` v = `this is a text` - )->tag( `Label` - )->a( n = `text` v = `info3` - )->tag( `Text` - )->a( n = `text` v = `this is a text` - )->tag( `Text` - )->a( n = `text` v = `this is a text` ). - - popover->ele( `footer` - )->ele( `OverflowToolbar` - )->tag( `ToolbarSpacer` - )->tag( `Button` - )->a( n = `id` v = `btn_details` - )->a( n = `press` v = client->follow_up_action( val = client->cs_event-popover_close ) - )->a( n = `text` v = `details` - )->a( n = `type` v = `Emphasized` ). + METHOD z2ui5_if_app~main. - client->popover_display( xml = lo_popover->stringify( ) by_id = id ). + me->client = client. + IF client->check_on_init( ). + view_display( ). + set_data( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `POPOVER_DETAIL` ). - " a frontend action aimed at the popover: the view parameter scopes the - " id lookup to the popover slot (cs_view-popover), so the focus lands on - " the button INSIDE the popover and Enter confirms it straight away - client->follow_up_action( val = client->cs_event-control_by_id - view = client->cs_view-popover - t_arg = VALUE #( ( `btn_details` ) ( `focus` ) ) ). + mv_check_popover = abap_true. + mv_product = client->get_event_arg( 2 ). + popover_display( client->get_event_arg( ) ). + ENDIF. ENDMETHOD. @@ -159,25 +124,55 @@ CLASS z2ui5_cl_smp_app_052 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. + METHOD popover_display. - me->client = client. + DATA(lo_popover) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` + )->a( n = `xmlns:form` v = `sap.ui.layout.form` ). - IF client->check_on_init( ). + DATA(popover) = lo_popover->ele( `Popover` + )->a( n = `title` t = |abap2UI5 - Popover - { mv_product }| + )->a( n = `placement` v = `Right` + )->a( n = `contentWidth` v = `20rem` ). - view_display( ). - set_data( ). - RETURN. - ELSEIF client->check_on_navigated( ). - view_display( ). - ENDIF. + popover->ele( n = `SimpleForm` ns = `form` + )->a( n = `layout` v = `ColumnLayout` + )->a( n = `editable` b = abap_false + )->ele( n = `content` ns = `form` + )->tag( `Label` + )->a( n = `text` v = `Product` + )->tag( `Text` + )->a( n = `text` t = mv_product + )->tag( `Label` + )->a( n = `text` v = `info2` + )->tag( `Text` + )->a( n = `text` v = `this is a text` + )->tag( `Label` + )->a( n = `text` v = `info3` + )->tag( `Text` + )->a( n = `text` v = `this is a text` + )->tag( `Text` + )->a( n = `text` v = `this is a text` ). + + popover->ele( `footer` + )->ele( `OverflowToolbar` + )->tag( `ToolbarSpacer` + )->tag( `Button` + )->a( n = `id` v = `btn_details` + )->a( n = `press` v = client->follow_up_action( val = client->cs_event-popover_close ) + )->a( n = `text` v = `details` + )->a( n = `type` v = `Emphasized` ). - IF client->check_on_event( `POPOVER_DETAIL` ). + client->popover_display( xml = lo_popover->stringify( ) by_id = id ). - mv_check_popover = abap_true. - mv_product = client->get_event_arg( 2 ). - popover_display( client->get_event_arg( ) ). - ENDIF. + " a frontend action aimed at the popover: the view parameter scopes the + " id lookup to the popover slot (cs_view-popover), so the focus lands on + " the button INSIDE the popover and Enter confirms it straight away + client->follow_up_action( val = client->cs_event-control_by_id + view = client->cs_view-popover + t_arg = VALUE #( ( `btn_details` ) ( `focus` ) ) ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_053.clas.abap b/src/z2ui5_cl_smp_app_053.clas.abap index 0fa31b9f..29f237f0 100644 --- a/src/z2ui5_cl_smp_app_053.clas.abap +++ b/src/z2ui5_cl_smp_app_053.clas.abap @@ -50,18 +50,6 @@ CLASS z2ui5_cl_smp_app_053 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `BUTTON_SEARCH` OR `BUTTON_START`. - set_data( ). - set_search( ). - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -137,6 +125,18 @@ CLASS z2ui5_cl_smp_app_053 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + + WHEN `BUTTON_SEARCH` OR `BUTTON_START`. + set_data( ). + set_search( ). + ENDCASE. + + ENDMETHOD. + + METHOD set_data. mt_table = VALUE #( diff --git a/src/z2ui5_cl_smp_app_059.clas.abap b/src/z2ui5_cl_smp_app_059.clas.abap index bef21da7..3858dff6 100644 --- a/src/z2ui5_cl_smp_app_059.clas.abap +++ b/src/z2ui5_cl_smp_app_059.clas.abap @@ -26,10 +26,10 @@ CLASS z2ui5_cl_smp_app_059 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. + METHODS view_display. METHODS set_data. METHODS set_search. - METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -55,61 +55,6 @@ CLASS z2ui5_cl_smp_app_059 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->check_on_event( `BUTTON_SEARCH` ). - - set_data( ). - set_search( ). - - ENDIF. - - ENDMETHOD. - - - METHOD set_search. - - " a typed contains-search over the columns the table shows - the search - " string is compared uppercase against uppercase, so it matches whatever - " the user typed - DATA(lv_search) = to_upper( mv_field ). - IF lv_search IS INITIAL. - RETURN. - ENDIF. - - DATA(lt_all) = mt_table. - mt_table = VALUE #( ). - - LOOP AT lt_all INTO DATA(ls_row). - IF to_upper( ls_row-product ) CS lv_search - OR to_upper( ls_row-create_date ) CS lv_search - OR to_upper( ls_row-create_by ) CS lv_search - OR to_upper( ls_row-storage_location ) CS lv_search OR |{ ls_row-quantity }| CS lv_search. - INSERT ls_row INTO TABLE mt_table. - ENDIF. - ENDLOOP. - - ENDMETHOD. - - - METHOD set_data. - - mt_table = VALUE #( ). - DO 1000 TIMES. - INSERT LINES OF VALUE ty_t_table( - ( product = `table` create_date = `01.01.2023` create_by = `Peter` storage_location = `AREA_001` quantity = 400 ) - ( product = `chair` create_date = `01.01.2022` create_by = `James` storage_location = `AREA_001` quantity = 123 ) - ( product = `sofa` create_date = `01.05.2021` create_by = `Simone` storage_location = `AREA_001` quantity = 700 ) - ( product = `computer` create_date = `27.01.2023` create_by = `Theo` storage_location = `AREA_001` quantity = 200 ) - ( product = `printer` create_date = `01.01.2023` create_by = `Hannah` storage_location = `AREA_001` quantity = 90 ) - ( product = `table2` create_date = `01.01.2023` create_by = `Julia` storage_location = `AREA_001` quantity = 110 ) - ) INTO TABLE mt_table. - - ENDDO. - - ENDMETHOD. - - METHOD view_display. " The SearchField below round-trips on every keystroke on purpose: the @@ -194,4 +139,59 @@ CLASS z2ui5_cl_smp_app_059 IMPLEMENTATION. " abap2ui5lint-enable live-event-roundtrip ENDMETHOD. + + + METHOD on_event. + + IF client->check_on_event( `BUTTON_SEARCH` ). + + set_data( ). + set_search( ). + + ENDIF. + + ENDMETHOD. + + + METHOD set_search. + + " a typed contains-search over the columns the table shows - the search + " string is compared uppercase against uppercase, so it matches whatever + " the user typed + DATA(lv_search) = to_upper( mv_field ). + IF lv_search IS INITIAL. + RETURN. + ENDIF. + + DATA(lt_all) = mt_table. + mt_table = VALUE #( ). + + LOOP AT lt_all INTO DATA(ls_row). + IF to_upper( ls_row-product ) CS lv_search + OR to_upper( ls_row-create_date ) CS lv_search + OR to_upper( ls_row-create_by ) CS lv_search + OR to_upper( ls_row-storage_location ) CS lv_search OR |{ ls_row-quantity }| CS lv_search. + INSERT ls_row INTO TABLE mt_table. + ENDIF. + ENDLOOP. + + ENDMETHOD. + + + METHOD set_data. + + mt_table = VALUE #( ). + DO 1000 TIMES. + INSERT LINES OF VALUE ty_t_table( + ( product = `table` create_date = `01.01.2023` create_by = `Peter` storage_location = `AREA_001` quantity = 400 ) + ( product = `chair` create_date = `01.01.2022` create_by = `James` storage_location = `AREA_001` quantity = 123 ) + ( product = `sofa` create_date = `01.05.2021` create_by = `Simone` storage_location = `AREA_001` quantity = 700 ) + ( product = `computer` create_date = `27.01.2023` create_by = `Theo` storage_location = `AREA_001` quantity = 200 ) + ( product = `printer` create_date = `01.01.2023` create_by = `Hannah` storage_location = `AREA_001` quantity = 90 ) + ( product = `table2` create_date = `01.01.2023` create_by = `Julia` storage_location = `AREA_001` quantity = 110 ) + ) INTO TABLE mt_table. + + ENDDO. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_061.clas.abap b/src/z2ui5_cl_smp_app_061.clas.abap index 92303c77..c0349c34 100644 --- a/src/z2ui5_cl_smp_app_061.clas.abap +++ b/src/z2ui5_cl_smp_app_061.clas.abap @@ -20,6 +20,47 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_061 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + FIELD-SYMBOLS TYPE table. + + me->client = client. + + IF client->check_on_init( ). + + " The point of this sample is a row type built at runtime from a DDIC + " name. SYST - the structure behind sy - is present on every release + " abap2UI5 runs on, ABAP Cloud included; the framework's own draft table + " is not an API (building-apps guide, section 5) and is not used here. + DATA(row_type) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( `SYST` ) ). + + " the DDIC components plus a SELKZ flag that exists in no dictionary: + " the Table's selection binds to it, so a selected row stays selected + " across roundtrips and re-renders instead of living in the control + DATA(components) = row_type->get_components( ). + INSERT VALUE #( name = `SELKZ` + type = CAST #( cl_abap_typedescr=>describe_by_name( `ABAP_BOOL` ) ) ) INTO TABLE components. + DATA(tab_type) = cl_abap_tabledescr=>create( cl_abap_structdescr=>create( components ) ). + + CREATE DATA t_tab TYPE HANDLE tab_type. + ASSIGN t_tab->* TO . + + " sy IS a SYST, so the rows are filled by component name - the only + " way to write a structure whose type exists at runtime alone + DO 3 TIMES. + APPEND INITIAL LINE TO ASSIGNING FIELD-SYMBOL(). + MOVE-CORRESPONDING sy TO . + ENDDO. + + view_display( ). + + ELSEIF client->check_on_navigated( ). + view_display( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -87,45 +128,4 @@ CLASS z2ui5_cl_smp_app_061 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - FIELD-SYMBOLS TYPE table. - - me->client = client. - - IF client->check_on_init( ). - - " The point of this sample is a row type built at runtime from a DDIC - " name. SYST - the structure behind sy - is present on every release - " abap2UI5 runs on, ABAP Cloud included; the framework's own draft table - " is not an API (building-apps guide, section 5) and is not used here. - DATA(row_type) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( `SYST` ) ). - - " the DDIC components plus a SELKZ flag that exists in no dictionary: - " the Table's selection binds to it, so a selected row stays selected - " across roundtrips and re-renders instead of living in the control - DATA(components) = row_type->get_components( ). - INSERT VALUE #( name = `SELKZ` - type = CAST #( cl_abap_typedescr=>describe_by_name( `ABAP_BOOL` ) ) ) INTO TABLE components. - DATA(tab_type) = cl_abap_tabledescr=>create( cl_abap_structdescr=>create( components ) ). - - CREATE DATA t_tab TYPE HANDLE tab_type. - ASSIGN t_tab->* TO . - - " sy IS a SYST, so the rows are filled by component name - the only - " way to write a structure whose type exists at runtime alone - DO 3 TIMES. - APPEND INITIAL LINE TO ASSIGNING FIELD-SYMBOL(). - MOVE-CORRESPONDING sy TO . - ENDDO. - - view_display( ). - - ELSEIF client->check_on_navigated( ). - view_display( ). - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_064.clas.abap b/src/z2ui5_cl_smp_app_064.clas.abap index 1f56342b..5b1101bb 100644 --- a/src/z2ui5_cl_smp_app_064.clas.abap +++ b/src/z2ui5_cl_smp_app_064.clas.abap @@ -13,8 +13,8 @@ CLASS z2ui5_cl_smp_app_064 DEFINITION PUBLIC. DATA mv_check_active TYPE abap_bool. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -39,39 +39,6 @@ CLASS z2ui5_cl_smp_app_064 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->check_on_event( `LOAD` ). - - " a press starts the bar over, a timer tick carries it on - IF mv_check_active = abap_false. - mv_percent = 0. - ENDIF. - - " the long-running backend step this bar reports on - WAIT UP TO 2 SECONDS. - mv_percent = mv_percent + 25. - - IF mv_percent < 100. - - mv_check_active = abap_true. - mv_check_enabled = abap_false. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-start_timer - t_arg = VALUE #( ( `LOAD` ) ( `0` ) ) ). - - ELSE. - - mv_check_active = abap_false. - mv_check_enabled = abap_true. - client->message_toast_display( `loaded` ). - ENDIF. - - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -116,4 +83,37 @@ CLASS z2ui5_cl_smp_app_064 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->check_on_event( `LOAD` ). + + " a press starts the bar over, a timer tick carries it on + IF mv_check_active = abap_false. + mv_percent = 0. + ENDIF. + + " the long-running backend step this bar reports on + WAIT UP TO 2 SECONDS. + mv_percent = mv_percent + 25. + + IF mv_percent < 100. + + mv_check_active = abap_true. + mv_check_enabled = abap_false. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-start_timer + t_arg = VALUE #( ( `LOAD` ) ( `0` ) ) ). + + ELSE. + + mv_check_active = abap_false. + mv_check_enabled = abap_true. + client->message_toast_display( `loaded` ). + ENDIF. + + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_065.clas.abap b/src/z2ui5_cl_smp_app_065.clas.abap index b4e2f7a7..ff17fd19 100644 --- a/src/z2ui5_cl_smp_app_065.clas.abap +++ b/src/z2ui5_cl_smp_app_065.clas.abap @@ -13,8 +13,8 @@ CLASS z2ui5_cl_smp_app_065 DEFINITION PUBLIC. DATA mv_count TYPE i. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS nest_view_display. PRIVATE SECTION. @@ -38,30 +38,6 @@ CLASS z2ui5_cl_smp_app_065 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - WHEN `TEST`. - client->message_box_display( |input { mv_input_nest }| ). - WHEN `ALL`. - view_display( ). - nest_view_display( ). - WHEN `MAIN`. - view_display( ). - WHEN `NEST`. - nest_view_display( ). - WHEN `NEST_MODEL`. - " change only a nest-bound field, without re-rendering the nested XML. - " The main and nested views share one model and that model is pushed - " with every response, so the nested view picks the change up too. - " After "Rerender Main without nest" there is no nested view to reach. - mv_count = mv_count + 1. - mv_input_nest = |nest model updated #{ mv_count }|. - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(lo_view) = z2ui5_cl_ui5_view_builder=>factory( @@ -107,6 +83,33 @@ CLASS z2ui5_cl_smp_app_065 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `TEST`. + client->message_box_display( |input { mv_input_nest }| ). + WHEN `ALL`. + " the re-render is what this button shows - nothing bound changed + view_display( ). + nest_view_display( ). + WHEN `MAIN`. + " on purpose without nest_view_display( ): the rebuilt main view + " comes up without the nested one + view_display( ). + WHEN `NEST`. + nest_view_display( ). + WHEN `NEST_MODEL`. + " change only a nest-bound field, without re-rendering the nested XML. + " The main and nested views share one model and that model is pushed + " with every response, so the nested view picks the change up too. + " After "Rerender Main without nest" there is no nested view to reach. + mv_count = mv_count + 1. + mv_input_nest = |nest model updated #{ mv_count }|. + ENDCASE. + + ENDMETHOD. + + METHOD nest_view_display. DATA(lo_view_nested) = z2ui5_cl_ui5_view_builder=>factory( diff --git a/src/z2ui5_cl_smp_app_070.clas.abap b/src/z2ui5_cl_smp_app_070.clas.abap index f2bf9c66..dc5cb29c 100644 --- a/src/z2ui5_cl_smp_app_070.clas.abap +++ b/src/z2ui5_cl_smp_app_070.clas.abap @@ -30,8 +30,8 @@ CLASS z2ui5_cl_smp_app_070 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS set_search. METHODS set_data. METHODS set_sort. @@ -64,90 +64,6 @@ CLASS z2ui5_cl_smp_app_070 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - WHEN `BUTTON_SEARCH` OR `BUTTON_START`. - client->message_toast_display( `Search Entries` ). - set_data( ). - set_search( ). - WHEN `SORT`. - set_sort( ). - WHEN `FILTER`. - set_filter( ). - WHEN `SELKZ`. - client->message_toast_display( |'Event SELKZ' { lv_selkz } | ). - set_selkz( lv_selkz ). - WHEN `ROW_ACTION_ITEM_NAVIGATION`. - client->message_toast_display( |Event ROW_ACTION_ITEM_NAVIGATION Row ID { client->get_event_arg( ) }| ). - WHEN `ROW_ACTION_ITEM_EDIT`. - client->message_toast_display( |Event ROW_ACTION_ITEM_EDIT Row ID { client->get_event_arg( ) }| ). - ENDCASE. - - ENDMETHOD. - - - METHOD set_selkz. - - LOOP AT mt_table REFERENCE INTO DATA(lr_row). - lr_row->selkz = iv_selkz. - ENDLOOP. - - ENDMETHOD. - - - METHOD set_sort. - - " the sort event carries the column's sortProperty and the requested - " order - the client sorts its binding too, so both agree, and the - " backend order is the one the next model push would restore - DATA(property) = client->get_event_arg( ). - DATA(sort_order) = client->get_event_arg( 2 ). - - IF sort_order = `Descending`. - SORT mt_table BY (property) DESCENDING. - ELSE. - SORT mt_table BY (property) ASCENDING. - ENDIF. - client->message_toast_display( |Event SORT { property } { sort_order }| ). - - ENDMETHOD. - - - METHOD set_filter. - - " the filter event carries the column's filterProperty and the typed - " value: a contains-filter over that one component, on the full data - DATA(property) = client->get_event_arg( ). - DATA(value) = to_upper( client->get_event_arg( 2 ) ). - - set_data( ). - set_search( ). - - IF value IS INITIAL. - client->message_toast_display( |Event FILTER { property } cleared| ). - RETURN. - ENDIF. - - DATA(lt_all) = mt_table. - mt_table = VALUE #( ). - - LOOP AT lt_all REFERENCE INTO DATA(lr_row). - ASSIGN COMPONENT property OF STRUCTURE lr_row->* TO FIELD-SYMBOL(). - - IF sy-subrc <> 0. - CONTINUE. - ENDIF. - - IF to_upper( |{ }| ) CS value. - INSERT lr_row->* INTO TABLE mt_table. - ENDIF. - ENDLOOP. - client->message_toast_display( |Event FILTER { property } { value }| ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -352,6 +268,90 @@ CLASS z2ui5_cl_smp_app_070 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `BUTTON_SEARCH` OR `BUTTON_START`. + client->message_toast_display( `Search Entries` ). + set_data( ). + set_search( ). + WHEN `SORT`. + set_sort( ). + WHEN `FILTER`. + set_filter( ). + WHEN `SELKZ`. + client->message_toast_display( |'Event SELKZ' { lv_selkz } | ). + set_selkz( lv_selkz ). + WHEN `ROW_ACTION_ITEM_NAVIGATION`. + client->message_toast_display( |Event ROW_ACTION_ITEM_NAVIGATION Row ID { client->get_event_arg( ) }| ). + WHEN `ROW_ACTION_ITEM_EDIT`. + client->message_toast_display( |Event ROW_ACTION_ITEM_EDIT Row ID { client->get_event_arg( ) }| ). + ENDCASE. + + ENDMETHOD. + + + METHOD set_selkz. + + LOOP AT mt_table REFERENCE INTO DATA(lr_row). + lr_row->selkz = iv_selkz. + ENDLOOP. + + ENDMETHOD. + + + METHOD set_sort. + + " the sort event carries the column's sortProperty and the requested + " order - the client sorts its binding too, so both agree, and the + " backend order is the one the next model push would restore + DATA(property) = client->get_event_arg( ). + DATA(sort_order) = client->get_event_arg( 2 ). + + IF sort_order = `Descending`. + SORT mt_table BY (property) DESCENDING. + ELSE. + SORT mt_table BY (property) ASCENDING. + ENDIF. + client->message_toast_display( |Event SORT { property } { sort_order }| ). + + ENDMETHOD. + + + METHOD set_filter. + + " the filter event carries the column's filterProperty and the typed + " value: a contains-filter over that one component, on the full data + DATA(property) = client->get_event_arg( ). + DATA(value) = to_upper( client->get_event_arg( 2 ) ). + + set_data( ). + set_search( ). + + IF value IS INITIAL. + client->message_toast_display( |Event FILTER { property } cleared| ). + RETURN. + ENDIF. + + DATA(lt_all) = mt_table. + mt_table = VALUE #( ). + + LOOP AT lt_all REFERENCE INTO DATA(lr_row). + ASSIGN COMPONENT property OF STRUCTURE lr_row->* TO FIELD-SYMBOL(). + + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + + IF to_upper( |{ }| ) CS value. + INSERT lr_row->* INTO TABLE mt_table. + ENDIF. + ENDLOOP. + client->message_toast_display( |Event FILTER { property } { value }| ). + + ENDMETHOD. + + METHOD set_data. mt_table = VALUE #( diff --git a/src/z2ui5_cl_smp_app_071.clas.abap b/src/z2ui5_cl_smp_app_071.clas.abap index ea800611..b7d287b2 100644 --- a/src/z2ui5_cl_smp_app_071.clas.abap +++ b/src/z2ui5_cl_smp_app_071.clas.abap @@ -79,16 +79,6 @@ CLASS z2ui5_cl_smp_app_071 IMPLEMENTATION. ENDMETHOD. - METHOD combo_fill. - - t_combo = VALUE #( ). - DO combo_number TIMES. - INSERT VALUE #( key = sy-index text = sy-index ) INTO TABLE t_combo. - ENDDO. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -145,4 +135,14 @@ CLASS z2ui5_cl_smp_app_071 IMPLEMENTATION. ENDMETHOD. + + METHOD combo_fill. + + t_combo = VALUE #( ). + DO combo_number TIMES. + INSERT VALUE #( key = sy-index text = sy-index ) INTO TABLE t_combo. + ENDDO. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_073.clas.abap b/src/z2ui5_cl_smp_app_073.clas.abap index a9bb450c..883db1fc 100644 --- a/src/z2ui5_cl_smp_app_073.clas.abap +++ b/src/z2ui5_cl_smp_app_073.clas.abap @@ -21,6 +21,19 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_073 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `BUTTON_OPEN_NEW_TAB` ). + client->follow_up_action( val = z2ui5_if_client=>cs_event-open_new_tab t_arg = VALUE #( ( url_own_get( ) ) ) ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -57,19 +70,6 @@ CLASS z2ui5_cl_smp_app_073 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( `BUTTON_OPEN_NEW_TAB` ). - client->follow_up_action( val = z2ui5_if_client=>cs_event-open_new_tab t_arg = VALUE #( ( url_own_get( ) ) ) ). - ENDIF. - - ENDMETHOD. - - METHOD url_own_get. DATA lt_param TYPE string_table. diff --git a/src/z2ui5_cl_smp_app_074.clas.abap b/src/z2ui5_cl_smp_app_074.clas.abap index 3f5b0586..20de82d7 100644 --- a/src/z2ui5_cl_smp_app_074.clas.abap +++ b/src/z2ui5_cl_smp_app_074.clas.abap @@ -18,8 +18,8 @@ CLASS z2ui5_cl_smp_app_074 DEFINITION PUBLIC. DATA upload_text TYPE string. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. " Both wrap a pair of classes that do the same job under different names: " the first is the ABAP Cloud one, the second the classic on-premise one. @@ -56,6 +56,66 @@ CLASS z2ui5_cl_smp_app_074 IMPLEMENTATION. ENDMETHOD. + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` + )->a( n = `xmlns:z2ui5` v = `z2ui5.cc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - File - Upload to the Backend` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `The file_uploader custom control returns the picked file as a base64 data URL; the backend ` && + `strips the prefix, decodes the payload and reports what arrived - name, size in bytes and content.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + IF upload_name IS NOT INITIAL. + + DATA(box) = page->ele( `Panel` + )->a( n = `headerText` v = `Received in the backend` + )->a( n = `class` v = `sapUiSmallMargin` + )->ele( `VBox` + )->a( n = `class` v = `sapUiSmallMargin` ). + + box->tag( `ObjectStatus` + )->a( n = `title` v = `File` + )->a( n = `text` t = upload_name ). + box->tag( `ObjectStatus` + )->a( n = `title` v = `Size` + )->a( n = `text` t = |{ upload_size } bytes| + )->a( n = `state` v = `Success` ). + box->tag( `TextArea` + )->a( n = `value` t = upload_text + )->a( n = `editable` b = abap_false + )->a( n = `rows` v = `8` + )->a( n = `width` v = `100%` + )->a( n = `class` v = `sapUiSmallMarginTop` ). + + ENDIF. + + page->ele( `footer` + )->ele( `OverflowToolbar` + )->tag( n = `FileUploader` ns = `z2ui5` + )->a( n = `placeholder` v = `filepath here...` + )->a( n = `upload` v = client->_event( `UPLOAD` ) + )->a( n = `path` v = client->_bind( filepath ) + )->a( n = `value` v = client->_bind( file ) ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. TRY. @@ -80,6 +140,8 @@ CLASS z2ui5_cl_smp_app_074 IMPLEMENTATION. file = VALUE #( ). filepath = VALUE #( ). + " the result panel is not part of the view before the first upload, + " and its texts are rendered, not bound - the view is built again view_display( ). ENDIF. @@ -148,64 +210,4 @@ CLASS z2ui5_cl_smp_app_074 IMPLEMENTATION. ENDMETHOD. - - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` - )->a( n = `xmlns:z2ui5` v = `z2ui5.cc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - File - Upload to the Backend` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `The file_uploader custom control returns the picked file as a base64 data URL; the backend ` && - `strips the prefix, decodes the payload and reports what arrived - name, size in bytes and content.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - IF upload_name IS NOT INITIAL. - - DATA(box) = page->ele( `Panel` - )->a( n = `headerText` v = `Received in the backend` - )->a( n = `class` v = `sapUiSmallMargin` - )->ele( `VBox` - )->a( n = `class` v = `sapUiSmallMargin` ). - - box->tag( `ObjectStatus` - )->a( n = `title` v = `File` - )->a( n = `text` t = upload_name ). - box->tag( `ObjectStatus` - )->a( n = `title` v = `Size` - )->a( n = `text` t = |{ upload_size } bytes| - )->a( n = `state` v = `Success` ). - box->tag( `TextArea` - )->a( n = `value` t = upload_text - )->a( n = `editable` b = abap_false - )->a( n = `rows` v = `8` - )->a( n = `width` v = `100%` - )->a( n = `class` v = `sapUiSmallMarginTop` ). - - ENDIF. - - page->ele( `footer` - )->ele( `OverflowToolbar` - )->tag( n = `FileUploader` ns = `z2ui5` - )->a( n = `placeholder` v = `filepath here...` - )->a( n = `upload` v = client->_event( `UPLOAD` ) - )->a( n = `path` v = client->_bind( filepath ) - )->a( n = `value` v = client->_bind( file ) ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_081.clas.abap b/src/z2ui5_cl_smp_app_081.clas.abap index 08138858..bac27223 100644 --- a/src/z2ui5_cl_smp_app_081.clas.abap +++ b/src/z2ui5_cl_smp_app_081.clas.abap @@ -21,8 +21,8 @@ CLASS z2ui5_cl_smp_app_081 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS popover_list_display IMPORTING id TYPE string. @@ -33,25 +33,18 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_081 IMPLEMENTATION. - METHOD popover_list_display. + METHOD z2ui5_if_app~main. - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` ). - view->ele( `Popover` - )->a( n = `title` v = `Popover Title` - )->a( n = `placement` t = mv_placement - )->ele( `List` - )->a( n = `items` v = client->_bind( mt_tab ) - )->a( n = `mode` v = `SingleSelectMaster` - )->a( n = `selectionChange` v = client->_event( val = `SEL_CHANGE` ) - )->tag( `StandardListItem` - )->a( n = `title` v = `{ID}` - )->a( n = `description` v = `{NAME}` - )->a( n = `selected` v = `{SELECTED}` ). + me->client = client. + IF client->check_on_init( ). + on_init( ). + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). - client->popover_display( xml = view->stringify( ) by_id = id ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. ENDMETHOD. @@ -127,22 +120,6 @@ CLASS z2ui5_cl_smp_app_081 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - on_init( ). - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - - METHOD on_event. CASE client->get_event( ). @@ -163,6 +140,29 @@ CLASS z2ui5_cl_smp_app_081 IMPLEMENTATION. ENDMETHOD. + METHOD popover_list_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` ). + view->ele( `Popover` + )->a( n = `title` v = `Popover Title` + )->a( n = `placement` t = mv_placement + )->ele( `List` + )->a( n = `items` v = client->_bind( mt_tab ) + )->a( n = `mode` v = `SingleSelectMaster` + )->a( n = `selectionChange` v = client->_event( val = `SEL_CHANGE` ) + )->tag( `StandardListItem` + )->a( n = `title` v = `{ID}` + )->a( n = `description` v = `{NAME}` + )->a( n = `selected` v = `{SELECTED}` ). + + client->popover_display( xml = view->stringify( ) by_id = id ). + + ENDMETHOD. + + METHOD on_init. mv_placement = `Left`. diff --git a/src/z2ui5_cl_smp_app_097.clas.abap b/src/z2ui5_cl_smp_app_097.clas.abap index 5aa30971..c8362e24 100644 --- a/src/z2ui5_cl_smp_app_097.clas.abap +++ b/src/z2ui5_cl_smp_app_097.clas.abap @@ -37,6 +37,59 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_097 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_init( ). + + t_tab = VALUE #( + ( title = `row_01` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_02` info = `incompleted` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_03` info = `working` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_04` info = `working` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_05` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_06` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) ). + + mv_layout = `OneColumn`. + view_display_master( ). + view_display_detail( ). + + ELSEIF client->check_on_navigated( ). + + " both views again: the detail is a nested view inside the master, so + " a re-displayed master without it would leave the mid column empty + view_display_master( ). + view_display_detail( ). + + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + + METHOD on_event. + + CASE client->get_event( ). + WHEN `ROW_DELETE`. + DELETE t_tab2 WHERE uuid = client->get_event_arg( ). + WHEN `SELCHANGE`. + DATA(lt_sel) = t_tab. + DELETE lt_sel WHERE selected = abap_false. + READ TABLE lt_sel INTO DATA(ls_sel) INDEX 1. + + IF sy-subrc = 0. + + mv_row_id = mv_row_id + 1. + ls_sel-uuid = |{ mv_row_id }|. + INSERT ls_sel INTO TABLE t_tab2. + ENDIF. + mv_layout = `TwoColumnsMidExpanded`. + ENDCASE. + + ENDMETHOD. + + METHOD view_display_detail. DATA(lo_view_nested) = z2ui5_cl_ui5_view_builder=>factory( @@ -146,57 +199,4 @@ CLASS z2ui5_cl_smp_app_097 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - - t_tab = VALUE #( - ( title = `row_01` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_02` info = `incompleted` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_03` info = `working` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_04` info = `working` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_05` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_06` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) ). - - mv_layout = `OneColumn`. - view_display_master( ). - view_display_detail( ). - - ELSEIF client->check_on_navigated( ). - - " both views again: the detail is a nested view inside the master, so - " a re-displayed master without it would leave the mid column empty - view_display_master( ). - view_display_detail( ). - - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `ROW_DELETE`. - DELETE t_tab2 WHERE uuid = client->get_event_arg( ). - WHEN `SELCHANGE`. - DATA(lt_sel) = t_tab. - DELETE lt_sel WHERE selected = abap_false. - READ TABLE lt_sel INTO DATA(ls_sel) INDEX 1. - - IF sy-subrc = 0. - - mv_row_id = mv_row_id + 1. - ls_sel-uuid = |{ mv_row_id }|. - INSERT ls_sel INTO TABLE t_tab2. - ENDIF. - mv_layout = `TwoColumnsMidExpanded`. - ENDCASE. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_098.clas.abap b/src/z2ui5_cl_smp_app_098.clas.abap index 593b5415..a2bf168b 100644 --- a/src/z2ui5_cl_smp_app_098.clas.abap +++ b/src/z2ui5_cl_smp_app_098.clas.abap @@ -39,6 +39,71 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_098 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_init( ). + + t_tab = VALUE #( + ( title = `row_01` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_02` info = `incompleted` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_03` info = `working` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_04` info = `working` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_05` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `row_06` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) ). + + mv_layout = `OneColumn`. + view_display_master( ). + view_display_detail( ). + + ELSEIF client->check_on_navigated( ). + + " every column that was open again: the nested views live inside the + " master, so a re-displayed master alone would leave them empty + view_display_master( ). + view_display_detail( ). + + IF mv_layout = `ThreeColumnsEndExpanded`. + view_display_detail_detail( ). + ENDIF. + + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + + METHOD on_event. + + CASE client->get_event( ). + WHEN `NN_VIEW`. + client->message_box_display( `Event in nested nested view raised` ). + WHEN `ROW_NAVIGATE`. + + " a row without a title has nothing to open - the third column stays + " closed instead of being filled behind a two-column layout + IF client->get_event_arg( ) IS NOT INITIAL. + mv_layout = `ThreeColumnsEndExpanded`. + mv_title = client->get_event_arg( ). + view_display_detail_detail( ). + ENDIF. + + WHEN `SELCHANGE`. + DATA(lt_sel) = t_tab. + DELETE lt_sel WHERE selected = abap_false. + READ TABLE lt_sel INTO DATA(ls_sel) INDEX 1. + + IF sy-subrc = 0 AND NOT line_exists( t_tab2[ title = ls_sel-title ] ). + INSERT ls_sel INTO TABLE t_tab2. + ENDIF. + mv_layout = `TwoColumnsMidExpanded`. + view_display_detail( ). + ENDCASE. + + ENDMETHOD. + + METHOD view_display_detail. DATA(lo_view_nested) = z2ui5_cl_ui5_view_builder=>factory( @@ -177,69 +242,4 @@ CLASS z2ui5_cl_smp_app_098 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - - t_tab = VALUE #( - ( title = `row_01` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_02` info = `incompleted` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_03` info = `working` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_04` info = `working` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_05` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `row_06` info = `completed` descr = `this is a description` icon = `sap-icon://account` ) ). - - mv_layout = `OneColumn`. - view_display_master( ). - view_display_detail( ). - - ELSEIF client->check_on_navigated( ). - - " every column that was open again: the nested views live inside the - " master, so a re-displayed master alone would leave them empty - view_display_master( ). - view_display_detail( ). - - IF mv_layout = `ThreeColumnsEndExpanded`. - view_display_detail_detail( ). - ENDIF. - - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `NN_VIEW`. - client->message_box_display( `Event in nested nested view raised` ). - WHEN `ROW_NAVIGATE`. - - " a row without a title has nothing to open - the third column stays - " closed instead of being filled behind a two-column layout - IF client->get_event_arg( ) IS NOT INITIAL. - mv_layout = `ThreeColumnsEndExpanded`. - mv_title = client->get_event_arg( ). - view_display_detail_detail( ). - ENDIF. - - WHEN `SELCHANGE`. - DATA(lt_sel) = t_tab. - DELETE lt_sel WHERE selected = abap_false. - READ TABLE lt_sel INTO DATA(ls_sel) INDEX 1. - - IF sy-subrc = 0 AND NOT line_exists( t_tab2[ title = ls_sel-title ] ). - INSERT ls_sel INTO TABLE t_tab2. - ENDIF. - mv_layout = `TwoColumnsMidExpanded`. - view_display_detail( ). - ENDCASE. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_104.clas.abap b/src/z2ui5_cl_smp_app_104.clas.abap index d465d494..251378f2 100644 --- a/src/z2ui5_cl_smp_app_104.clas.abap +++ b/src/z2ui5_cl_smp_app_104.clas.abap @@ -52,6 +52,39 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_104 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_init( ). + + t_tab = VALUE #( + ( title = `Class 1` info = `z2ui5_cl_smp_app_105` descr = `this is a description` icon = `sap-icon://account` ) + ( title = `Class 2` info = `z2ui5_cl_smp_app_112` descr = `this is a description` icon = `sap-icon://account` ) ). + + layout = `OneColumn`. + view_display_master( ). + + ELSEIF client->check_on_navigated( ). + + " the embedded view again: it is nested inside the master, so a + " re-displayed master alone would leave the mid column empty - the + " sub-app instance is kept, and with it what was typed into it + view_display_master( ). + + IF app_sub IS BOUND. + view_display_sub( ). + ENDIF. + + ELSEIF client->check_on_event( `SELCHANGE` ). + on_event_selchange( ). + ELSEIF client->check_on_event( ). + " every other event was raised inside the embedded app - it handles it + on_event_sub( ). + ENDIF. + + ENDMETHOD. + + METHOD on_event_sub. IF app_sub IS BOUND. @@ -206,37 +239,4 @@ CLASS z2ui5_cl_smp_app_104 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - - t_tab = VALUE #( - ( title = `Class 1` info = `z2ui5_cl_smp_app_105` descr = `this is a description` icon = `sap-icon://account` ) - ( title = `Class 2` info = `z2ui5_cl_smp_app_112` descr = `this is a description` icon = `sap-icon://account` ) ). - - layout = `OneColumn`. - view_display_master( ). - - ELSEIF client->check_on_navigated( ). - - " the embedded view again: it is nested inside the master, so a - " re-displayed master alone would leave the mid column empty - the - " sub-app instance is kept, and with it what was typed into it - view_display_master( ). - - IF app_sub IS BOUND. - view_display_sub( ). - ENDIF. - - ELSEIF client->check_on_event( `SELCHANGE` ). - on_event_selchange( ). - ELSEIF client->check_on_event( ). - " every other event was raised inside the embedded app - it handles it - on_event_sub( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_105.clas.abap b/src/z2ui5_cl_smp_app_105.clas.abap index 634ad929..c4b54775 100644 --- a/src/z2ui5_cl_smp_app_105.clas.abap +++ b/src/z2ui5_cl_smp_app_105.clas.abap @@ -6,8 +6,8 @@ CLASS z2ui5_cl_smp_app_105 DEFINITION PUBLIC. DATA view_parent TYPE REF TO z2ui5_cl_ui5_view_builder. DATA mv_class_1 TYPE string. - METHODS on_event. METHODS view_display. + METHODS on_event. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. @@ -18,6 +18,21 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_105 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + " No check_on_navigated( ) branch: this is a SUB-APP. It never calls + " client->view_display( ) - it renders into the parent's view reference + " (view_parent), and the parent app owns the screen and re-displays it. + me->client = client. + IF client->check_on_init( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. " Deliberately styled DIFFERENTLY from sub-app class 2 (a table), so the @@ -69,19 +84,4 @@ CLASS z2ui5_cl_smp_app_105 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - " No check_on_navigated( ) branch: this is a SUB-APP. It never calls - " client->view_display( ) - it renders into the parent's view reference - " (view_parent), and the parent app owns the screen and re-displays it. - me->client = client. - IF client->check_on_init( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_109.clas.abap b/src/z2ui5_cl_smp_app_109.clas.abap index 0f94b077..895ebce7 100644 --- a/src/z2ui5_cl_smp_app_109.clas.abap +++ b/src/z2ui5_cl_smp_app_109.clas.abap @@ -11,8 +11,8 @@ CLASS z2ui5_cl_smp_app_109 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS popover_display IMPORTING id TYPE string. @@ -23,53 +23,18 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_109 IMPLEMENTATION. - METHOD popover_display. + METHOD z2ui5_if_app~main. - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` ). - view->ele( `QuickView` - )->a( n = `placement` t = mv_placement - )->ele( `QuickViewPage` - )->a( n = `description` v = `Enjoy` - )->a( n = `header` v = `Employee Info` - )->a( n = `pageId` v = `employeePageId` - )->a( n = `title` v = `choper725` - )->a( n = `titleUrl` v = `https://github.com/abap2UI5/abap2UI5` - )->ele( `QuickViewGroup` - )->a( n = `heading` v = `Contact Details` - )->ele( `QuickViewGroupElement` - )->a( n = `label` v = `Mobile` - )->a( n = `type` v = `mobile` - )->a( n = `value` v = `123-456-789` - )->end( - )->ele( `QuickViewGroupElement` - )->a( n = `label` v = `Phone` - )->a( n = `type` v = `phone` - )->a( n = `value` v = `789-456-123` - )->end( - )->ele( `QuickViewGroupElement` - )->a( n = `emailSubject` v = `Subject` - )->a( n = `label` v = `Email` - )->a( n = `type` v = `email` - )->a( n = `value` v = `thisisemail@email.com` - )->end( - )->end( - )->ele( `QuickViewGroup` - )->a( n = `heading` v = `Company` - )->ele( `QuickViewGroupElement` - )->a( n = `label` v = `Name` - )->a( n = `type` v = `link` - )->a( n = `url` v = `https://github.com/abap2UI5/abap2UI5` - )->a( n = `value` v = `Adventure Company` - )->end( - )->ele( `QuickViewGroupElement` - )->a( n = `label` v = `Address` - )->a( n = `value` v = `Here` - )->end( ). + me->client = client. + IF client->check_on_init( ). - client->popover_display( xml = view->stringify( ) by_id = id ). + mv_placement = `Left`. + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. ENDMETHOD. @@ -139,27 +104,62 @@ CLASS z2ui5_cl_smp_app_109 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). + METHOD on_event. - mv_placement = `Left`. - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). + IF client->check_on_event( `POPOVER` ). + popover_display( `TEST` ). ENDIF. ENDMETHOD. - METHOD on_event. + METHOD popover_display. - IF client->check_on_event( `POPOVER` ). - popover_display( `TEST` ). - ENDIF. + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` ). + view->ele( `QuickView` + )->a( n = `placement` t = mv_placement + )->ele( `QuickViewPage` + )->a( n = `description` v = `Enjoy` + )->a( n = `header` v = `Employee Info` + )->a( n = `pageId` v = `employeePageId` + )->a( n = `title` v = `choper725` + )->a( n = `titleUrl` v = `https://github.com/abap2UI5/abap2UI5` + )->ele( `QuickViewGroup` + )->a( n = `heading` v = `Contact Details` + )->ele( `QuickViewGroupElement` + )->a( n = `label` v = `Mobile` + )->a( n = `type` v = `mobile` + )->a( n = `value` v = `123-456-789` + )->end( + )->ele( `QuickViewGroupElement` + )->a( n = `label` v = `Phone` + )->a( n = `type` v = `phone` + )->a( n = `value` v = `789-456-123` + )->end( + )->ele( `QuickViewGroupElement` + )->a( n = `emailSubject` v = `Subject` + )->a( n = `label` v = `Email` + )->a( n = `type` v = `email` + )->a( n = `value` v = `thisisemail@email.com` + )->end( + )->end( + )->ele( `QuickViewGroup` + )->a( n = `heading` v = `Company` + )->ele( `QuickViewGroupElement` + )->a( n = `label` v = `Name` + )->a( n = `type` v = `link` + )->a( n = `url` v = `https://github.com/abap2UI5/abap2UI5` + )->a( n = `value` v = `Adventure Company` + )->end( + )->ele( `QuickViewGroupElement` + )->a( n = `label` v = `Address` + )->a( n = `value` v = `Here` + )->end( ). + + client->popover_display( xml = view->stringify( ) by_id = id ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_112.clas.abap b/src/z2ui5_cl_smp_app_112.clas.abap index b1f37a0f..1d50cd23 100644 --- a/src/z2ui5_cl_smp_app_112.clas.abap +++ b/src/z2ui5_cl_smp_app_112.clas.abap @@ -13,8 +13,8 @@ CLASS z2ui5_cl_smp_app_112 DEFINITION PUBLIC. DATA mv_class_2 TYPE string. DATA t_items TYPE STANDARD TABLE OF ty_s_item WITH EMPTY KEY. - METHODS on_event. METHODS view_display. + METHODS on_event. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. @@ -25,6 +25,21 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_112 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + " No check_on_navigated( ) branch: this is a SUB-APP. It never calls + " client->view_display( ) - it renders into the parent's view reference + " (view_parent), and the parent app owns the screen and re-displays it. + me->client = client. + IF client->check_on_init( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. " Deliberately styled DIFFERENTLY from sub-app class 1 (a form), so the @@ -69,19 +84,4 @@ CLASS z2ui5_cl_smp_app_112 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - " No check_on_navigated( ) branch: this is a SUB-APP. It never calls - " client->view_display( ) - it renders into the parent's view reference - " (view_parent), and the parent app owns the screen and re-displays it. - me->client = client. - IF client->check_on_init( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_122.clas.abap b/src/z2ui5_cl_smp_app_122.clas.abap index 97c9f875..0022864a 100644 --- a/src/z2ui5_cl_smp_app_122.clas.abap +++ b/src/z2ui5_cl_smp_app_122.clas.abap @@ -42,50 +42,17 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_122 IMPLEMENTATION. - METHOD read_frontend_info. + METHOD z2ui5_if_app~main. - DATA(ls_get) = client->get( ). + me->client = client. + IF client->check_on_init( ). - device_browser = ls_get-s_device-browser-name. - device_browser_version = ls_get-s_device-browser-version. - device_os = ls_get-s_device-os-name. - device_os_version = ls_get-s_device-os-version. - device_systemtype = ls_get-s_device-system. - device_orientation = ls_get-s_device-orientation. - device_height = CONV string( ls_get-s_device-resize-height ). - device_width = CONV string( ls_get-s_device-resize-width ). - device_phone = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-phone ). - device_desktop = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-desktop ). - device_tablet = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-tablet ). - device_combi = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-combi ). - device_touch = ls_get-s_device-support-touch. - device_pointer = ls_get-s_device-support-pointer. - device_retina = ls_get-s_device-support-retina. - ui5_version = ls_get-s_ui5-version. - ui5_theme = ls_get-s_ui5-theme. - ui5_gav = ls_get-s_ui5-gav. - ui5_build_timestamp = ls_get-s_ui5-build_timestamp. + read_frontend_info( ). + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). - " the raw values are short codes (cr, ff, win, mac, ...). cs_device - " names every one of them, so an app branches on the constant rather - " than on a string it would have to know - here into a label per group - browser_label = SWITCH #( ls_get-s_device-browser-name - WHEN z2ui5_if_client=>cs_device-browser-chrome THEN `Google Chrome (or Chromium)` - WHEN z2ui5_if_client=>cs_device-browser-firefox THEN `Mozilla Firefox` - WHEN z2ui5_if_client=>cs_device-browser-safari THEN `Apple Safari` - WHEN z2ui5_if_client=>cs_device-browser-edge THEN `Microsoft Edge` - ELSE `not one cs_device-browser names` ). - os_label = SWITCH #( ls_get-s_device-os-name - WHEN z2ui5_if_client=>cs_device-os-windows THEN `Windows` - WHEN z2ui5_if_client=>cs_device-os-macintosh THEN `macOS` - WHEN z2ui5_if_client=>cs_device-os-linux THEN `Linux` - WHEN z2ui5_if_client=>cs_device-os-ios THEN `iOS` - WHEN z2ui5_if_client=>cs_device-os-android THEN `Android` - ELSE `not one cs_device-os names` ). - orientation_label = SWITCH #( ls_get-s_device-orientation - WHEN z2ui5_if_client=>cs_device-orientation-portrait THEN `portrait - one column would fit best` - WHEN z2ui5_if_client=>cs_device-orientation-landscape THEN `landscape - room for two columns` - ELSE `not one cs_device-orientation names` ). + ENDIF. ENDMETHOD. @@ -233,17 +200,50 @@ CLASS z2ui5_cl_smp_app_122 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. + METHOD read_frontend_info. - me->client = client. - IF client->check_on_init( ). + DATA(ls_get) = client->get( ). - read_frontend_info( ). - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). + device_browser = ls_get-s_device-browser-name. + device_browser_version = ls_get-s_device-browser-version. + device_os = ls_get-s_device-os-name. + device_os_version = ls_get-s_device-os-version. + device_systemtype = ls_get-s_device-system. + device_orientation = ls_get-s_device-orientation. + device_height = CONV string( ls_get-s_device-resize-height ). + device_width = CONV string( ls_get-s_device-resize-width ). + device_phone = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-phone ). + device_desktop = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-desktop ). + device_tablet = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-tablet ). + device_combi = xsdbool( ls_get-s_device-system = z2ui5_if_client=>cs_device-system-combi ). + device_touch = ls_get-s_device-support-touch. + device_pointer = ls_get-s_device-support-pointer. + device_retina = ls_get-s_device-support-retina. + ui5_version = ls_get-s_ui5-version. + ui5_theme = ls_get-s_ui5-theme. + ui5_gav = ls_get-s_ui5-gav. + ui5_build_timestamp = ls_get-s_ui5-build_timestamp. - ENDIF. + " the raw values are short codes (cr, ff, win, mac, ...). cs_device + " names every one of them, so an app branches on the constant rather + " than on a string it would have to know - here into a label per group + browser_label = SWITCH #( ls_get-s_device-browser-name + WHEN z2ui5_if_client=>cs_device-browser-chrome THEN `Google Chrome (or Chromium)` + WHEN z2ui5_if_client=>cs_device-browser-firefox THEN `Mozilla Firefox` + WHEN z2ui5_if_client=>cs_device-browser-safari THEN `Apple Safari` + WHEN z2ui5_if_client=>cs_device-browser-edge THEN `Microsoft Edge` + ELSE `not one cs_device-browser names` ). + os_label = SWITCH #( ls_get-s_device-os-name + WHEN z2ui5_if_client=>cs_device-os-windows THEN `Windows` + WHEN z2ui5_if_client=>cs_device-os-macintosh THEN `macOS` + WHEN z2ui5_if_client=>cs_device-os-linux THEN `Linux` + WHEN z2ui5_if_client=>cs_device-os-ios THEN `iOS` + WHEN z2ui5_if_client=>cs_device-os-android THEN `Android` + ELSE `not one cs_device-os names` ). + orientation_label = SWITCH #( ls_get-s_device-orientation + WHEN z2ui5_if_client=>cs_device-orientation-portrait THEN `portrait - one column would fit best` + WHEN z2ui5_if_client=>cs_device-orientation-landscape THEN `landscape - room for two columns` + ELSE `not one cs_device-orientation names` ). ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_133.clas.abap b/src/z2ui5_cl_smp_app_133.clas.abap index 5f9d87ae..49b30b4e 100644 --- a/src/z2ui5_cl_smp_app_133.clas.abap +++ b/src/z2ui5_cl_smp_app_133.clas.abap @@ -23,6 +23,30 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_133 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_init( ). + + field_01 = `this is a text`. + field_02 = `this is another text`. + selstart = `3`. + selend = `7`. + view_display( ). + + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `BUTTON01` ) OR client->check_on_event( `BUTTON02` ). + + client->follow_up_action( + val = z2ui5_if_client=>cs_event-set_focus + t_arg = VALUE #( ( client->get_event( ) ) ( selstart ) ( selend ) ) ). + client->message_toast_display( |focus changed| ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -81,28 +105,4 @@ CLASS z2ui5_cl_smp_app_133 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - - field_01 = `this is a text`. - field_02 = `this is another text`. - selstart = `3`. - selend = `7`. - view_display( ). - - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( `BUTTON01` ) OR client->check_on_event( `BUTTON02` ). - - client->follow_up_action( - val = z2ui5_if_client=>cs_event-set_focus - t_arg = VALUE #( ( client->get_event( ) ) ( selstart ) ( selend ) ) ). - client->message_toast_display( |focus changed| ). - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_143.clas.abap b/src/z2ui5_cl_smp_app_143.clas.abap index 0dcfc260..e235d1d1 100644 --- a/src/z2ui5_cl_smp_app_143.clas.abap +++ b/src/z2ui5_cl_smp_app_143.clas.abap @@ -19,9 +19,9 @@ CLASS z2ui5_cl_smp_app_143 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -33,7 +33,8 @@ CLASS z2ui5_cl_smp_app_143 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -43,32 +44,6 @@ CLASS z2ui5_cl_smp_app_143 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - gt_data = VALUE ty_t_data( - ( field1 = `21` field2 = `T1` field3 = `TEXT1` ) - ( field1 = `22` field2 = `T1` field3 = `TEXT1` ) - ( field1 = `23` field2 = `T2` field3 = `TEXT1` ) - ( field1 = `24` field2 = `T2` field3 = `TEXT2` ) - ( field1 = `25` field2 = `T3` field3 = `TEXT2` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - " the roundtrip re-renders the view on purpose: that is the model update - " the column filters have to survive - IF client->check_on_event( `ROW_ACTION_ITEM_ADD` ). - client->message_toast_display( |row { client->get_event_arg( ) } pressed| ). - view_display( ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -168,4 +143,28 @@ CLASS z2ui5_cl_smp_app_143 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + " the roundtrip re-renders the view on purpose: that is the model update + " the column filters have to survive + IF client->check_on_event( `ROW_ACTION_ITEM_ADD` ). + client->message_toast_display( |row { client->get_event_arg( ) } pressed| ). + view_display( ). + ENDIF. + + ENDMETHOD. + + + METHOD model_init. + + gt_data = VALUE ty_t_data( + ( field1 = `21` field2 = `T1` field3 = `TEXT1` ) + ( field1 = `22` field2 = `T1` field3 = `TEXT1` ) + ( field1 = `23` field2 = `T2` field3 = `TEXT1` ) + ( field1 = `24` field2 = `T2` field3 = `TEXT2` ) + ( field1 = `25` field2 = `T3` field3 = `TEXT2` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_144.clas.abap b/src/z2ui5_cl_smp_app_144.clas.abap index fd1d7f07..7bb4f8da 100644 --- a/src/z2ui5_cl_smp_app_144.clas.abap +++ b/src/z2ui5_cl_smp_app_144.clas.abap @@ -25,6 +25,23 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_144 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + + t_tab = VALUE #( BASE t_tab + ( title = `entry 01` value = `red` ) + ( title = `entry 02` value = `blue` ) ). + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -92,21 +109,4 @@ CLASS z2ui5_cl_smp_app_144 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - - t_tab = VALUE #( BASE t_tab - ( title = `entry 01` value = `red` ) - ( title = `entry 02` value = `blue` ) ). - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_160.clas.abap b/src/z2ui5_cl_smp_app_160.clas.abap index ef4b1c71..28fc2c73 100644 --- a/src/z2ui5_cl_smp_app_160.clas.abap +++ b/src/z2ui5_cl_smp_app_160.clas.abap @@ -19,9 +19,9 @@ CLASS z2ui5_cl_smp_app_160 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS model_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -44,35 +44,6 @@ CLASS z2ui5_cl_smp_app_160 IMPLEMENTATION. ENDMETHOD. - METHOD model_init. - - mt_output = VALUE #( ). - - DO 10 TIMES. - INSERT VALUE #( index = sy-index - set_sk = `Test` - matnr = `1234567` - pl_total = sy-index * 10 - per_cent_total = sy-index ) INTO TABLE mt_output. - ENDDO. - - ENDMETHOD. - - - METHOD on_event. - - IF client->check_on_event( `PL_TOTAL_CHANGE` ). - client->message_box_display( - |Id of Input via source object: { client->get_event_arg( ) }\n| && - |Id of Input via event.oSource.sId: { client->get_event_arg( 2 ) }\n| && - |Value of same row, index: { client->get_event_arg( 3 ) }\n| && - |Id of parent (row) via event.oSource.oParent.sId: { client->get_event_arg( 4 ) }\n| && - |Attribute of parameters.value: { client->get_event_arg( 5 ) }| ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -158,4 +129,33 @@ CLASS z2ui5_cl_smp_app_160 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->check_on_event( `PL_TOTAL_CHANGE` ). + client->message_box_display( + |Id of Input via source object: { client->get_event_arg( ) }\n| && + |Id of Input via event.oSource.sId: { client->get_event_arg( 2 ) }\n| && + |Value of same row, index: { client->get_event_arg( 3 ) }\n| && + |Id of parent (row) via event.oSource.oParent.sId: { client->get_event_arg( 4 ) }\n| && + |Attribute of parameters.value: { client->get_event_arg( 5 ) }| ). + ENDIF. + + ENDMETHOD. + + + METHOD model_init. + + mt_output = VALUE #( ). + + DO 10 TIMES. + INSERT VALUE #( index = sy-index + set_sk = `Test` + matnr = `1234567` + pl_total = sy-index * 10 + per_cent_total = sy-index ) INTO TABLE mt_output. + ENDDO. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_161.clas.abap b/src/z2ui5_cl_smp_app_161.clas.abap index f163ddcd..ec35f47d 100644 --- a/src/z2ui5_cl_smp_app_161.clas.abap +++ b/src/z2ui5_cl_smp_app_161.clas.abap @@ -20,55 +20,14 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_161 IMPLEMENTATION. - METHOD simple_popup1. - - DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` ). - - DATA(dialog) = popup->ele( `Dialog` - )->a( n = `afterClose` v = client->_event( `BTN_OK_1ND` ) - )->ele( `content` ). - - dialog->tag( `Button` - )->a( n = `press` v = client->_event( `GOTO_2ND` ) - )->a( n = `text` v = `Open 2nd popup` ). - - dialog->end( - )->ele( `buttons` - )->tag( `Button` - )->a( n = `press` v = client->_event( `BTN_OK_1ND` ) - )->a( n = `text` v = `OK` - )->a( n = `type` v = `Emphasized` ). - - client->popup_display( popup->stringify( ) ). - - ENDMETHOD. - - - METHOD simple_popup2. - - DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `FragmentDefinition` ns = `core` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:core` v = `sap.ui.core` ). - - DATA(dialog) = popup->ele( `Dialog` - )->a( n = `afterClose` v = client->_event( `BTN_OK_2ND` ) - )->ele( `content` ). - - dialog->tag( `Label` - )->a( n = `text` v = `this is a second popup` ). - - dialog->end( - )->ele( `buttons` - )->tag( `Button` - )->a( n = `press` v = client->_event( `BTN_OK_2ND` ) - )->a( n = `text` v = `GOTO 1ST POPUP` - )->a( n = `type` v = `Emphasized` ). + METHOD z2ui5_if_app~main. - client->popup_display( popup->stringify( ) ). + me->client = client. + IF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. ENDMETHOD. @@ -124,14 +83,55 @@ CLASS z2ui5_cl_smp_app_161 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. + METHOD simple_popup1. - me->client = client. - IF client->check_on_navigated( ). - view_display( ). - RETURN. - ENDIF. - on_event( ). + DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` ). + + DATA(dialog) = popup->ele( `Dialog` + )->a( n = `afterClose` v = client->_event( `BTN_OK_1ND` ) + )->ele( `content` ). + + dialog->tag( `Button` + )->a( n = `press` v = client->_event( `GOTO_2ND` ) + )->a( n = `text` v = `Open 2nd popup` ). + + dialog->end( + )->ele( `buttons` + )->tag( `Button` + )->a( n = `press` v = client->_event( `BTN_OK_1ND` ) + )->a( n = `text` v = `OK` + )->a( n = `type` v = `Emphasized` ). + + client->popup_display( popup->stringify( ) ). + + ENDMETHOD. + + + METHOD simple_popup2. + + DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `FragmentDefinition` ns = `core` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:core` v = `sap.ui.core` ). + + DATA(dialog) = popup->ele( `Dialog` + )->a( n = `afterClose` v = client->_event( `BTN_OK_2ND` ) + )->ele( `content` ). + + dialog->tag( `Label` + )->a( n = `text` v = `this is a second popup` ). + + dialog->end( + )->ele( `buttons` + )->tag( `Button` + )->a( n = `press` v = client->_event( `BTN_OK_2ND` ) + )->a( n = `text` v = `GOTO 1ST POPUP` + )->a( n = `type` v = `Emphasized` ). + + client->popup_display( popup->stringify( ) ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_163.clas.abap b/src/z2ui5_cl_smp_app_163.clas.abap index 5831f186..bbd3de76 100644 --- a/src/z2ui5_cl_smp_app_163.clas.abap +++ b/src/z2ui5_cl_smp_app_163.clas.abap @@ -8,8 +8,8 @@ CLASS z2ui5_cl_smp_app_163 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS view_menu. PRIVATE SECTION. @@ -18,6 +18,54 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_163 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + view = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Menu - Menu as Popover with core:require` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) + )->a( n = `id` v = `page_main` ). + + view->tag( `MessageStrip` + )->a( n = `text` v = `This sample opens a Menu as a popover anchored to a button; choosing an ` && + `item shows the selected action in a MessageToast.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + DATA(vbox) = view->ele( `VBox` ). + + vbox->tag( `Button` + )->a( n = `press` v = client->_event( `OPEN_MENU` ) + )->a( n = `text` v = `Open Menu` + )->a( n = `id` v = `menuButton` + )->a( n = `class` v = `sapUiSmallMargin` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. IF client->check_on_event( `OPEN_MENU` ). @@ -72,52 +120,4 @@ CLASS z2ui5_cl_smp_app_163 IMPLEMENTATION. ENDMETHOD. - - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - view = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Menu - Menu as Popover with core:require` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) - )->a( n = `id` v = `page_main` ). - - view->tag( `MessageStrip` - )->a( n = `text` v = `This sample opens a Menu as a popover anchored to a button; choosing an ` && - `item shows the selected action in a MessageToast.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - DATA(vbox) = view->ele( `VBox` ). - - vbox->tag( `Button` - )->a( n = `press` v = client->_event( `OPEN_MENU` ) - )->a( n = `text` v = `Open Menu` - )->a( n = `id` v = `menuButton` - )->a( n = `class` v = `sapUiSmallMargin` ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_166.clas.abap b/src/z2ui5_cl_smp_app_166.clas.abap index b8ba1e4b..d04ea2e8 100644 --- a/src/z2ui5_cl_smp_app_166.clas.abap +++ b/src/z2ui5_cl_smp_app_166.clas.abap @@ -38,6 +38,31 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_166 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + + ms_struc-title = `title`. + ms_struc-value = `val01`. + ms_struc-value2 = `val02`. + + ms_struc2-title = `title`. + ms_struc2-value = `val01`. + ms_struc2-value2 = `val02`. + ms_struc2-incl_title = `title_incl`. + ms_struc2-incl_value = `val01_incl`. + ms_struc2-incl_value2 = `val02_incl`. + + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -84,29 +109,4 @@ CLASS z2ui5_cl_smp_app_166 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - - ms_struc-title = `title`. - ms_struc-value = `val01`. - ms_struc-value2 = `val02`. - - ms_struc2-title = `title`. - ms_struc2-value = `val01`. - ms_struc2-value2 = `val02`. - ms_struc2-incl_title = `title_incl`. - ms_struc2-incl_value = `val01_incl`. - ms_struc2-incl_value2 = `val02_incl`. - - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_167.clas.abap b/src/z2ui5_cl_smp_app_167.clas.abap index 16a0d5a8..ebcc126b 100644 --- a/src/z2ui5_cl_smp_app_167.clas.abap +++ b/src/z2ui5_cl_smp_app_167.clas.abap @@ -20,6 +20,26 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_167 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_init( ). + mv_value = `my value`. + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + + CASE client->get_event( ). + WHEN `EVENT_FIX_VAL` OR `EVENT_MODEL_VALUE` OR `SOURCE_PROPERTY_TEXT` OR `EVENT_PROPERTY_VALUE` OR `PARENT_PROPERTY_ID`. + client->message_box_display( |backend event: { client->get_event_arg( ) }| ). + ENDCASE. + + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -71,23 +91,4 @@ CLASS z2ui5_cl_smp_app_167 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - mv_value = `my value`. - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ENDIF. - - CASE client->get_event( ). - WHEN `EVENT_FIX_VAL` OR `EVENT_MODEL_VALUE` OR `SOURCE_PROPERTY_TEXT` OR `EVENT_PROPERTY_VALUE` OR `PARENT_PROPERTY_ID`. - client->message_box_display( |backend event: { client->get_event_arg( ) }| ). - ENDCASE. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_170.clas.abap b/src/z2ui5_cl_smp_app_170.clas.abap index b1ed7458..fde1cea2 100644 --- a/src/z2ui5_cl_smp_app_170.clas.abap +++ b/src/z2ui5_cl_smp_app_170.clas.abap @@ -22,6 +22,71 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_170 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_navigated( ). + view_display( ). + + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Popup - Navigate between Dialogs (NavContainer)` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Open the dialog and pick its tabs: each tab switches the NavContainer inside the dialog ` && + `to another page, on the client - the select event calls the container's to method by id ` && + `(follow_up_action with cs_event-control_by_id), no roundtrip. The first page also opens a second ` && + `popup, whose button brings the first one back.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + page->tag( `Button` + )->a( n = `press` v = client->_event( `POPUP` ) + )->a( n = `text` v = `Open Popup...` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + + METHOD on_event. + + CASE client->get_event( ). + WHEN `GOTO_2ND`. + simple_popup2( ). + + WHEN `BTN_OK_2ND`. + client->popup_destroy( ). + simple_popup1( ). + + WHEN `BTN_OK_1ND`. + client->popup_destroy( ). + + WHEN `POPUP`. + simple_popup1( ). + ENDCASE. + + ENDMETHOD. + + METHOD simple_popup1. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( @@ -117,69 +182,4 @@ CLASS z2ui5_cl_smp_app_170 IMPLEMENTATION. ENDMETHOD. - - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Popup - Navigate between Dialogs (NavContainer)` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Open the dialog and pick its tabs: each tab switches the NavContainer inside the dialog ` && - `to another page, on the client - the select event calls the container's to method by id ` && - `(follow_up_action with cs_event-control_by_id), no roundtrip. The first page also opens a second ` && - `popup, whose button brings the first one back.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - page->tag( `Button` - )->a( n = `press` v = client->_event( `POPUP` ) - )->a( n = `text` v = `Open Popup...` ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `GOTO_2ND`. - simple_popup2( ). - - WHEN `BTN_OK_2ND`. - client->popup_destroy( ). - simple_popup1( ). - - WHEN `BTN_OK_1ND`. - client->popup_destroy( ). - - WHEN `POPUP`. - simple_popup1( ). - ENDCASE. - - ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_navigated( ). - view_display( ). - - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_173.clas.abap b/src/z2ui5_cl_smp_app_173.clas.abap index 726e2b7f..93639833 100644 --- a/src/z2ui5_cl_smp_app_173.clas.abap +++ b/src/z2ui5_cl_smp_app_173.clas.abap @@ -78,6 +78,24 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_173 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + model_init( ). + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `CHANGE_FLAG` ). + " a template:if is evaluated once, while the view is expanded - the + " changed flag reaches it only through a rebuild + view_display( ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. " the template model is the view model, so what the repeat, the with and @@ -261,20 +279,4 @@ CLASS z2ui5_cl_smp_app_173 IMPLEMENTATION. active = abap_true ). ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - model_init( ). - view_display( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( `CHANGE_FLAG` ). - view_display( ). - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_186.clas.abap b/src/z2ui5_cl_smp_app_186.clas.abap index 1647d967..f38c0e26 100644 --- a/src/z2ui5_cl_smp_app_186.clas.abap +++ b/src/z2ui5_cl_smp_app_186.clas.abap @@ -12,9 +12,9 @@ CLASS z2ui5_cl_smp_app_186 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -22,32 +22,16 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_186 IMPLEMENTATION. - METHOD on_init. - - file_name = `Default_File_Name.png`. - file_content_64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAA` && - `KYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIp` && - `QBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW` && - `0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpd` && - `mZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoeP` && - `PQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKc` && - `TNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jc` && - `W+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/` && - `JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3` && - `/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQj` && - `LYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=`. - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. + METHOD z2ui5_if_app~main. - IF client->check_on_event( `BUTTON_DOWNLOAD` ). - client->follow_up_action( - val = client->cs_event-download_b64_file - t_arg = VALUE #( ( file_content_64 ) ( file_name ) ) ). + me->client = client. + IF client->check_on_init( ). + model_init( ). + view_display( ). + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). ENDIF. ENDMETHOD. @@ -108,17 +92,32 @@ CLASS z2ui5_cl_smp_app_186 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. + METHOD on_event. - me->client = client. - IF client->check_on_init( ). - on_init( ). - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). + IF client->check_on_event( `BUTTON_DOWNLOAD` ). + client->follow_up_action( + val = client->cs_event-download_b64_file + t_arg = VALUE #( ( file_content_64 ) ( file_name ) ) ). ENDIF. ENDMETHOD. + + METHOD model_init. + + file_name = `Default_File_Name.png`. + file_content_64 = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAA` && + `KYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIp` && + `QBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW` && + `0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpd` && + `mZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoeP` && + `PQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKc` && + `TNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jc` && + `W+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/` && + `JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3` && + `/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQj` && + `LYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=`. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_189.clas.abap b/src/z2ui5_cl_smp_app_189.clas.abap index 663ca8c8..67548938 100644 --- a/src/z2ui5_cl_smp_app_189.clas.abap +++ b/src/z2ui5_cl_smp_app_189.clas.abap @@ -13,8 +13,8 @@ CLASS z2ui5_cl_smp_app_189 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -22,18 +22,21 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_189 IMPLEMENTATION. - METHOD on_event. + METHOD z2ui5_if_app~main. - CASE client->get_event( ). - WHEN `one_enter`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-set_focus - t_arg = VALUE #( ( `IdTwo` ) ) ). - WHEN `two_enter`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-set_focus - t_arg = VALUE #( ( `IdThree` ) ) ). - ENDCASE. + me->client = client. + IF client->check_on_init( ). + + view_display( ). + client->follow_up_action( + val = z2ui5_if_client=>cs_event-set_focus + t_arg = VALUE #( ( `IdOne` ) ) ). + + ELSEIF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. ENDMETHOD. @@ -85,21 +88,18 @@ CLASS z2ui5_cl_smp_app_189 IMPLEMENTATION. ENDMETHOD. - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_init( ). - - view_display( ). - client->follow_up_action( - val = z2ui5_if_client=>cs_event-set_focus - t_arg = VALUE #( ( `IdOne` ) ) ). + METHOD on_event. - ELSEIF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( ). - on_event( ). - ENDIF. + CASE client->get_event( ). + WHEN `one_enter`. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-set_focus + t_arg = VALUE #( ( `IdTwo` ) ) ). + WHEN `two_enter`. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-set_focus + t_arg = VALUE #( ( `IdThree` ) ) ). + ENDCASE. ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_197.clas.abap b/src/z2ui5_cl_smp_app_197.clas.abap index 27221b15..8a53c377 100644 --- a/src/z2ui5_cl_smp_app_197.clas.abap +++ b/src/z2ui5_cl_smp_app_197.clas.abap @@ -23,7 +23,6 @@ CLASS z2ui5_cl_smp_app_197 DEFINITION PUBLIC. DATA mt_table_full TYPE ty_t_table. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. METHODS on_event_filter. METHODS view_display. METHODS data_read. @@ -44,7 +43,8 @@ CLASS z2ui5_cl_smp_app_197 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + data_read( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `RESET` ). @@ -56,39 +56,6 @@ CLASS z2ui5_cl_smp_app_197 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - data_read( ). - view_display( ). - - ENDMETHOD. - - - METHOD on_event_filter. - - " listClose hands over selectedItems - an ARRAY OF CONTROLS - " (sap.m.FacetFilterItem). The framework marshals every control-valued - " event argument into a flat JSON object carrying its ID plus the values - " of its metadata properties, so a property is read as // - " - there is no mProperties level in the payload. - DATA t_range TYPE RANGE OF string. - - LOOP AT json_get_values( json = client->get_event_arg( ) - name = `key` ) INTO DATA(lv_key). - APPEND VALUE #( sign = `I` option = `EQ` low = lv_key ) TO t_range. - ENDLOOP. - - " an empty selection is no filter at all - the list closed with every - " item unchecked, which must show all rows again, not none of them - mt_table = mt_table_full. - - IF t_range IS NOT INITIAL. - DELETE mt_table WHERE product NOT IN t_range. - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -169,6 +136,31 @@ CLASS z2ui5_cl_smp_app_197 IMPLEMENTATION. ENDMETHOD. + METHOD on_event_filter. + + " listClose hands over selectedItems - an ARRAY OF CONTROLS + " (sap.m.FacetFilterItem). The framework marshals every control-valued + " event argument into a flat JSON object carrying its ID plus the values + " of its metadata properties, so a property is read as // + " - there is no mProperties level in the payload. + DATA t_range TYPE RANGE OF string. + + LOOP AT json_get_values( json = client->get_event_arg( ) + name = `key` ) INTO DATA(lv_key). + APPEND VALUE #( sign = `I` option = `EQ` low = lv_key ) TO t_range. + ENDLOOP. + + " an empty selection is no filter at all - the list closed with every + " item unchecked, which must show all rows again, not none of them + mt_table = mt_table_full. + + IF t_range IS NOT INITIAL. + DELETE mt_table WHERE product NOT IN t_range. + ENDIF. + + ENDMETHOD. + + METHOD json_get_values. " A minimal reader for one string property of a JSON array of objects: diff --git a/src/z2ui5_cl_smp_app_202.clas.abap b/src/z2ui5_cl_smp_app_202.clas.abap index ef6f1ae7..b1662d23 100644 --- a/src/z2ui5_cl_smp_app_202.clas.abap +++ b/src/z2ui5_cl_smp_app_202.clas.abap @@ -20,6 +20,28 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_202 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + IF client->check_on_navigated( ). + view_display( client ). + ELSEIF client->check_on_event( `STEP22` ) OR client->check_on_event( `STEP23` ). + + " the original wizard flow (discardProgress + setNextStep) as two + " generic whitelisted control calls - t_arg is positional: + " id, method, params (the step params are control ids; the view + " defaults to cs_view-main) + next_step = client->get_event( ). + client->follow_up_action( + val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `wiz` ) ( `discardProgress` ) ( `STEP2` ) ) ). + client->follow_up_action( + val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `STEP2` ) ( `setNextStep` ) ( next_step ) ) ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(lr_view) = z2ui5_cl_ui5_view_builder=>factory( @@ -113,26 +135,4 @@ CLASS z2ui5_cl_smp_app_202 IMPLEMENTATION. ENDIF. ENDMETHOD. - - - METHOD z2ui5_if_app~main. - - IF client->check_on_navigated( ). - view_display( client ). - ELSEIF client->check_on_event( `STEP22` ) OR client->check_on_event( `STEP23` ). - - " the original wizard flow (discardProgress + setNextStep) as two - " generic whitelisted control calls - t_arg is positional: - " id, method, params (the step params are control ids; the view - " defaults to cs_view-main) - next_step = client->get_event( ). - client->follow_up_action( - val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `wiz` ) ( `discardProgress` ) ( `STEP2` ) ) ). - client->follow_up_action( - val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `STEP2` ) ( `setNextStep` ) ( next_step ) ) ). - ENDIF. - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_255.clas.abap b/src/z2ui5_cl_smp_app_255.clas.abap index 6b12d22a..f1f23d77 100644 --- a/src/z2ui5_cl_smp_app_255.clas.abap +++ b/src/z2ui5_cl_smp_app_255.clas.abap @@ -20,6 +20,18 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_255 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + IF client->check_on_navigated( ). + view_display( ). + ELSEIF client->check_on_event( `POPOVER` ). + popover_display( `hint_icon` ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. " the classes below exist nowhere in UI5 - they are shipped with the view @@ -170,16 +182,4 @@ CLASS z2ui5_cl_smp_app_255 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - IF client->check_on_navigated( ). - view_display( ). - ELSEIF client->check_on_event( `POPOVER` ). - popover_display( `hint_icon` ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_305.clas.abap b/src/z2ui5_cl_smp_app_305.clas.abap index a0bd1b71..ad7ccb3e 100644 --- a/src/z2ui5_cl_smp_app_305.clas.abap +++ b/src/z2ui5_cl_smp_app_305.clas.abap @@ -23,6 +23,27 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_305 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + t_tab = VALUE #( + ( title = `entry 01` value = `red` ) + ( title = `entry 02` value = `blue` ) + ( title = `entry 03` value = `green` ) + ( title = `entry 04` value = `yellow` ) + ( title = `entry 05` value = `orange` ) + ( title = `entry 06` value = `grey` ) ). + + set_view( ). + ELSEIF client->check_on_navigated( ). + set_view( ). + ENDIF. + + ENDMETHOD. + + METHOD set_view. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -113,25 +134,4 @@ CLASS z2ui5_cl_smp_app_305 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - me->client = client. - - IF client->check_on_init( ). - t_tab = VALUE #( - ( title = `entry 01` value = `red` ) - ( title = `entry 02` value = `blue` ) - ( title = `entry 03` value = `green` ) - ( title = `entry 04` value = `yellow` ) - ( title = `entry 05` value = `orange` ) - ( title = `entry 06` value = `grey` ) ). - - set_view( ). - ELSEIF client->check_on_navigated( ). - set_view( ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_306.clas.abap b/src/z2ui5_cl_smp_app_306.clas.abap index 8f7372b1..30c6d44c 100644 --- a/src/z2ui5_cl_smp_app_306.clas.abap +++ b/src/z2ui5_cl_smp_app_306.clas.abap @@ -173,6 +173,8 @@ CLASS z2ui5_cl_smp_app_306 IMPLEMENTATION. selected_picture = mt_picture_out[ selected = abap_true ]. mv_pic_display = mt_picture[ selected_picture-id ]-data. rebuild_output( ). + " the full-size Image is only part of the view once a picture was + " chosen - the first selection adds a control, so the view is rebuilt view_display( ). ENDCASE. diff --git a/src/z2ui5_cl_smp_app_316.clas.abap b/src/z2ui5_cl_smp_app_316.clas.abap index fda7c429..185926c6 100644 --- a/src/z2ui5_cl_smp_app_316.clas.abap +++ b/src/z2ui5_cl_smp_app_316.clas.abap @@ -31,6 +31,25 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_316 IMPLEMENTATION. + METHOD z2ui5_if_app~main. + + IF client->check_on_init( ). + + " seeded once - a re-display after a navigation keeps what was typed + url = VALUE #( url = `http://www.sap.com` ). + email = VALUE #( email = `email@email.com` + subject = `subject` + body = `body` ). + + view_display( client ). + + ELSEIF client->check_on_navigated( ). + view_display( client ). + ENDIF. + + ENDMETHOD. + + METHOD view_display. DATA(page) = z2ui5_cl_ui5_view_builder=>factory( @@ -165,23 +184,4 @@ CLASS z2ui5_cl_smp_app_316 IMPLEMENTATION. ENDMETHOD. - - METHOD z2ui5_if_app~main. - - IF client->check_on_init( ). - - " seeded once - a re-display after a navigation keeps what was typed - url = VALUE #( url = `http://www.sap.com` ). - email = VALUE #( email = `email@email.com` - subject = `subject` - body = `body` ). - - view_display( client ). - - ELSEIF client->check_on_navigated( ). - view_display( client ). - ENDIF. - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_325.clas.abap b/src/z2ui5_cl_smp_app_325.clas.abap index 8b098119..f0ac5cba 100644 --- a/src/z2ui5_cl_smp_app_325.clas.abap +++ b/src/z2ui5_cl_smp_app_325.clas.abap @@ -106,22 +106,21 @@ CLASS z2ui5_cl_smp_app_325 IMPLEMENTATION. client->view_display( view->stringify( ) ). - ENDIF. + ELSEIF client->check_on_event( `COPY_INPUT` ). + + client->follow_up_action( + val = z2ui5_if_client=>cs_event-clipboard_copy + t_arg = VALUE #( ( input ) ) ). + client->message_toast_display( |input field copied: { input }| ). - CASE client->get_event( ). - WHEN `COPY_INPUT`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-clipboard_copy - t_arg = VALUE #( ( input ) ) ). - client->message_toast_display( |input field copied: { input }| ). + ELSEIF client->check_on_event( `COPY_TEXT_AREA` ). - WHEN `COPY_TEXT_AREA`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-clipboard_copy - t_arg = VALUE #( ( text ) ) ). - client->message_toast_display( |text area copied: { text }| ). + client->follow_up_action( + val = z2ui5_if_client=>cs_event-clipboard_copy + t_arg = VALUE #( ( text ) ) ). + client->message_toast_display( |text area copied: { text }| ). - ENDCASE. + ENDIF. ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_327.clas.abap b/src/z2ui5_cl_smp_app_327.clas.abap index 4efb58a2..248eb7a5 100644 --- a/src/z2ui5_cl_smp_app_327.clas.abap +++ b/src/z2ui5_cl_smp_app_327.clas.abap @@ -36,9 +36,9 @@ CLASS z2ui5_cl_smp_app_327 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS json_get_value IMPORTING json TYPE string @@ -56,7 +56,8 @@ CLASS z2ui5_cl_smp_app_327 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -66,72 +67,6 @@ CLASS z2ui5_cl_smp_app_327 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_types = VALUE #( ( type = `local` ) ( type = `session` ) ). - s_storage = VALUE #( type = `local` - prefix = `prefix1` - key = `key1` - value = VALUE #( field1 = `1` - field2 = `textfld1` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `LOCAL_STORAGE_LOADED`. - " The z2ui5:Storage control read a value out of the browser storage - " and reports it through its `finished` event. The payload is a whole - " structure, so it arrives as JSON - here it is picked apart field by - " field, which is also what keeps this tolerant: whatever sits under - " the key may carry more (or other) fields than this app models - an - " earlier shape, or a value someone else wrote. A field that is not - " there simply stays empty. - DATA(lv_json) = client->get_event_arg( 4 ). - s_storage-value = VALUE #( field1 = json_get_value( json = lv_json - name = `FIELD1` ) - field2 = json_get_value( json = lv_json - name = `FIELD2` ) ). - - WHEN `GET_STORED_VALUE`. - " The z2ui5:Storage control reads the storage only when it renders, - " and `store` writes it on the client without a roundtrip - so the - " last value read may be stale. Take it, and re-display: the fresh - " control reads the key again and reports a newer value through - " `finished` (LOCAL_STORAGE_LOADED above). - s_storage-value = s_stored_value. - view_display( ). - - ENDCASE. - - ENDMETHOD. - - - METHOD json_get_value. - - " A minimal reader for one string field of a flat JSON object: find - " `"":"` and take what stands up to the next quote. The model writes - " the ABAP component names in upper case, hence the case-insensitive - " search. An app parsing arbitrary JSON wants a real parser instead. - DATA(lv_marker) = |"{ name }":"|. - - DATA(lv_off) = find( val = json sub = lv_marker case = abap_false ). - IF lv_off < 0. - RETURN. - ENDIF. - - result = substring_before( val = substring( val = json - off = lv_off + strlen( lv_marker ) ) - sub = `"` ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -220,4 +155,68 @@ CLASS z2ui5_cl_smp_app_327 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `LOCAL_STORAGE_LOADED`. + " The z2ui5:Storage control read a value out of the browser storage + " and reports it through its `finished` event. The payload is a whole + " structure, so it arrives as JSON - here it is picked apart field by + " field, which is also what keeps this tolerant: whatever sits under + " the key may carry more (or other) fields than this app models - an + " earlier shape, or a value someone else wrote. A field that is not + " there simply stays empty. + DATA(lv_json) = client->get_event_arg( 4 ). + s_storage-value = VALUE #( field1 = json_get_value( json = lv_json + name = `FIELD1` ) + field2 = json_get_value( json = lv_json + name = `FIELD2` ) ). + + WHEN `GET_STORED_VALUE`. + " The z2ui5:Storage control reads the storage only when it renders, + " and `store` writes it on the client without a roundtrip - so the + " last value read may be stale. Take it, and re-display: the fresh + " control reads the key again and reports a newer value through + " `finished` (LOCAL_STORAGE_LOADED above). + s_storage-value = s_stored_value. + view_display( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD json_get_value. + + " A minimal reader for one string field of a flat JSON object: find + " `"":"` and take what stands up to the next quote. The model writes + " the ABAP component names in upper case, hence the case-insensitive + " search. An app parsing arbitrary JSON wants a real parser instead. + DATA(lv_marker) = |"{ name }":"|. + + DATA(lv_off) = find( val = json sub = lv_marker case = abap_false ). + IF lv_off < 0. + RETURN. + ENDIF. + + result = substring_before( val = substring( val = json + off = lv_off + strlen( lv_marker ) ) + sub = `"` ). + + ENDMETHOD. + + + METHOD model_init. + + t_types = VALUE #( ( type = `local` ) ( type = `session` ) ). + s_storage = VALUE #( type = `local` + prefix = `prefix1` + key = `key1` + value = VALUE #( field1 = `1` + field2 = `textfld1` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_362.clas.abap b/src/z2ui5_cl_smp_app_362.clas.abap index b2e78af6..034f2240 100644 --- a/src/z2ui5_cl_smp_app_362.clas.abap +++ b/src/z2ui5_cl_smp_app_362.clas.abap @@ -18,9 +18,9 @@ CLASS z2ui5_cl_smp_app_362 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS restore_scroll. PRIVATE SECTION. @@ -34,7 +34,8 @@ CLASS z2ui5_cl_smp_app_362 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -44,74 +45,6 @@ CLASS z2ui5_cl_smp_app_362 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - DO 100 TIMES. - INSERT VALUE #( title = |Row { sy-index }| - value = `red` - info = `completed` - descr = `this is a description` ) - INTO TABLE t_tab. - ENDDO. - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - " The SCROLL_TO client event sets scrollTop / scrollLeft by pixel. - " args: ( control-id, scrollTop, scrollLeft, behavior ) - " behavior is one of: "auto" (default, instant), "smooth", "instant". - CASE client->get_event( ). - WHEN `SCROLL_TOP`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_to - t_arg = VALUE #( ( `id_page` ) ( `0` ) ( `0` ) ( `smooth` ) ) ). - WHEN `SCROLL_MIDDLE`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_to - t_arg = VALUE #( ( `id_page` ) ( `1500` ) ( `0` ) ( `smooth` ) ) ). - WHEN `SCROLL_BOTTOM`. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_to - t_arg = VALUE #( ( `id_page` ) ( `99999` ) ( `0` ) ( `smooth` ) ) ). - WHEN `SCROLL_JUMP`. - " Same target as middle but without smooth - instant snap. - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_to - t_arg = VALUE #( ( `id_page` ) ( `1500` ) ( `0` ) ) ). - WHEN `REFRESH`. - " The redraw of the view resets the scroll position. - " The current scroll info comes in on every roundtrip via - " client->get( )-s_scroll, so we push it back via SCROLL_TO and - " the user lands at the exact same spot after the redraw. - view_display( ). - restore_scroll( ). - client->message_toast_display( `Table refreshed, scroll preserved` ). - ENDCASE. - - ENDMETHOD. - - - METHOD restore_scroll. - - DATA(scroll) = client->get( )-s_scroll-main. - - IF scroll-id IS INITIAL. - RETURN. - ENDIF. - - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_to - t_arg = VALUE #( ( scroll-id ) - ( |{ scroll-y }| ) - ( |{ scroll-x }| ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -187,4 +120,70 @@ CLASS z2ui5_cl_smp_app_362 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD on_event. + + " The SCROLL_TO client event sets scrollTop / scrollLeft by pixel. + " args: ( control-id, scrollTop, scrollLeft, behavior ) + " behavior is one of: "auto" (default, instant), "smooth", "instant". + CASE client->get_event( ). + WHEN `SCROLL_TOP`. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_to + t_arg = VALUE #( ( `id_page` ) ( `0` ) ( `0` ) ( `smooth` ) ) ). + WHEN `SCROLL_MIDDLE`. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_to + t_arg = VALUE #( ( `id_page` ) ( `1500` ) ( `0` ) ( `smooth` ) ) ). + WHEN `SCROLL_BOTTOM`. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_to + t_arg = VALUE #( ( `id_page` ) ( `99999` ) ( `0` ) ( `smooth` ) ) ). + WHEN `SCROLL_JUMP`. + " Same target as middle but without smooth - instant snap. + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_to + t_arg = VALUE #( ( `id_page` ) ( `1500` ) ( `0` ) ) ). + WHEN `REFRESH`. + " The redraw of the view resets the scroll position. + " The current scroll info comes in on every roundtrip via + " client->get( )-s_scroll, so we push it back via SCROLL_TO and + " the user lands at the exact same spot after the redraw. + view_display( ). + restore_scroll( ). + client->message_toast_display( `Table refreshed, scroll preserved` ). + ENDCASE. + + ENDMETHOD. + + + METHOD restore_scroll. + + DATA(scroll) = client->get( )-s_scroll-main. + + IF scroll-id IS INITIAL. + RETURN. + ENDIF. + + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_to + t_arg = VALUE #( ( scroll-id ) + ( |{ scroll-y }| ) + ( |{ scroll-x }| ) ) ). + + ENDMETHOD. + + + METHOD model_init. + + DO 100 TIMES. + INSERT VALUE #( title = |Row { sy-index }| + value = `red` + info = `completed` + descr = `this is a description` ) + INTO TABLE t_tab. + ENDDO. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_363.clas.abap b/src/z2ui5_cl_smp_app_363.clas.abap index cdefe023..00453e0f 100644 --- a/src/z2ui5_cl_smp_app_363.clas.abap +++ b/src/z2ui5_cl_smp_app_363.clas.abap @@ -13,8 +13,8 @@ CLASS z2ui5_cl_smp_app_363 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -34,40 +34,6 @@ CLASS z2ui5_cl_smp_app_363 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - DATA(target) = client->get_event( ). - DATA(behavior) = `smooth`. - DATA(block) = `start`. - - CASE target. - WHEN `JUMP_BOTTOM`. - target = `bottom_input`. - WHEN `JUMP_MIDDLE`. - target = `middle_input`. - block = `center`. - WHEN `JUMP_TOP`. - target = `top_input`. - WHEN `VALIDATE`. - IF field_02 IS INITIAL. - target = `middle_input`. - block = `center`. - client->message_toast_display( `Middle field is required` ). - ELSE. - client->message_toast_display( `All fields ok` ). - RETURN. - ENDIF. - WHEN OTHERS. - RETURN. - ENDCASE. - - client->follow_up_action( - val = z2ui5_if_client=>cs_event-scroll_into_view - t_arg = VALUE #( ( target ) ( behavior ) ( block ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -149,4 +115,38 @@ CLASS z2ui5_cl_smp_app_363 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + DATA(target) = client->get_event( ). + DATA(behavior) = `smooth`. + DATA(block) = `start`. + + CASE target. + WHEN `JUMP_BOTTOM`. + target = `bottom_input`. + WHEN `JUMP_MIDDLE`. + target = `middle_input`. + block = `center`. + WHEN `JUMP_TOP`. + target = `top_input`. + WHEN `VALIDATE`. + IF field_02 IS INITIAL. + target = `middle_input`. + block = `center`. + client->message_toast_display( `Middle field is required` ). + ELSE. + client->message_toast_display( `All fields ok` ). + RETURN. + ENDIF. + WHEN OTHERS. + RETURN. + ENDCASE. + + client->follow_up_action( + val = z2ui5_if_client=>cs_event-scroll_into_view + t_arg = VALUE #( ( target ) ( behavior ) ( block ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_381.clas.abap b/src/z2ui5_cl_smp_app_381.clas.abap index c45115c7..bcf75311 100644 --- a/src/z2ui5_cl_smp_app_381.clas.abap +++ b/src/z2ui5_cl_smp_app_381.clas.abap @@ -76,127 +76,6 @@ CLASS z2ui5_cl_smp_app_381 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - message = `This is a message toast.`. - duration = `3000`. - width = `15em`. - my = `center bottom`. - at = `center bottom`. - offset = `0 0`. - collision = `fit fit`. - animation_timing = `ease`. - animation_duration = `1000`. - autoclose = abap_true. - close_on_navigation = abap_true. - notify_close = abap_true. - css_class = `myToast`. - closed_text = `no toast closed yet`. - - ENDMETHOD. - - - METHOD show_toast. - - " Where a toast docks, how it animates, how wide it is - that is the - " CONTROL, not the ABAP app, so it is set the way every other UI5 control - " is steered from here: the whitelisted global call, whose last argument - " is the option object of sap.m.MessageToast.show( ) 1:1. - " - " client->message_toast_display( ) carries none of these. It carries what - " an ABAP app decides - the text, how long the toast stands, and the - " backend event its closing raises - and the class - " Z2UI5_CL_SMP_APP_502 shows that side for the message box - client->follow_up_action( val = client->cs_event-control_global - t_arg = VALUE #( ( `MESSAGE_TOAST` ) - ( `show` ) - ( message ) - ( toast_options( ) ) ) ). - - ENDMETHOD. - - - METHOD toast_options. - - DATA t_opt TYPE string_table. - - " The option object as JSON. A t_arg that starts with a brace is embedded - " as REAL JSON by the framework, so this arrives on the client as an - " object - not as a string that happens to look like one. Numbers stay - " unquoted and flags are true/false, because sap.m.MessageToast checks - " the type of every option it reads. - " - " An option the form left EMPTY is left out rather than sent empty: a - " `"duration":` is no JSON, the backend would fail to parse the whole - " object and embed it as a plain string, and the toast would then show - " with no options at all - quietly, which is the one failure mode of this - " path worth knowing - " The two numbers travel unquoted, so anything but digits would break the - " object - a typo in the form then costs the OPTIONS, not the toast - IF duration IS NOT INITIAL AND duration CO `0123456789`. - APPEND |"duration":{ duration }| TO t_opt. - ENDIF. - IF animation_duration IS NOT INITIAL AND animation_duration CO `0123456789`. - APPEND |"animationDuration":{ animation_duration }| TO t_opt. - ENDIF. - LOOP AT VALUE ty_t_opt( ( name = `width` val = width ) - ( name = `my` val = my ) - ( name = `at` val = at ) - ( name = `offset` val = offset ) - ( name = `collision` val = collision ) - ( name = `animationTimingFunction` val = animation_timing ) ) INTO DATA(s_opt). - IF s_opt-val IS NOT INITIAL. - APPEND |"{ s_opt-name }":"{ json_escape( s_opt-val ) }"| TO t_opt. - ENDIF. - ENDLOOP. - APPEND |"autoClose":{ COND string( WHEN autoclose = abap_true THEN `true` ELSE `false` ) }| TO t_opt. - APPEND |"closeOnBrowserNavigation":{ COND string( WHEN close_on_navigation = abap_true THEN `true` ELSE `false` ) }| TO t_opt. - - " `of` is the element the toast docks to - my/at are read relative to it - " instead of to the window. It travels as a jQuery selector, so the - " anchor is a DOM node with an id the backend can spell: the core:HTML - " box in the view below, not a control whose id UI5 prefixes at runtime - IF dock_to_anchor = abap_true. - APPEND |"of":"#toastAnchor"| TO t_opt. - ENDIF. - - " `class` is the one entry here that is NO MessageToast option: the - " frontend puts the classes on the DOM node of the toast, which carries - " no id to address it by. It rides in the same object - IF css_class IS NOT INITIAL. - APPEND |"class":"{ json_escape( css_class ) }"| TO t_opt. - ENDIF. - - " onClose is a BACKEND event name here, not a JS callback: the frontend - " turns it into the round-trip that reaches on_event below - IF notify_close = abap_true. - APPEND |"onClose":"TOAST_CLOSED"| TO t_opt. - ENDIF. - - LOOP AT t_opt INTO DATA(option). - IF result IS INITIAL. - result = option. - ELSE. - result = |{ result },{ option }|. - ENDIF. - ENDLOOP. - - result = |\{{ result }\}|. - - ENDMETHOD. - - - METHOD json_escape. - - " The values above are typed into the form: a `"` or `\` left raw would - " end the string early, the object would not parse, and the toast would - " show with no options - quietly (see toast_options) - result = replace( val = val sub = `\` with = `\\` occ = 0 ). - result = replace( val = result sub = `"` with = `\"` occ = 0 ). - - ENDMETHOD. - - METHOD view_display. DATA(page) = z2ui5_cl_ui5_view_builder=>factory( @@ -402,6 +281,127 @@ CLASS z2ui5_cl_smp_app_381 IMPLEMENTATION. ENDMETHOD. + METHOD on_init. + + message = `This is a message toast.`. + duration = `3000`. + width = `15em`. + my = `center bottom`. + at = `center bottom`. + offset = `0 0`. + collision = `fit fit`. + animation_timing = `ease`. + animation_duration = `1000`. + autoclose = abap_true. + close_on_navigation = abap_true. + notify_close = abap_true. + css_class = `myToast`. + closed_text = `no toast closed yet`. + + ENDMETHOD. + + + METHOD show_toast. + + " Where a toast docks, how it animates, how wide it is - that is the + " CONTROL, not the ABAP app, so it is set the way every other UI5 control + " is steered from here: the whitelisted global call, whose last argument + " is the option object of sap.m.MessageToast.show( ) 1:1. + " + " client->message_toast_display( ) carries none of these. It carries what + " an ABAP app decides - the text, how long the toast stands, and the + " backend event its closing raises - and the class + " Z2UI5_CL_SMP_APP_502 shows that side for the message box + client->follow_up_action( val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_TOAST` ) + ( `show` ) + ( message ) + ( toast_options( ) ) ) ). + + ENDMETHOD. + + + METHOD toast_options. + + DATA t_opt TYPE string_table. + + " The option object as JSON. A t_arg that starts with a brace is embedded + " as REAL JSON by the framework, so this arrives on the client as an + " object - not as a string that happens to look like one. Numbers stay + " unquoted and flags are true/false, because sap.m.MessageToast checks + " the type of every option it reads. + " + " An option the form left EMPTY is left out rather than sent empty: a + " `"duration":` is no JSON, the backend would fail to parse the whole + " object and embed it as a plain string, and the toast would then show + " with no options at all - quietly, which is the one failure mode of this + " path worth knowing + " The two numbers travel unquoted, so anything but digits would break the + " object - a typo in the form then costs the OPTIONS, not the toast + IF duration IS NOT INITIAL AND duration CO `0123456789`. + APPEND |"duration":{ duration }| TO t_opt. + ENDIF. + IF animation_duration IS NOT INITIAL AND animation_duration CO `0123456789`. + APPEND |"animationDuration":{ animation_duration }| TO t_opt. + ENDIF. + LOOP AT VALUE ty_t_opt( ( name = `width` val = width ) + ( name = `my` val = my ) + ( name = `at` val = at ) + ( name = `offset` val = offset ) + ( name = `collision` val = collision ) + ( name = `animationTimingFunction` val = animation_timing ) ) INTO DATA(s_opt). + IF s_opt-val IS NOT INITIAL. + APPEND |"{ s_opt-name }":"{ json_escape( s_opt-val ) }"| TO t_opt. + ENDIF. + ENDLOOP. + APPEND |"autoClose":{ COND string( WHEN autoclose = abap_true THEN `true` ELSE `false` ) }| TO t_opt. + APPEND |"closeOnBrowserNavigation":{ COND string( WHEN close_on_navigation = abap_true THEN `true` ELSE `false` ) }| TO t_opt. + + " `of` is the element the toast docks to - my/at are read relative to it + " instead of to the window. It travels as a jQuery selector, so the + " anchor is a DOM node with an id the backend can spell: the core:HTML + " box in the view below, not a control whose id UI5 prefixes at runtime + IF dock_to_anchor = abap_true. + APPEND |"of":"#toastAnchor"| TO t_opt. + ENDIF. + + " `class` is the one entry here that is NO MessageToast option: the + " frontend puts the classes on the DOM node of the toast, which carries + " no id to address it by. It rides in the same object + IF css_class IS NOT INITIAL. + APPEND |"class":"{ json_escape( css_class ) }"| TO t_opt. + ENDIF. + + " onClose is a BACKEND event name here, not a JS callback: the frontend + " turns it into the round-trip that reaches on_event below + IF notify_close = abap_true. + APPEND |"onClose":"TOAST_CLOSED"| TO t_opt. + ENDIF. + + LOOP AT t_opt INTO DATA(option). + IF result IS INITIAL. + result = option. + ELSE. + result = |{ result },{ option }|. + ENDIF. + ENDLOOP. + + result = |\{{ result }\}|. + + ENDMETHOD. + + + METHOD json_escape. + + " The values above are typed into the form: a `"` or `\` left raw would + " end the string early, the object would not parse, and the toast would + " show with no options - quietly (see toast_options) + result = replace( val = val sub = `\` with = `\\` occ = 0 ). + result = replace( val = result sub = `"` with = `\"` occ = 0 ). + + ENDMETHOD. + + METHOD get_positions. result = VALUE #( diff --git a/src/z2ui5_cl_smp_app_382.clas.abap b/src/z2ui5_cl_smp_app_382.clas.abap index 5b0eab14..cf755135 100644 --- a/src/z2ui5_cl_smp_app_382.clas.abap +++ b/src/z2ui5_cl_smp_app_382.clas.abap @@ -14,8 +14,8 @@ CLASS z2ui5_cl_smp_app_382 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -38,44 +38,6 @@ CLASS z2ui5_cl_smp_app_382 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - title = `abap2UI5`. - message = `This is a message box.`. - details = `These are additional details about the message.`. - - ENDMETHOD. - - - METHOD on_event. - - " every box names BOX_CLOSED as its onclose event: the button the user - " pressed comes back as the first event argument - the type's default - " (OK, CANCEL, CLOSE) or one of the custom actions - CASE client->get_event( ). - WHEN `BOX_CLOSED`. - client->message_toast_display( |Answer: { client->get_event_arg( ) }| ). - WHEN `CUSTOM`. - client->message_box_display( - text = message - title = title - type = `information` - details = details - actions = VALUE #( ( `Approve` ) ( `Reject` ) ) - emphasizedaction = `Approve` - onclose = `BOX_CLOSED` ). - WHEN OTHERS. - client->message_box_display( - text = message - title = title - type = client->get_event( ) - details = details - onclose = `BOX_CLOSED` ). - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(page) = z2ui5_cl_ui5_view_builder=>factory( @@ -156,4 +118,42 @@ CLASS z2ui5_cl_smp_app_382 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + " every box names BOX_CLOSED as its onclose event: the button the user + " pressed comes back as the first event argument - the type's default + " (OK, CANCEL, CLOSE) or one of the custom actions + CASE client->get_event( ). + WHEN `BOX_CLOSED`. + client->message_toast_display( |Answer: { client->get_event_arg( ) }| ). + WHEN `CUSTOM`. + client->message_box_display( + text = message + title = title + type = `information` + details = details + actions = VALUE #( ( `Approve` ) ( `Reject` ) ) + emphasizedaction = `Approve` + onclose = `BOX_CLOSED` ). + WHEN OTHERS. + client->message_box_display( + text = message + title = title + type = client->get_event( ) + details = details + onclose = `BOX_CLOSED` ). + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + title = `abap2UI5`. + message = `This is a message box.`. + details = `These are additional details about the message.`. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_421.clas.abap b/src/z2ui5_cl_smp_app_421.clas.abap index ad8943a4..4e2e8832 100644 --- a/src/z2ui5_cl_smp_app_421.clas.abap +++ b/src/z2ui5_cl_smp_app_421.clas.abap @@ -34,8 +34,8 @@ CLASS z2ui5_cl_smp_app_421 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS focus. METHODS read_focus. METHODS next_focus. @@ -62,40 +62,6 @@ CLASS z2ui5_cl_smp_app_421 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_tab = VALUE #( - ( index = 0 title = `entry 01` value = `red` info = `completed` description = `this is a description` checkbox = abap_true ) - ( index = 1 title = `entry 02` value = `blue` info = `completed` description = `this is a description` checkbox = abap_true ) - ( index = 2 title = `entry 03` value = `green` info = `completed` description = `this is a description` checkbox = abap_true ) - ( index = 3 title = `entry 04` value = `orange` info = `completed` description = `` checkbox = abap_true ) - ( index = 4 title = `entry 05` value = `grey` info = `completed` description = `this is a description` checkbox = abap_true ) - ( index = 5 title = `` value = `` info = `` description = `` checkbox = abap_false ) ). - - default_focus( ). - view_display( ). - focus( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `FOCUS`. - focus( ). - WHEN `NEXT`. - read_focus( ). - next_focus( ). - focus( ). - WHEN `RESET`. - default_focus( ). - focus( ). - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -222,6 +188,40 @@ CLASS z2ui5_cl_smp_app_421 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `FOCUS`. + focus( ). + WHEN `NEXT`. + read_focus( ). + next_focus( ). + focus( ). + WHEN `RESET`. + default_focus( ). + focus( ). + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + t_tab = VALUE #( + ( index = 0 title = `entry 01` value = `red` info = `completed` description = `this is a description` checkbox = abap_true ) + ( index = 1 title = `entry 02` value = `blue` info = `completed` description = `this is a description` checkbox = abap_true ) + ( index = 2 title = `entry 03` value = `green` info = `completed` description = `this is a description` checkbox = abap_true ) + ( index = 3 title = `entry 04` value = `orange` info = `completed` description = `` checkbox = abap_true ) + ( index = 4 title = `entry 05` value = `grey` info = `completed` description = `this is a description` checkbox = abap_true ) + ( index = 5 title = `` value = `` info = `` description = `` checkbox = abap_false ) ). + + default_focus( ). + view_display( ). + focus( ). + + ENDMETHOD. + + METHOD focus. focusid = |{ focuscolumn }_{ focusrow }|. diff --git a/src/z2ui5_cl_smp_app_445.clas.abap b/src/z2ui5_cl_smp_app_445.clas.abap index 597a1dbf..1f9369ce 100644 --- a/src/z2ui5_cl_smp_app_445.clas.abap +++ b/src/z2ui5_cl_smp_app_445.clas.abap @@ -41,66 +41,6 @@ CLASS z2ui5_cl_smp_app_445 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->check_on_event( `OPEN_POPUP` ). - popup_display( ). - ENDIF. - - ENDMETHOD. - - - METHOD device_form. - - DATA(form) = parent->ele( n = `SimpleForm` ns = `form` - )->a( n = `layout` v = `ResponsiveGridLayout` - )->a( n = `editable` b = abap_false ). - - " a readable label per system type instead of the raw booleans - form->tag( `Label` - )->a( n = `text` v = `System type` ). - - form->ele( `ObjectStatus` - )->a( n = `state` v = `Information` - )->a( n = `text` v = `{= ${device>/system/phone} ? 'Phone' : (${device>/system/tablet} ? 'Tablet' : (${device>/system/desktop} ? 'Desktop' : 'Other')) }` ). - - form->tag( `Label` - )->a( n = `text` v = `Orientation` ). - - form->ele( `ObjectStatus` - )->a( n = `text` v = `{= ${device>/orientation/landscape} ? 'Landscape' : 'Portrait' }` ). - - " resize/width and resize/height are updated live by UI5 - form->tag( `Label` - )->a( n = `text` v = `Window size` ). - - form->ele( `ObjectStatus` - )->a( n = `text` v = `{device>/resize/width} x {device>/resize/height} px` ). - - form->tag( `Label` - )->a( n = `text` v = `Touch support` ). - - form->ele( `ObjectStatus` - )->a( n = `state` v = `{= ${device>/support/touch} ? 'Success' : 'None' }` - )->a( n = `text` v = `{= ${device>/support/touch} ? 'Yes' : 'No' }` ). - - form->tag( `Label` - )->a( n = `text` v = `Browser` ). - - form->tag( `Text` - )->a( n = `text` v = `{device>/browser/name} {device>/browser/version}` ). - - form->tag( `Label` - )->a( n = `text` v = `Operating system` ). - - form->tag( `Text` - )->a( n = `text` v = `{device>/os/name} {device>/os/version}` ). - - result = form. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -172,6 +112,66 @@ CLASS z2ui5_cl_smp_app_445 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + IF client->check_on_event( `OPEN_POPUP` ). + popup_display( ). + ENDIF. + + ENDMETHOD. + + + METHOD device_form. + + DATA(form) = parent->ele( n = `SimpleForm` ns = `form` + )->a( n = `layout` v = `ResponsiveGridLayout` + )->a( n = `editable` b = abap_false ). + + " a readable label per system type instead of the raw booleans + form->tag( `Label` + )->a( n = `text` v = `System type` ). + + form->ele( `ObjectStatus` + )->a( n = `state` v = `Information` + )->a( n = `text` v = `{= ${device>/system/phone} ? 'Phone' : (${device>/system/tablet} ? 'Tablet' : (${device>/system/desktop} ? 'Desktop' : 'Other')) }` ). + + form->tag( `Label` + )->a( n = `text` v = `Orientation` ). + + form->ele( `ObjectStatus` + )->a( n = `text` v = `{= ${device>/orientation/landscape} ? 'Landscape' : 'Portrait' }` ). + + " resize/width and resize/height are updated live by UI5 + form->tag( `Label` + )->a( n = `text` v = `Window size` ). + + form->ele( `ObjectStatus` + )->a( n = `text` v = `{device>/resize/width} x {device>/resize/height} px` ). + + form->tag( `Label` + )->a( n = `text` v = `Touch support` ). + + form->ele( `ObjectStatus` + )->a( n = `state` v = `{= ${device>/support/touch} ? 'Success' : 'None' }` + )->a( n = `text` v = `{= ${device>/support/touch} ? 'Yes' : 'No' }` ). + + form->tag( `Label` + )->a( n = `text` v = `Browser` ). + + form->tag( `Text` + )->a( n = `text` v = `{device>/browser/name} {device>/browser/version}` ). + + form->tag( `Label` + )->a( n = `text` v = `Operating system` ). + + form->tag( `Text` + )->a( n = `text` v = `{device>/os/name} {device>/os/version}` ). + + result = form. + + ENDMETHOD. + + METHOD popup_display. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( diff --git a/src/z2ui5_cl_smp_app_448.clas.abap b/src/z2ui5_cl_smp_app_448.clas.abap index 45b8e3d1..a7504ece 100644 --- a/src/z2ui5_cl_smp_app_448.clas.abap +++ b/src/z2ui5_cl_smp_app_448.clas.abap @@ -33,32 +33,6 @@ CLASS z2ui5_cl_smp_app_448 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - WHEN `PANEL_EXPAND`. - " the user expanded or collapsed the panel by its own header - and - " setExpanded fires this as well - so the mirror follows the panel - expanded = xsdbool( client->get_event_arg( ) = abap_true ). - WHEN `TOGGLE`. - " invert the mirrored state and call the whitelisted setExpanded on - " the panel - client-side, after the response renders, no rebuild. - " t_arg is positional: id, method, params (the view defaults to - " cs_view-main and can be omitted for a main-view control) - expanded = xsdbool( expanded = abap_false ). - " Driving a property through control_by_id IS this sample; the plain - " binding the rule recommends would be expanded = _bind( expanded ). - " abap2ui5lint-disable settable-property-via-action - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `demoPanel` ) - ( `setExpanded` ) - ( CONV string( expanded ) ) ) ). - " abap2ui5lint-enable settable-property-via-action - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -102,4 +76,30 @@ CLASS z2ui5_cl_smp_app_448 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + WHEN `PANEL_EXPAND`. + " the user expanded or collapsed the panel by its own header - and + " setExpanded fires this as well - so the mirror follows the panel + expanded = xsdbool( client->get_event_arg( ) = abap_true ). + WHEN `TOGGLE`. + " invert the mirrored state and call the whitelisted setExpanded on + " the panel - client-side, after the response renders, no rebuild. + " t_arg is positional: id, method, params (the view defaults to + " cs_view-main and can be omitted for a main-view control) + expanded = xsdbool( expanded = abap_false ). + " Driving a property through control_by_id IS this sample; the plain + " binding the rule recommends would be expanded = _bind( expanded ). + " abap2ui5lint-disable settable-property-via-action + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `demoPanel` ) + ( `setExpanded` ) + ( CONV string( expanded ) ) ) ). + " abap2ui5lint-enable settable-property-via-action + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_449.clas.abap b/src/z2ui5_cl_smp_app_449.clas.abap index c2d4bbe8..15771353 100644 --- a/src/z2ui5_cl_smp_app_449.clas.abap +++ b/src/z2ui5_cl_smp_app_449.clas.abap @@ -30,21 +30,6 @@ CLASS z2ui5_cl_smp_app_449 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `OPEN`. - " open the popup-mode PDFViewer via the whitelisted open method - - " the viewer brings its own dialog and close button. - " t_arg is positional: id, method (the view defaults to cs_view-main - " and can be omitted for a main-view control) - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `demoPdf` ) - ( `open` ) ) ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -87,4 +72,19 @@ CLASS z2ui5_cl_smp_app_449 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->get_event( ) = `OPEN`. + " open the popup-mode PDFViewer via the whitelisted open method - + " the viewer brings its own dialog and close button. + " t_arg is positional: id, method (the view defaults to cs_view-main + " and can be omitted for a main-view control) + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `demoPdf` ) + ( `open` ) ) ). + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_452.clas.abap b/src/z2ui5_cl_smp_app_452.clas.abap index 1578ef99..42199f00 100644 --- a/src/z2ui5_cl_smp_app_452.clas.abap +++ b/src/z2ui5_cl_smp_app_452.clas.abap @@ -19,9 +19,9 @@ CLASS z2ui5_cl_smp_app_452 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS popup_display. METHODS popover_display IMPORTING @@ -37,7 +37,8 @@ CLASS z2ui5_cl_smp_app_452 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -47,87 +48,6 @@ CLASS z2ui5_cl_smp_app_452 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - DATA(description) = `First Error message description. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ` && - `Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ` && - `Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ` && - `Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`. - - t_msg = VALUE #( - ( type = `Error` - title = `Account 801 requires an assignment` - subtitle = `Role is invalid` - description = description - group = `Purchase Order 450001` ) - ( type = `Warning` - title = `Account 821 requires a check` - subtitle = `Undefined task` - description = description - group = `Purchase Order 450001` ) - ( type = `Warning` - title = `Enter a text with maximum 6 characters length` - subtitle = `` - description = description - group = `Purchase Order 450002` ) - ( type = `Warning` - title = `Enter a text with maximum 8 characters length` - subtitle = `` - description = description - group = `Purchase Order 450002` ) - ( type = `Error` - title = `Account 802 requires an assignment` - subtitle = `Role is invalid` - description = description - group = `Purchase Order 450002` ) - ( type = `Information` - title = `Account 804 requires an assignment` - subtitle = `Information type subtitle` - description = description - group = `Purchase Order 450002` ) - ( type = `Error` - title = `Technical message without object relation` - subtitle = `` - description = description - group = `General` ) - ( type = `Warning` - title = `Global System will be down on Sunday` - subtitle = `` - description = description - group = `General` ) - ( type = `Error` - title = `Global System will be down on Sunday` - subtitle = `` - description = description - group = `General` ) - ( type = `Error` - title = `An Error` - subtitle = `Ungrouped message` - description = description - group = `` ) - ( type = `Warning` - title = `A Warning` - subtitle = `Ungrouped message` - description = description - group = `` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `POPUP`. - popup_display( ). - WHEN `POPOVER`. - popover_display( `messagePopoverBtn` ). - ENDCASE. - - ENDMETHOD. - - METHOD view_display. " the footer button shows the current number of error messages - counted here in the backend, no frontend formatter involved @@ -189,6 +109,18 @@ CLASS z2ui5_cl_smp_app_452 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + WHEN `POPUP`. + popup_display( ). + WHEN `POPOVER`. + popover_display( `messagePopoverBtn` ). + ENDCASE. + + ENDMETHOD. + + METHOD popup_display. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( @@ -254,4 +186,71 @@ CLASS z2ui5_cl_smp_app_452 IMPLEMENTATION. ENDMETHOD. + + METHOD model_init. + + DATA(description) = `First Error message description. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ` && + `Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ` && + `Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ` && + `Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`. + + t_msg = VALUE #( + ( type = `Error` + title = `Account 801 requires an assignment` + subtitle = `Role is invalid` + description = description + group = `Purchase Order 450001` ) + ( type = `Warning` + title = `Account 821 requires a check` + subtitle = `Undefined task` + description = description + group = `Purchase Order 450001` ) + ( type = `Warning` + title = `Enter a text with maximum 6 characters length` + subtitle = `` + description = description + group = `Purchase Order 450002` ) + ( type = `Warning` + title = `Enter a text with maximum 8 characters length` + subtitle = `` + description = description + group = `Purchase Order 450002` ) + ( type = `Error` + title = `Account 802 requires an assignment` + subtitle = `Role is invalid` + description = description + group = `Purchase Order 450002` ) + ( type = `Information` + title = `Account 804 requires an assignment` + subtitle = `Information type subtitle` + description = description + group = `Purchase Order 450002` ) + ( type = `Error` + title = `Technical message without object relation` + subtitle = `` + description = description + group = `General` ) + ( type = `Warning` + title = `Global System will be down on Sunday` + subtitle = `` + description = description + group = `General` ) + ( type = `Error` + title = `Global System will be down on Sunday` + subtitle = `` + description = description + group = `General` ) + ( type = `Error` + title = `An Error` + subtitle = `Ungrouped message` + description = description + group = `` ) + ( type = `Warning` + title = `A Warning` + subtitle = `Ungrouped message` + description = description + group = `` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_453.clas.abap b/src/z2ui5_cl_smp_app_453.clas.abap index bac798d8..e0878e79 100644 --- a/src/z2ui5_cl_smp_app_453.clas.abap +++ b/src/z2ui5_cl_smp_app_453.clas.abap @@ -64,52 +64,6 @@ CLASS z2ui5_cl_smp_app_453 IMPLEMENTATION. ENDMETHOD. - METHOD products_prepare. - - " Everything the UI shows beyond the raw values is decided HERE, in ABAP. - " The original UI5 demo kit samples do all of this in their frontend - " Formatter.js - abap2UI5 is a thin frontend, so it moves server-side and - " the view binds the finished field. Note what each of these actually is: - " a threshold, a rounding rule, a string composition and two lookups from - " a business status to a visual. None of them is a rendering detail the - " browser knows better than the backend, so none of them belongs in the - " curated formatter module (which is why the functions that used to do - " them there were removed again). - LOOP AT t_products REFERENCE INTO DATA(product). - - " classification by threshold - business logic, never a formatter - product->weight_state = COND #( WHEN product->weight < 1000 THEN `Success` - WHEN product->weight < 2000 THEN `Warning` - ELSE `Error` ). - - " a packed field renders its declared decimals, so the display string - " is simply its character form - no client-side rounding needed - product->price_disp = |{ product->price }|. - - product->dimensions = |{ product->width } x { product->depth } x | && - |{ product->height } { product->dim_unit }|. - - " which icon and which state stand for a business status is a backend - " decision - the frontend must not carry the domain's vocabulary - product->status_icon = SWITCH #( product->status - WHEN `Available` THEN `sap-icon://accept` - WHEN `Out of Stock` THEN `sap-icon://alert` - WHEN `Discontinued` THEN `sap-icon://decline` ). - product->status_state = SWITCH #( product->status - WHEN `Available` THEN `Success` - WHEN `Out of Stock` THEN `Warning` - WHEN `Discontinued` THEN `Error` - ELSE `None` ). - - product->delivery_state = SWITCH #( product->delivery - WHEN `Shipped` THEN `Success` - WHEN `Failed Shipping` THEN `Error` - ELSE `None` ). - ENDLOOP. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -193,4 +147,50 @@ CLASS z2ui5_cl_smp_app_453 IMPLEMENTATION. ENDMETHOD. + + METHOD products_prepare. + + " Everything the UI shows beyond the raw values is decided HERE, in ABAP. + " The original UI5 demo kit samples do all of this in their frontend + " Formatter.js - abap2UI5 is a thin frontend, so it moves server-side and + " the view binds the finished field. Note what each of these actually is: + " a threshold, a rounding rule, a string composition and two lookups from + " a business status to a visual. None of them is a rendering detail the + " browser knows better than the backend, so none of them belongs in the + " curated formatter module (which is why the functions that used to do + " them there were removed again). + LOOP AT t_products REFERENCE INTO DATA(product). + + " classification by threshold - business logic, never a formatter + product->weight_state = COND #( WHEN product->weight < 1000 THEN `Success` + WHEN product->weight < 2000 THEN `Warning` + ELSE `Error` ). + + " a packed field renders its declared decimals, so the display string + " is simply its character form - no client-side rounding needed + product->price_disp = |{ product->price }|. + + product->dimensions = |{ product->width } x { product->depth } x | && + |{ product->height } { product->dim_unit }|. + + " which icon and which state stand for a business status is a backend + " decision - the frontend must not carry the domain's vocabulary + product->status_icon = SWITCH #( product->status + WHEN `Available` THEN `sap-icon://accept` + WHEN `Out of Stock` THEN `sap-icon://alert` + WHEN `Discontinued` THEN `sap-icon://decline` ). + product->status_state = SWITCH #( product->status + WHEN `Available` THEN `Success` + WHEN `Out of Stock` THEN `Warning` + WHEN `Discontinued` THEN `Error` + ELSE `None` ). + + product->delivery_state = SWITCH #( product->delivery + WHEN `Shipped` THEN `Success` + WHEN `Failed Shipping` THEN `Error` + ELSE `None` ). + ENDLOOP. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_454.clas.abap b/src/z2ui5_cl_smp_app_454.clas.abap index 504c74ef..6fed7269 100644 --- a/src/z2ui5_cl_smp_app_454.clas.abap +++ b/src/z2ui5_cl_smp_app_454.clas.abap @@ -46,39 +46,6 @@ CLASS z2ui5_cl_smp_app_454 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `SEARCH`. - " apply a declarative filter to the list's items binding - - " client-side after the response renders. The model data stays - " untouched (no table copy, no model change); an empty query - " clears the filter again. - " t_arg is positional: id, aggregation, method, params - client->follow_up_action( val = z2ui5_if_client=>cs_event-binding_call - t_arg = VALUE #( ( `productList` ) - ( `items` ) - ( `filter` ) - ( `NAME` ) - ( `Contains` ) - ( client->get_event_arg( ) ) ) ). - - WHEN `SORT_ASC` OR `SORT_DESC`. - client->follow_up_action( val = z2ui5_if_client=>cs_event-binding_call - t_arg = VALUE #( ( `productList` ) - ( `items` ) - ( `sort` ) - ( `NAME` ) - ( COND #( WHEN client->get_event( ) = `SORT_DESC` - THEN `true` - ELSE `false` ) ) ) ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -133,4 +100,37 @@ CLASS z2ui5_cl_smp_app_454 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `SEARCH`. + " apply a declarative filter to the list's items binding - + " client-side after the response renders. The model data stays + " untouched (no table copy, no model change); an empty query + " clears the filter again. + " t_arg is positional: id, aggregation, method, params + client->follow_up_action( val = z2ui5_if_client=>cs_event-binding_call + t_arg = VALUE #( ( `productList` ) + ( `items` ) + ( `filter` ) + ( `NAME` ) + ( `Contains` ) + ( client->get_event_arg( ) ) ) ). + + WHEN `SORT_ASC` OR `SORT_DESC`. + client->follow_up_action( val = z2ui5_if_client=>cs_event-binding_call + t_arg = VALUE #( ( `productList` ) + ( `items` ) + ( `sort` ) + ( `NAME` ) + ( COND #( WHEN client->get_event( ) = `SORT_DESC` + THEN `true` + ELSE `false` ) ) ) ). + + ENDCASE. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_459.clas.abap b/src/z2ui5_cl_smp_app_459.clas.abap index c7ad4c52..8ddcf796 100644 --- a/src/z2ui5_cl_smp_app_459.clas.abap +++ b/src/z2ui5_cl_smp_app_459.clas.abap @@ -46,40 +46,6 @@ CLASS z2ui5_cl_smp_app_459 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `REORDER`. - " the three event args arrive resolved client-side from the drop - " event: dragged row index, drop target index (both 0-based) and - " the drop position (Before/After) - TRY. - DATA(lv_from) = CONV i( client->get_event_arg( ) ) + 1. - DATA(lv_to) = CONV i( client->get_event_arg( 2 ) ) + 1. - DATA(lv_pos) = client->get_event_arg( 3 ). - DATA(ls_row) = t_products[ lv_from ]. - CATCH cx_root. - RETURN. - ENDTRY. - " dropping a row onto itself is a no-op, and a target outside the - " table is refused here - after the DELETE an INSERT out of range - " would lose the dragged row - IF lv_from = lv_to OR lv_to < 1 OR lv_to > lines( t_products ). - RETURN. - ENDIF. - DELETE t_products INDEX lv_from. - IF lv_from < lv_to. - lv_to = lv_to - 1. - ENDIF. - IF lv_pos = `Before`. - INSERT ls_row INTO t_products INDEX lv_to. - ELSE. - INSERT ls_row INTO t_products INDEX lv_to + 1. - ENDIF. - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -144,4 +110,38 @@ CLASS z2ui5_cl_smp_app_459 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->get_event( ) = `REORDER`. + " the three event args arrive resolved client-side from the drop + " event: dragged row index, drop target index (both 0-based) and + " the drop position (Before/After) + TRY. + DATA(lv_from) = CONV i( client->get_event_arg( ) ) + 1. + DATA(lv_to) = CONV i( client->get_event_arg( 2 ) ) + 1. + DATA(lv_pos) = client->get_event_arg( 3 ). + DATA(ls_row) = t_products[ lv_from ]. + CATCH cx_root. + RETURN. + ENDTRY. + " dropping a row onto itself is a no-op, and a target outside the + " table is refused here - after the DELETE an INSERT out of range + " would lose the dragged row + IF lv_from = lv_to OR lv_to < 1 OR lv_to > lines( t_products ). + RETURN. + ENDIF. + DELETE t_products INDEX lv_from. + IF lv_from < lv_to. + lv_to = lv_to - 1. + ENDIF. + IF lv_pos = `Before`. + INSERT ls_row INTO t_products INDEX lv_to. + ELSE. + INSERT ls_row INTO t_products INDEX lv_to + 1. + ENDIF. + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_461.clas.abap b/src/z2ui5_cl_smp_app_461.clas.abap index 972bfae5..76e0c534 100644 --- a/src/z2ui5_cl_smp_app_461.clas.abap +++ b/src/z2ui5_cl_smp_app_461.clas.abap @@ -51,58 +51,6 @@ CLASS z2ui5_cl_smp_app_461 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `MOVE_NODE`. - " both event args arrive resolved client-side: the binding context - " paths of the dragged and the drop target item, e.g. - " /T_NODES/0/NODES/1 (a file) and /T_NODES/2 (a folder) - so parse - " from the END of the path - SPLIT client->get_event_arg( ) AT `/` INTO TABLE DATA(lt_drag). - SPLIT client->get_event_arg( 2 ) AT `/` INTO TABLE DATA(lt_drop). - DATA(lv_drag_lines) = lines( lt_drag ). - DATA(lv_drop_lines) = lines( lt_drop ). - IF lv_drag_lines < 4 OR lv_drop_lines < 2 - OR VALUE #( lt_drag[ lv_drag_lines - 1 ] OPTIONAL ) <> `NODES` - OR VALUE #( lt_drag[ lv_drag_lines - 3 ] OPTIONAL ) <> `T_NODES` - OR VALUE #( lt_drop[ lv_drop_lines - 1 ] OPTIONAL ) <> `T_NODES`. - client->message_toast_display( `drop a file onto a folder` ). - RETURN. - ENDIF. - TRY. - DATA(lv_from_root) = CONV i( lt_drag[ lv_drag_lines - 2 ] ) + 1. - DATA(lv_from_child) = CONV i( lt_drag[ lv_drag_lines ] ) + 1. - DATA(lv_to_root) = CONV i( lt_drop[ lv_drop_lines ] ) + 1. - DATA(ls_child) = t_nodes[ lv_from_root ]-nodes[ lv_from_child ]. - CATCH cx_root. - RETURN. - ENDTRY. - " dropping a file onto its own parent folder is a no-op - IF lv_from_root = lv_to_root. - RETURN. - ENDIF. - " IS ASSIGNED, not sy-subrc: a SUCCESSFUL dynamic ASSIGN does not reset - " sy-subrc on every release (abap2UI5 #1937) - ASSIGN t_nodes[ lv_from_root ] TO FIELD-SYMBOL(). - IF IS NOT ASSIGNED. - RETURN. - ENDIF. - ASSIGN t_nodes[ lv_to_root ] TO FIELD-SYMBOL(). - IF IS NOT ASSIGNED. - RETURN. - ENDIF. - DELETE -nodes INDEX lv_from_child. - APPEND ls_child TO -nodes. - " full view rebuild instead of relying on the automatic model push: - " the z2ui5.cc.Tree companion re-applies the expand state (snapshotted - " before this roundtrip) only when it renders - a pure model refresh - " would leave the rebuilt tree binding collapsed - view_display( ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -154,4 +102,56 @@ CLASS z2ui5_cl_smp_app_461 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD on_event. + + IF client->get_event( ) = `MOVE_NODE`. + " both event args arrive resolved client-side: the binding context + " paths of the dragged and the drop target item, e.g. + " /T_NODES/0/NODES/1 (a file) and /T_NODES/2 (a folder) - so parse + " from the END of the path + SPLIT client->get_event_arg( ) AT `/` INTO TABLE DATA(lt_drag). + SPLIT client->get_event_arg( 2 ) AT `/` INTO TABLE DATA(lt_drop). + DATA(lv_drag_lines) = lines( lt_drag ). + DATA(lv_drop_lines) = lines( lt_drop ). + IF lv_drag_lines < 4 OR lv_drop_lines < 2 + OR VALUE #( lt_drag[ lv_drag_lines - 1 ] OPTIONAL ) <> `NODES` + OR VALUE #( lt_drag[ lv_drag_lines - 3 ] OPTIONAL ) <> `T_NODES` + OR VALUE #( lt_drop[ lv_drop_lines - 1 ] OPTIONAL ) <> `T_NODES`. + client->message_toast_display( `drop a file onto a folder` ). + RETURN. + ENDIF. + TRY. + DATA(lv_from_root) = CONV i( lt_drag[ lv_drag_lines - 2 ] ) + 1. + DATA(lv_from_child) = CONV i( lt_drag[ lv_drag_lines ] ) + 1. + DATA(lv_to_root) = CONV i( lt_drop[ lv_drop_lines ] ) + 1. + DATA(ls_child) = t_nodes[ lv_from_root ]-nodes[ lv_from_child ]. + CATCH cx_root. + RETURN. + ENDTRY. + " dropping a file onto its own parent folder is a no-op + IF lv_from_root = lv_to_root. + RETURN. + ENDIF. + " IS ASSIGNED, not sy-subrc: a SUCCESSFUL dynamic ASSIGN does not reset + " sy-subrc on every release (abap2UI5 #1937) + ASSIGN t_nodes[ lv_from_root ] TO FIELD-SYMBOL(). + IF IS NOT ASSIGNED. + RETURN. + ENDIF. + ASSIGN t_nodes[ lv_to_root ] TO FIELD-SYMBOL(). + IF IS NOT ASSIGNED. + RETURN. + ENDIF. + DELETE -nodes INDEX lv_from_child. + APPEND ls_child TO -nodes. + " full view rebuild instead of relying on the automatic model push: + " the z2ui5.cc.Tree companion re-applies the expand state (snapshotted + " before this roundtrip) only when it renders - a pure model refresh + " would leave the rebuilt tree binding collapsed + view_display( ). + ENDIF. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_462.clas.abap b/src/z2ui5_cl_smp_app_462.clas.abap index be1741b4..195e3244 100644 --- a/src/z2ui5_cl_smp_app_462.clas.abap +++ b/src/z2ui5_cl_smp_app_462.clas.abap @@ -60,6 +60,41 @@ CLASS z2ui5_cl_smp_app_462 IMPLEMENTATION. ENDMETHOD. + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Tree - Inside a Dialog` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `The button opens a Dialog whose content is a sap.m.Tree over a nested ABAP ` && + `table. Expand some nodes, close and reopen: the z2ui5.cc.Tree companion ` && + `preserves the expand state across the roundtrips.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + page->ele( `VBox` + )->a( n = `class` v = `sapUiSmallMargin` + )->tag( `Button` + )->a( n = `press` v = client->_event( `OPEN_POPUP` ) + )->a( n = `text` v = `Open tree popup` + )->a( n = `icon` v = `sap-icon://tree` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. CASE client->get_event( ). @@ -111,39 +146,4 @@ CLASS z2ui5_cl_smp_app_462 IMPLEMENTATION. client->popup_display( popup->stringify( ) ). ENDMETHOD. - - - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Tree - Inside a Dialog` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `The button opens a Dialog whose content is a sap.m.Tree over a nested ABAP ` && - `table. Expand some nodes, close and reopen: the z2ui5.cc.Tree companion ` && - `preserves the expand state across the roundtrips.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - page->ele( `VBox` - )->a( n = `class` v = `sapUiSmallMargin` - )->tag( `Button` - )->a( n = `press` v = client->_event( `OPEN_POPUP` ) - )->a( n = `text` v = `Open tree popup` - )->a( n = `icon` v = `sap-icon://tree` ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_463.clas.abap b/src/z2ui5_cl_smp_app_463.clas.abap index 9bc2fe50..b2d59963 100644 --- a/src/z2ui5_cl_smp_app_463.clas.abap +++ b/src/z2ui5_cl_smp_app_463.clas.abap @@ -58,22 +58,6 @@ CLASS z2ui5_cl_smp_app_463 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `SHOW_MODEL`. - " the bound inputs have already written the edits back into - " t_nodes before on_event runs - read the (possibly renamed) roots - " back and echo them, proving the round-trip - DATA(lv_roots) = ``. - LOOP AT t_nodes INTO DATA(ls_node). - lv_roots = |{ lv_roots }{ COND #( WHEN sy-tabix > 1 THEN `, ` ) }{ ls_node-text }|. - ENDLOOP. - client->message_toast_display( |Root nodes now: { lv_roots }| ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -125,4 +109,20 @@ CLASS z2ui5_cl_smp_app_463 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->get_event( ) = `SHOW_MODEL`. + " the bound inputs have already written the edits back into + " t_nodes before on_event runs - read the (possibly renamed) roots + " back and echo them, proving the round-trip + DATA(lv_roots) = ``. + LOOP AT t_nodes INTO DATA(ls_node). + lv_roots = |{ lv_roots }{ COND #( WHEN sy-tabix > 1 THEN `, ` ) }{ ls_node-text }|. + ENDLOOP. + client->message_toast_display( |Root nodes now: { lv_roots }| ). + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_464.clas.abap b/src/z2ui5_cl_smp_app_464.clas.abap index 094c475b..1d7ee801 100644 --- a/src/z2ui5_cl_smp_app_464.clas.abap +++ b/src/z2ui5_cl_smp_app_464.clas.abap @@ -30,23 +30,6 @@ CLASS z2ui5_cl_smp_app_464 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `RAISE_EXCEPTION`. - " the division dumps - nothing ever reads the result, and that is - " the point of the sample - DATA(lv_zero) = 0. - DATA(lv_result) = 1 / lv_zero ##NEEDED. - WHEN `ASSERT`. - ASSERT 1 = 0. - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -88,4 +71,21 @@ CLASS z2ui5_cl_smp_app_464 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `RAISE_EXCEPTION`. + " the division dumps - nothing ever reads the result, and that is + " the point of the sample + DATA(lv_zero) = 0. + DATA(lv_result) = 1 / lv_zero ##NEEDED. + WHEN `ASSERT`. + ASSERT 1 = 0. + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_465.clas.abap b/src/z2ui5_cl_smp_app_465.clas.abap index 112c973a..840c4110 100644 --- a/src/z2ui5_cl_smp_app_465.clas.abap +++ b/src/z2ui5_cl_smp_app_465.clas.abap @@ -30,23 +30,6 @@ CLASS z2ui5_cl_smp_app_465 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `TOGGLE`. - " toggle the popover open/closed, anchored to the pressed button's DOM - " ref - the whitelisted toggleBy opens it if closed, closes it if open - " (the controller pattern oPopover.openBy(oButton) / oPopover.close()). - " t_arg is positional: id, method, anchor id (the view defaults to - " cs_view-main and can be omitted for a main-view control) - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `demoPopover` ) - ( `toggleBy` ) - ( client->get_event_arg( ) ) ) ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -95,4 +78,21 @@ CLASS z2ui5_cl_smp_app_465 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->get_event( ) = `TOGGLE`. + " toggle the popover open/closed, anchored to the pressed button's DOM + " ref - the whitelisted toggleBy opens it if closed, closes it if open + " (the controller pattern oPopover.openBy(oButton) / oPopover.close()). + " t_arg is positional: id, method, anchor id (the view defaults to + " cs_view-main and can be omitted for a main-view control) + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `demoPopover` ) + ( `toggleBy` ) + ( client->get_event_arg( ) ) ) ). + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_468.clas.abap b/src/z2ui5_cl_smp_app_468.clas.abap index 0bbea830..771241ea 100644 --- a/src/z2ui5_cl_smp_app_468.clas.abap +++ b/src/z2ui5_cl_smp_app_468.clas.abap @@ -22,13 +22,13 @@ CLASS z2ui5_cl_smp_app_468 DEFINITION PUBLIC. DATA input TYPE string. DATA routing TYPE abap_bool. + DATA counter TYPE i. PROTECTED SECTION. - DATA counter TYPE i. - DATA client TYPE REF TO z2ui5_if_client. + DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -50,34 +50,6 @@ CLASS z2ui5_cl_smp_app_468 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `INC`. - counter = counter + 1. - view_display( ). - - WHEN `GO_DETAIL`. - client->nav_app_call( NEW z2ui5_cl_smp_app_469( ) ). - - WHEN `ROUTING`. - " the mode is remembered on the app, so switching it is one action: - " DEFAULT leaves the hash alone from now on - Back/Forward leave the - " page, the framework default - and FRESH puts the class back in - client->follow_up_action( val = client->cs_event-hash_routing - t_arg = VALUE #( ( COND #( WHEN routing = abap_true - THEN client->cs_nav_mode-fresh - ELSE client->cs_nav_mode-default ) ) ) ). - client->message_toast_display( COND #( WHEN routing = abap_true - THEN `routing mode fresh - the URL carries the class` - ELSE `routing mode default - the URL is left untouched` ) ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. " configure the routing mode once - the framework remembers it on the app @@ -126,7 +98,7 @@ CLASS z2ui5_cl_smp_app_468 IMPLEMENTATION. )->a( n = `text` v = `and raise a counter` ). form->tag( `Button` )->a( n = `press` v = client->_event( `INC` ) - )->a( n = `text` t = |increment ({ counter })| ). + )->a( n = `text` v = |increment ({ client->_bind( counter ) })| ). form->tag( `Label` )->a( n = `text` v = `2. Navigate forward` ). @@ -154,4 +126,31 @@ CLASS z2ui5_cl_smp_app_468 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `INC`. + counter = counter + 1. + + WHEN `GO_DETAIL`. + client->nav_app_call( NEW z2ui5_cl_smp_app_469( ) ). + + WHEN `ROUTING`. + " the mode is remembered on the app, so switching it is one action: + " DEFAULT leaves the hash alone from now on - Back/Forward leave the + " page, the framework default - and FRESH puts the class back in + client->follow_up_action( val = client->cs_event-hash_routing + t_arg = VALUE #( ( COND #( WHEN routing = abap_true + THEN client->cs_nav_mode-fresh + ELSE client->cs_nav_mode-default ) ) ) ). + client->message_toast_display( COND #( WHEN routing = abap_true + THEN `routing mode fresh - the URL carries the class` + ELSE `routing mode default - the URL is left untouched` ) ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_470.clas.abap b/src/z2ui5_cl_smp_app_470.clas.abap index 84a46d6b..d5dbe182 100644 --- a/src/z2ui5_cl_smp_app_470.clas.abap +++ b/src/z2ui5_cl_smp_app_470.clas.abap @@ -32,8 +32,8 @@ CLASS z2ui5_cl_smp_app_470 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS popup_components IMPORTING index TYPE string. @@ -72,15 +72,6 @@ CLASS z2ui5_cl_smp_app_470 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `SHOW`. - popup_components( client->get_event_arg( ) ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -144,6 +135,15 @@ CLASS z2ui5_cl_smp_app_470 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + IF client->get_event( ) = `SHOW`. + popup_components( client->get_event_arg( ) ). + ENDIF. + + ENDMETHOD. + + METHOD popup_components. DATA(popup) = z2ui5_cl_ui5_view_builder=>factory( diff --git a/src/z2ui5_cl_smp_app_471.clas.abap b/src/z2ui5_cl_smp_app_471.clas.abap index eccef211..19ab4f3a 100644 --- a/src/z2ui5_cl_smp_app_471.clas.abap +++ b/src/z2ui5_cl_smp_app_471.clas.abap @@ -10,15 +10,16 @@ CLASS z2ui5_cl_smp_app_471 DEFINITION PUBLIC. BEGIN OF ty_s_log, entry TYPE string, END OF ty_s_log. - DATA t_log TYPE STANDARD TABLE OF ty_s_log WITH EMPTY KEY. + DATA t_log TYPE STANDARD TABLE OF ty_s_log WITH EMPTY KEY. + DATA toggle_text TYPE string. PROTECTED SECTION. DATA registered TYPE abap_bool. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS shortcuts_set IMPORTING event_save TYPE string @@ -34,7 +35,8 @@ CLASS z2ui5_cl_smp_app_471 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -44,11 +46,58 @@ CLASS z2ui5_cl_smp_app_471 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. + METHOD view_display. - registered = abap_true. - shortcuts_set( event_save = `SAVE` event_delete = `DELETE` ). - view_display( ). + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Event - Keyboard Shortcuts, Ctrl+S` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Ctrl+S and Ctrl+D fire the backend events SAVE and DELETE - the same events the ` && + `buttons below send, but from the keyboard and without a control. The binding is ` && + `pure data (cs_event-keyboard_shortcut with the combination and the event name), ` && + `the browser default for the combination is suppressed.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + page->ele( `HBox` + )->a( n = `class` v = `sapUiSmallMargin` + )->tag( `Button` + )->a( n = `press` v = client->_event( `TOGGLE_REGISTRATION` ) + )->a( n = `tooltip` v = `Register or unregister the keyboard shortcuts` + )->a( n = `text` v = client->_bind( toggle_text ) + )->a( n = `icon` v = `sap-icon://keyboard-and-mouse` + )->tag( `Button` + )->a( n = `press` v = client->_event( `SAVE` ) + )->a( n = `text` v = `Save (Ctrl+S)` + )->a( n = `type` v = `Emphasized` + )->a( n = `class` v = `sapUiTinyMarginBegin` + )->tag( `Button` + )->a( n = `press` v = client->_event( `DELETE` ) + )->a( n = `text` v = `Delete (Ctrl+D)` + )->a( n = `class` v = `sapUiTinyMarginBegin` + )->tag( `Button` + )->a( n = `press` v = client->_event( `CLEAR` ) + )->a( n = `text` v = `Clear log` + )->a( n = `class` v = `sapUiTinyMarginBegin` ). + + page->ele( `List` + )->a( n = `headerText` v = `Triggered events` + )->a( n = `items` v = client->_bind( t_log ) + )->tag( `StandardListItem` + )->a( n = `title` v = `{ENTRY}` ). + + client->view_display( view->stringify( ) ). ENDMETHOD. @@ -70,11 +119,12 @@ CLASS z2ui5_cl_smp_app_471 IMPLEMENTATION. IF registered = abap_true. shortcuts_set( event_save = `SAVE` event_delete = `DELETE` ). + toggle_text = `Unregister the shortcuts`. ELSE. " an empty event name removes the binding again shortcuts_set( event_save = `` event_delete = `` ). + toggle_text = `Register the shortcuts`. ENDIF. - view_display( ). WHEN `CLEAR`. t_log = VALUE #( ). @@ -102,60 +152,11 @@ CLASS z2ui5_cl_smp_app_471 IMPLEMENTATION. ENDMETHOD. - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Event - Keyboard Shortcuts, Ctrl+S` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Ctrl+S and Ctrl+D fire the backend events SAVE and DELETE - the same events the ` && - `buttons below send, but from the keyboard and without a control. The binding is ` && - `pure data (cs_event-keyboard_shortcut with the combination and the event name), ` && - `the browser default for the combination is suppressed.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - page->ele( `HBox` - )->a( n = `class` v = `sapUiSmallMargin` - )->tag( `Button` - )->a( n = `press` v = client->_event( `TOGGLE_REGISTRATION` ) - )->a( n = `tooltip` v = `Register or unregister the keyboard shortcuts` - )->a( n = `text` t = COND #( WHEN registered = abap_true - THEN `Unregister the shortcuts` - ELSE `Register the shortcuts` ) - )->a( n = `icon` v = `sap-icon://keyboard-and-mouse` - )->tag( `Button` - )->a( n = `press` v = client->_event( `SAVE` ) - )->a( n = `text` v = `Save (Ctrl+S)` - )->a( n = `type` v = `Emphasized` - )->a( n = `class` v = `sapUiTinyMarginBegin` - )->tag( `Button` - )->a( n = `press` v = client->_event( `DELETE` ) - )->a( n = `text` v = `Delete (Ctrl+D)` - )->a( n = `class` v = `sapUiTinyMarginBegin` - )->tag( `Button` - )->a( n = `press` v = client->_event( `CLEAR` ) - )->a( n = `text` v = `Clear log` - )->a( n = `class` v = `sapUiTinyMarginBegin` ). - - page->ele( `List` - )->a( n = `headerText` v = `Triggered events` - )->a( n = `items` v = client->_bind( t_log ) - )->tag( `StandardListItem` - )->a( n = `title` v = `{ENTRY}` ). + METHOD model_init. - client->view_display( view->stringify( ) ). + registered = abap_true. + toggle_text = `Unregister the shortcuts`. + shortcuts_set( event_save = `SAVE` event_delete = `DELETE` ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_472.clas.abap b/src/z2ui5_cl_smp_app_472.clas.abap index de0af55c..48e65eaf 100644 --- a/src/z2ui5_cl_smp_app_472.clas.abap +++ b/src/z2ui5_cl_smp_app_472.clas.abap @@ -12,8 +12,8 @@ CLASS z2ui5_cl_smp_app_472 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -36,28 +36,6 @@ CLASS z2ui5_cl_smp_app_472 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `LINK_PRESS`. - - IF block_navigation = abap_true. - last_press = `Link pressed - the browser did NOT follow the href, the backend decides what happens.`. - ELSE. - last_press = `Link pressed - the href was followed by the browser as usual.`. - ENDIF. - - WHEN `TOGGLE`. - " the flag is part of the event registration, so the view has to be - " rebuilt for the change to reach the frontend - view_display( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -116,4 +94,26 @@ CLASS z2ui5_cl_smp_app_472 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `LINK_PRESS`. + + IF block_navigation = abap_true. + last_press = `Link pressed - the browser did NOT follow the href, the backend decides what happens.`. + ELSE. + last_press = `Link pressed - the href was followed by the browser as usual.`. + ENDIF. + + WHEN `TOGGLE`. + " the flag is part of the event registration, so the view has to be + " rebuilt for the change to reach the frontend + view_display( ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_474.clas.abap b/src/z2ui5_cl_smp_app_474.clas.abap index 55265216..b124cff5 100644 --- a/src/z2ui5_cl_smp_app_474.clas.abap +++ b/src/z2ui5_cl_smp_app_474.clas.abap @@ -9,11 +9,11 @@ CLASS z2ui5_cl_smp_app_474 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. + METHODS view_display. METHODS popover_open IMPORTING policy TYPE string. - METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -33,53 +33,6 @@ CLASS z2ui5_cl_smp_app_474 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `OPEN_RELATIVE_ONLY`. - popover_open( `RELATIVE_ONLY` ). - - WHEN `OPEN_ALLOW_ALL`. - popover_open( `ALLOW_ALL` ). - - WHEN `OPEN_DENY_ALL`. - popover_open( `DENY_ALL` ). - - ENDCASE. - - ENDMETHOD. - - - METHOD popover_open. - - " setAsyncURLHandler takes a JS callback in a UI5 controller, which no - " backend payload can carry - the frontend therefore takes the NAME of a - " built-in policy and installs the matching validator itself: - " RELATIVE_ONLY (only in-app links stay clickable), ALLOW_ALL, DENY_ALL - " - " The handler is live control state a rebuild destroys, and this method is - " not on the display path - control-state-lost-on-rebuild is right about - " both. It is still not a defect HERE: every open goes through this method, - " so the validator is re-installed immediately before each openBy( ) below, - " and there is no window in which the popover is visible without it. That - " is the one thing the rule cannot see, so it is said here instead. - " abap2ui5lint-disable control-state-lost-on-rebuild -- re-issued before every openBy - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `msgPopover` ) - ( `setAsyncURLHandler` ) - ( policy ) ) ). - " abap2ui5lint-enable control-state-lost-on-rebuild - - " ... and only then open it, anchored to the button that fired the event - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `msgPopover` ) - ( `openBy` ) - ( client->get_event_arg( ) ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -146,4 +99,51 @@ CLASS z2ui5_cl_smp_app_474 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `OPEN_RELATIVE_ONLY`. + popover_open( `RELATIVE_ONLY` ). + + WHEN `OPEN_ALLOW_ALL`. + popover_open( `ALLOW_ALL` ). + + WHEN `OPEN_DENY_ALL`. + popover_open( `DENY_ALL` ). + + ENDCASE. + + ENDMETHOD. + + + METHOD popover_open. + + " setAsyncURLHandler takes a JS callback in a UI5 controller, which no + " backend payload can carry - the frontend therefore takes the NAME of a + " built-in policy and installs the matching validator itself: + " RELATIVE_ONLY (only in-app links stay clickable), ALLOW_ALL, DENY_ALL + " + " The handler is live control state a rebuild destroys, and this method is + " not on the display path - control-state-lost-on-rebuild is right about + " both. It is still not a defect HERE: every open goes through this method, + " so the validator is re-installed immediately before each openBy( ) below, + " and there is no window in which the popover is visible without it. That + " is the one thing the rule cannot see, so it is said here instead. + " abap2ui5lint-disable control-state-lost-on-rebuild -- re-issued before every openBy + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `msgPopover` ) + ( `setAsyncURLHandler` ) + ( policy ) ) ). + " abap2ui5lint-enable control-state-lost-on-rebuild + + " ... and only then open it, anchored to the button that fired the event + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `msgPopover` ) + ( `openBy` ) + ( client->get_event_arg( ) ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_480.clas.abap b/src/z2ui5_cl_smp_app_480.clas.abap index 55c05056..ffc234d0 100644 --- a/src/z2ui5_cl_smp_app_480.clas.abap +++ b/src/z2ui5_cl_smp_app_480.clas.abap @@ -16,14 +16,14 @@ CLASS z2ui5_cl_smp_app_480 DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES z2ui5_if_app. - DATA input TYPE string. + DATA input TYPE string. + DATA counter TYPE i. PROTECTED SECTION. - DATA counter TYPE i. - DATA client TYPE REF TO z2ui5_if_client. + DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -45,22 +45,6 @@ CLASS z2ui5_cl_smp_app_480 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `INC`. - counter = counter + 1. - view_display( ). - - WHEN `GO_DETAIL`. - client->nav_app_call( NEW z2ui5_cl_smp_app_469( ) ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. " configure the routing mode once - the framework remembers it on the app @@ -108,7 +92,7 @@ CLASS z2ui5_cl_smp_app_480 IMPLEMENTATION. )->a( n = `text` v = `and raise a counter` ). form->tag( `Button` )->a( n = `press` v = client->_event( `INC` ) - )->a( n = `text` t = |increment ({ counter })| ). + )->a( n = `text` v = |increment ({ client->_bind( counter ) })| ). form->tag( `Label` )->a( n = `text` v = `2. Navigate forward` ). @@ -128,4 +112,19 @@ CLASS z2ui5_cl_smp_app_480 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `INC`. + counter = counter + 1. + + WHEN `GO_DETAIL`. + client->nav_app_call( NEW z2ui5_cl_smp_app_469( ) ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_488.clas.abap b/src/z2ui5_cl_smp_app_488.clas.abap index 002fc091..4d9a3b58 100644 --- a/src/z2ui5_cl_smp_app_488.clas.abap +++ b/src/z2ui5_cl_smp_app_488.clas.abap @@ -44,39 +44,6 @@ CLASS z2ui5_cl_smp_app_488 IMPLEMENTATION. ENDMETHOD. - METHOD on_navigation. - - DATA(ls_get) = client->get( ). - returned_event = ls_get-event. - - CASE returned_event. - - WHEN `DATA_CONFIRMED`. - - " the payload handed over by nav_app_leave( r_data = ... ) arrives as a - " generic data reference - the receiver decides the type - ASSIGN ls_get-r_event_data->* TO FIELD-SYMBOL(). - - IF IS ASSIGNED. - - s_result = . - client->message_toast_display( |Returned event { returned_event }, | && - |product { s_result-product }, quantity { s_result-quantity }| ). - - ENDIF. - - WHEN `DATA_CANCELLED`. - - s_result = VALUE #( ). - client->message_toast_display( `Returned event DATA_CANCELLED, no data passed` ). - - ENDCASE. - - view_display( ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -138,4 +105,39 @@ CLASS z2ui5_cl_smp_app_488 IMPLEMENTATION. ENDMETHOD. + + METHOD on_navigation. + + DATA(ls_get) = client->get( ). + returned_event = ls_get-event. + + CASE returned_event. + + WHEN `DATA_CONFIRMED`. + + " the payload handed over by nav_app_leave( r_data = ... ) arrives as a + " generic data reference - the receiver decides the type + ASSIGN ls_get-r_event_data->* TO FIELD-SYMBOL(). + + IF IS ASSIGNED. + + s_result = . + client->message_toast_display( |Returned event { returned_event }, | && + |product { s_result-product }, quantity { s_result-quantity }| ). + + ENDIF. + + WHEN `DATA_CANCELLED`. + + s_result = VALUE #( ). + client->message_toast_display( `Returned event DATA_CANCELLED, no data passed` ). + + ENDCASE. + + " not an event path: back from the called app the view slot is this + " app's again and has to be filled + view_display( ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_495.clas.abap b/src/z2ui5_cl_smp_app_495.clas.abap index 8c37f8e9..09845fa0 100644 --- a/src/z2ui5_cl_smp_app_495.clas.abap +++ b/src/z2ui5_cl_smp_app_495.clas.abap @@ -53,13 +53,6 @@ CLASS z2ui5_cl_smp_app_495 IMPLEMENTATION. ENDMETHOD. - METHOD log_step. - - INSERT VALUE #( no = |{ lines( t_log ) + 1 }| check = val ) INTO TABLE t_log. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -106,4 +99,11 @@ CLASS z2ui5_cl_smp_app_495 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD log_step. + + INSERT VALUE #( no = |{ lines( t_log ) + 1 }| check = val ) INTO TABLE t_log. + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_496.clas.abap b/src/z2ui5_cl_smp_app_496.clas.abap index 20cbe1bc..32498f5d 100644 --- a/src/z2ui5_cl_smp_app_496.clas.abap +++ b/src/z2ui5_cl_smp_app_496.clas.abap @@ -69,29 +69,6 @@ CLASS z2ui5_cl_smp_app_496 IMPLEMENTATION. ENDMETHOD. - METHOD tabs_init. - - t_tab = VALUE #( - ( name = `Error` - descr = `The last uncaught exception with its call stack - the same one the error popup shows.` ) - ( name = `Log` - descr = `What the frontend did since the app started: roundtrips, frontend actions, events.` ) - ( name = `Previous Request` - descr = `The JSON this browser sent last - your event, the changed model, the app state.` ) - ( name = `Response` - descr = `The JSON the backend sent back - the new view, the new model, the follow-up actions.` ) - ( name = `Source Code` - descr = `The ABAP class behind the running app, with an ADT jump link in the dialog footer.` ) - ( name = `View` - descr = `The XML view your ABAP built - what z2ui5_cl_ui5_view_builder stringified into the response.` ) - ( name = `View Model` - descr = `The model behind that view: every bound attribute of this class with its live value.` ) - ( name = `Popup, Popover, Nest1, Nest2` - descr = `The same two tabs - view and model - for each of the other view slots of the app.` ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -153,4 +130,27 @@ CLASS z2ui5_cl_smp_app_496 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. + + + METHOD tabs_init. + + t_tab = VALUE #( + ( name = `Error` + descr = `The last uncaught exception with its call stack - the same one the error popup shows.` ) + ( name = `Log` + descr = `What the frontend did since the app started: roundtrips, frontend actions, events.` ) + ( name = `Previous Request` + descr = `The JSON this browser sent last - your event, the changed model, the app state.` ) + ( name = `Response` + descr = `The JSON the backend sent back - the new view, the new model, the follow-up actions.` ) + ( name = `Source Code` + descr = `The ABAP class behind the running app, with an ADT jump link in the dialog footer.` ) + ( name = `View` + descr = `The XML view your ABAP built - what z2ui5_cl_ui5_view_builder stringified into the response.` ) + ( name = `View Model` + descr = `The model behind that view: every bound attribute of this class with its live value.` ) + ( name = `Popup, Popover, Nest1, Nest2` + descr = `The same two tabs - view and model - for each of the other view slots of the app.` ) ). + + ENDMETHOD. ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_500.clas.abap b/src/z2ui5_cl_smp_app_500.clas.abap index 46f0664a..1f165375 100644 --- a/src/z2ui5_cl_smp_app_500.clas.abap +++ b/src/z2ui5_cl_smp_app_500.clas.abap @@ -24,8 +24,8 @@ CLASS z2ui5_cl_smp_app_500 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS read_back_from_popup. PRIVATE SECTION. @@ -52,63 +52,6 @@ CLASS z2ui5_cl_smp_app_500 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_table = VALUE #( ( row_id = 1 carrid = `LH` connid = `0400` cityfrom = `FRANKFURT` cityto = `NEW YORK` ) - ( row_id = 2 carrid = `UA` connid = `0941` cityfrom = `FRANKFURT` cityto = `SAN FRANCISCO` ) - ( row_id = 3 carrid = `AA` connid = `0017` cityfrom = `NEW YORK` cityto = `SAN FRANCISCO` ) ). - next_id = 4. - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `ROW_SELECT`. - " the row press carries its ROW_ID, so the popup app is handed the - " row to edit rather than a screen position - client->nav_app_call( z2ui5_cl_smp_app_501=>factory( t_table = t_table - row_id = CONV #( client->get_event_arg( ) ) - edit = abap_true ) ). - - WHEN `BUTTON_ADD`. - client->nav_app_call( z2ui5_cl_smp_app_501=>factory( t_table = t_table - row_id = next_id - edit = abap_false ) ). - next_id = next_id + 1. - - WHEN `BUTTON_DELETE`. - DELETE t_table WHERE selkz = abap_true. - view_display( ). - - WHEN `BUTTON_REFRESH`. - on_init( ). - view_display( ). - - WHEN `BUTTON_SAVE`. - client->message_toast_display( |{ lines( t_table ) } row(s) saved| ). - - ENDCASE. - - ENDMETHOD. - - - METHOD read_back_from_popup. - - " get_app_prev( ) hands over the INSTANCE that was called, so its edited - " table is read straight off it - no payload has to travel back - TRY. - DATA(app) = CAST z2ui5_cl_smp_app_501( client->get_app_prev( ) ). - t_table = app->t_table. - - CATCH cx_root ##NO_HANDLER. - ENDTRY. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -200,4 +143,59 @@ CLASS z2ui5_cl_smp_app_500 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `ROW_SELECT`. + " the row press carries its ROW_ID, so the popup app is handed the + " row to edit rather than a screen position + client->nav_app_call( z2ui5_cl_smp_app_501=>factory( t_table = t_table + row_id = CONV #( client->get_event_arg( ) ) + edit = abap_true ) ). + + WHEN `BUTTON_ADD`. + client->nav_app_call( z2ui5_cl_smp_app_501=>factory( t_table = t_table + row_id = next_id + edit = abap_false ) ). + next_id = next_id + 1. + + WHEN `BUTTON_DELETE`. + DELETE t_table WHERE selkz = abap_true. + + WHEN `BUTTON_REFRESH`. + on_init( ). + + WHEN `BUTTON_SAVE`. + client->message_toast_display( |{ lines( t_table ) } row(s) saved| ). + + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + t_table = VALUE #( ( row_id = 1 carrid = `LH` connid = `0400` cityfrom = `FRANKFURT` cityto = `NEW YORK` ) + ( row_id = 2 carrid = `UA` connid = `0941` cityfrom = `FRANKFURT` cityto = `SAN FRANCISCO` ) + ( row_id = 3 carrid = `AA` connid = `0017` cityfrom = `NEW YORK` cityto = `SAN FRANCISCO` ) ). + next_id = 4. + + ENDMETHOD. + + + METHOD read_back_from_popup. + + " get_app_prev( ) hands over the INSTANCE that was called, so its edited + " table is read straight off it - no payload has to travel back + TRY. + DATA(app) = CAST z2ui5_cl_smp_app_501( client->get_app_prev( ) ). + t_table = app->t_table. + + CATCH cx_root ##NO_HANDLER. + ENDTRY. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_501.clas.abap b/src/z2ui5_cl_smp_app_501.clas.abap index d267ecac..ff914dad 100644 --- a/src/z2ui5_cl_smp_app_501.clas.abap +++ b/src/z2ui5_cl_smp_app_501.clas.abap @@ -33,16 +33,6 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_501 IMPLEMENTATION. - METHOD factory. - - result = NEW #( ). - result->t_table = t_table. - result->row_id = row_id. - result->edit = edit. - - ENDMETHOD. - - METHOD z2ui5_if_app~main. me->client = client. @@ -62,15 +52,6 @@ CLASS z2ui5_cl_smp_app_501 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - " the one row the dialog edits; an add starts from an empty row that - " already carries the id the caller handed over - s_row = VALUE #( t_table[ row_id = row_id ] DEFAULT VALUE #( row_id = row_id ) ). - - ENDMETHOD. - - METHOD on_event. CASE client->get_event( ). @@ -98,6 +79,25 @@ CLASS z2ui5_cl_smp_app_501 IMPLEMENTATION. ENDMETHOD. + METHOD factory. + + result = NEW #( ). + result->t_table = t_table. + result->row_id = row_id. + result->edit = edit. + + ENDMETHOD. + + + METHOD on_init. + + " the one row the dialog edits; an add starts from an empty row that + " already carries the id the caller handed over + s_row = VALUE #( t_table[ row_id = row_id ] DEFAULT VALUE #( row_id = row_id ) ). + + ENDMETHOD. + + METHOD leave. " no app passed: nav_app_leave( ) returns to the caller on the stack by diff --git a/src/z2ui5_cl_smp_app_502.clas.abap b/src/z2ui5_cl_smp_app_502.clas.abap index 1ccf6ec1..a01af337 100644 --- a/src/z2ui5_cl_smp_app_502.clas.abap +++ b/src/z2ui5_cl_smp_app_502.clas.abap @@ -57,7 +57,7 @@ CLASS z2ui5_cl_smp_app_502 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. + METHODS view_display. METHODS on_event_basic IMPORTING event TYPE clike @@ -77,7 +77,7 @@ CLASS z2ui5_cl_smp_app_502 DEFINITION PUBLIC. IMPORTING event TYPE clike. - METHODS view_display. + METHODS on_event. METHODS render_basic IMPORTING form TYPE REF TO z2ui5_cl_ui5_view_builder. METHODS render_message @@ -132,6 +132,57 @@ CLASS z2ui5_cl_smp_app_502 IMPLEMENTATION. ENDMETHOD. + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` + )->a( n = `xmlns:form` v = `sap.ui.layout.form` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Message - MessageBox for Any Data` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `client->message_box_display( ) takes TYPE any: throw in what the app already holds. ` && + `Messages are recognized first and bring their own severity and title; everything else - a table, ` && + `a structure, a tree, an object, a number, an HTML string - is rendered instead of dropped. ` && + `One button per case, and each button is one call: the app pre-formats nothing. That is what this ` && + `method is for; a pure sap.m.MessageBox option is set on the control instead - ` && + `Z2UI5_CL_SMP_APP_512 is the same box, steered through the global object.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + DATA(form) = page->ele( n = `SimpleForm` ns = `form` + )->a( n = `editable` b = abap_true + )->a( n = `layout` v = `ResponsiveGridLayout` + )->a( n = `labelSpanXL` v = `2` + )->a( n = `labelSpanL` v = `2` + )->a( n = `labelSpanM` v = `3` + )->a( n = `labelSpanS` v = `12` + )->a( n = `adjustLabelSpan` v = `false` + )->a( n = `columnsXL` v = `1` + )->a( n = `columnsL` v = `1` + )->a( n = `columnsM` v = `1` + )->ele( n = `content` ns = `form` ). + + render_basic( form ). + render_message( form ). + render_data( form ). + render_limit( form ). + render_box( form ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. DATA(event) = client->get_event( ). @@ -342,57 +393,6 @@ CLASS z2ui5_cl_smp_app_502 IMPLEMENTATION. ENDMETHOD. - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` - )->a( n = `xmlns:form` v = `sap.ui.layout.form` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Message - MessageBox for Any Data` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `client->message_box_display( ) takes TYPE any: throw in what the app already holds. ` && - `Messages are recognized first and bring their own severity and title; everything else - a table, ` && - `a structure, a tree, an object, a number, an HTML string - is rendered instead of dropped. ` && - `One button per case, and each button is one call: the app pre-formats nothing. That is what this ` && - `method is for; a pure sap.m.MessageBox option is set on the control instead - ` && - `Z2UI5_CL_SMP_APP_512 is the same box, steered through the global object.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - DATA(form) = page->ele( n = `SimpleForm` ns = `form` - )->a( n = `editable` b = abap_true - )->a( n = `layout` v = `ResponsiveGridLayout` - )->a( n = `labelSpanXL` v = `2` - )->a( n = `labelSpanL` v = `2` - )->a( n = `labelSpanM` v = `3` - )->a( n = `labelSpanS` v = `12` - )->a( n = `adjustLabelSpan` v = `false` - )->a( n = `columnsXL` v = `1` - )->a( n = `columnsL` v = `1` - )->a( n = `columnsM` v = `1` - )->ele( n = `content` ns = `form` ). - - render_basic( form ). - render_message( form ). - render_data( form ). - render_limit( form ). - render_box( form ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - - METHOD render_basic. render_section( form = form diff --git a/src/z2ui5_cl_smp_app_503.clas.abap b/src/z2ui5_cl_smp_app_503.clas.abap index 6d232c38..a3e17e96 100644 --- a/src/z2ui5_cl_smp_app_503.clas.abap +++ b/src/z2ui5_cl_smp_app_503.clas.abap @@ -79,20 +79,6 @@ CLASS z2ui5_cl_smp_app_503 IMPLEMENTATION. ENDMETHOD. - METHOD gross_amount. - - " computed as a packed number: net * percent leaves the range of TYPE i - " long before the gross does, and assigning to a packed number with no - " decimals rounds commercially - the half away from zero, so -10.5 becomes - " -11 as 10.5 becomes 11. The rounding is the part worth a test. - DATA gross_p TYPE p LENGTH 16 DECIMALS 0. - - gross_p = net + net * percent / 100. - result = gross_p. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -147,4 +133,18 @@ CLASS z2ui5_cl_smp_app_503 IMPLEMENTATION. ENDMETHOD. + + METHOD gross_amount. + + " computed as a packed number: net * percent leaves the range of TYPE i + " long before the gross does, and assigning to a packed number with no + " decimals rounds commercially - the half away from zero, so -10.5 becomes + " -11 as 10.5 becomes 11. The rounding is the part worth a test. + DATA gross_p TYPE p LENGTH 16 DECIMALS 0. + + gross_p = net + net * percent / 100. + result = gross_p. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_504.clas.abap b/src/z2ui5_cl_smp_app_504.clas.abap index f801b2f8..a5cf5dfc 100644 --- a/src/z2ui5_cl_smp_app_504.clas.abap +++ b/src/z2ui5_cl_smp_app_504.clas.abap @@ -45,9 +45,9 @@ CLASS z2ui5_cl_smp_app_504 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. - METHODS refused_apply. METHODS view_display. + METHODS refused_apply. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -75,115 +75,6 @@ CLASS z2ui5_cl_smp_app_504 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_row = VALUE #( - ( product = `Notebook 15"` price = '1299.00' currency = `EUR` stock = 12 price_state = `None` stock_state = `None` - t_item = VALUE #( ( name = `SSD 1 TB` qty = 1 qty_state = `None` ) - ( name = `RAM 16 GB` qty = 2 qty_state = `None` ) ) ) - ( product = `Monitor 27"` price = '349.90' currency = `EUR` stock = 5 price_state = `None` stock_state = `None` - t_item = VALUE #( ( name = `HDMI cable` qty = 1 qty_state = `None` ) ) ) - ( product = `USB-C Dock` price = '189.00' currency = `EUR` stock = 40 price_state = `None` stock_state = `None` - t_item = VALUE #( ( name = `Power supply` qty = 1 qty_state = `None` ) ) ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD refused_apply. - - FIELD-SYMBOLS TYPE ty_s_row. - FIELD-SYMBOLS TYPE ty_s_item. - - " every roundtrip starts clean: a cell the user has corrected since is - " not in this roundtrip's trace any more, so its state goes back to None - LOOP AT t_row ASSIGNING . - -price_state = `None`. - -stock_state = `None`. - -price_text = ``. - -stock_text = ``. - LOOP AT -t_item ASSIGNING . - -qty_state = `None`. - -qty_text = ``. - ENDLOOP. - ENDLOOP. - - DATA(t_skipped) = client->get( )-t_model_skipped. - report = ``. - LOOP AT t_skipped INTO DATA(s_skipped). - - " name is the bound attribute as the class declares it - T_ROW for a - " top-level cell, T_ROW-T_ITEM for a cell of the nested table; row is - " the 1-based index in THAT table, row_parent the owning row above it - CASE s_skipped-name. - - WHEN `T_ROW`. - READ TABLE t_row ASSIGNING INDEX s_skipped-row. - IF sy-subrc <> 0. - CONTINUE. - ENDIF. - - CASE s_skipped-field. - WHEN `PRICE`. - -price_state = `Error`. - -price_text = |'{ s_skipped-value }' is not a valid price - the stored value { -price } stands|. - WHEN `STOCK`. - -stock_state = `Error`. - -stock_text = |'{ s_skipped-value }' is not a whole number - the stored value { -stock } stands|. - ENDCASE. - - WHEN `T_ROW-T_ITEM`. - READ TABLE t_row ASSIGNING INDEX s_skipped-row_parent. - IF sy-subrc <> 0. - CONTINUE. - ENDIF. - - READ TABLE -t_item ASSIGNING INDEX s_skipped-row. - IF sy-subrc <> 0. - CONTINUE. - ENDIF. - - -qty_state = `Error`. - -qty_text = |'{ s_skipped-value }' is not a quantity - the stored value { -qty } stands|. - - ENDCASE. - - report = |{ report }{ s_skipped-name } row { s_skipped-row } field { s_skipped-field }: '{ s_skipped-value }' refused. |. - ENDLOOP. - - report_text = COND #( WHEN report IS INITIAL - THEN `Every cell of the last roundtrip converted.` - ELSE report ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `SAVE`. - " a save that would silently drop the refused cells is the failure - " this trace exists for - so a roundtrip with a trace is no save - IF report IS INITIAL. - client->message_toast_display( `saved - every cell converted` ). - ELSE. - client->message_box_display( text = |Not saved. { report }| - type = `error` ). - ENDIF. - - WHEN `RESET`. - " reading the trace pushes no model: the browser goes on showing - " the refused text until the app writes something. A re-render - " with the seed data is that write - on_init( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -294,4 +185,113 @@ CLASS z2ui5_cl_smp_app_504 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `SAVE`. + " a save that would silently drop the refused cells is the failure + " this trace exists for - so a roundtrip with a trace is no save + IF report IS INITIAL. + client->message_toast_display( `saved - every cell converted` ). + ELSE. + client->message_box_display( text = |Not saved. { report }| + type = `error` ). + ENDIF. + + WHEN `RESET`. + " reading the trace pushes no model: the browser goes on showing + " the refused text until the app writes something. A re-render + " with the seed data is that write + on_init( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + t_row = VALUE #( + ( product = `Notebook 15"` price = '1299.00' currency = `EUR` stock = 12 price_state = `None` stock_state = `None` + t_item = VALUE #( ( name = `SSD 1 TB` qty = 1 qty_state = `None` ) + ( name = `RAM 16 GB` qty = 2 qty_state = `None` ) ) ) + ( product = `Monitor 27"` price = '349.90' currency = `EUR` stock = 5 price_state = `None` stock_state = `None` + t_item = VALUE #( ( name = `HDMI cable` qty = 1 qty_state = `None` ) ) ) + ( product = `USB-C Dock` price = '189.00' currency = `EUR` stock = 40 price_state = `None` stock_state = `None` + t_item = VALUE #( ( name = `Power supply` qty = 1 qty_state = `None` ) ) ) ). + + view_display( ). + + ENDMETHOD. + + + METHOD refused_apply. + + FIELD-SYMBOLS TYPE ty_s_row. + FIELD-SYMBOLS TYPE ty_s_item. + + " every roundtrip starts clean: a cell the user has corrected since is + " not in this roundtrip's trace any more, so its state goes back to None + LOOP AT t_row ASSIGNING . + -price_state = `None`. + -stock_state = `None`. + -price_text = ``. + -stock_text = ``. + LOOP AT -t_item ASSIGNING . + -qty_state = `None`. + -qty_text = ``. + ENDLOOP. + ENDLOOP. + + DATA(t_skipped) = client->get( )-t_model_skipped. + report = ``. + LOOP AT t_skipped INTO DATA(s_skipped). + + " name is the bound attribute as the class declares it - T_ROW for a + " top-level cell, T_ROW-T_ITEM for a cell of the nested table; row is + " the 1-based index in THAT table, row_parent the owning row above it + CASE s_skipped-name. + + WHEN `T_ROW`. + READ TABLE t_row ASSIGNING INDEX s_skipped-row. + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + + CASE s_skipped-field. + WHEN `PRICE`. + -price_state = `Error`. + -price_text = |'{ s_skipped-value }' is not a valid price - the stored value { -price } stands|. + WHEN `STOCK`. + -stock_state = `Error`. + -stock_text = |'{ s_skipped-value }' is not a whole number - the stored value { -stock } stands|. + ENDCASE. + + WHEN `T_ROW-T_ITEM`. + READ TABLE t_row ASSIGNING INDEX s_skipped-row_parent. + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + + READ TABLE -t_item ASSIGNING INDEX s_skipped-row. + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + + -qty_state = `Error`. + -qty_text = |'{ s_skipped-value }' is not a quantity - the stored value { -qty } stands|. + + ENDCASE. + + report = |{ report }{ s_skipped-name } row { s_skipped-row } field { s_skipped-field }: '{ s_skipped-value }' refused. |. + ENDLOOP. + + report_text = COND #( WHEN report IS INITIAL + THEN `Every cell of the last roundtrip converted.` + ELSE report ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_505.clas.abap b/src/z2ui5_cl_smp_app_505.clas.abap index 2de7ba51..9fe83fdc 100644 --- a/src/z2ui5_cl_smp_app_505.clas.abap +++ b/src/z2ui5_cl_smp_app_505.clas.abap @@ -33,9 +33,9 @@ CLASS z2ui5_cl_smp_app_505 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. DATA sort_order TYPE string. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -47,7 +47,8 @@ CLASS z2ui5_cl_smp_app_505 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -57,62 +58,6 @@ CLASS z2ui5_cl_smp_app_505 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - " the display text is what the column shows - day first, which sorts - " wrong as text; the real date next to it is what the backend sorts by - t_row = VALUE #( - ( product = `Notebook 15"` stock = 12 created = `20260115` ) - ( product = `Monitor 27"` stock = 5 created = `20251203` ) - ( product = `USB-C Dock` stock = 40 created = `20260302` ) - ( product = `Keyboard` stock = 71 created = `20250928` ) - ( product = `Headset` stock = 9 created = `20260107` ) ). - - LOOP AT t_row REFERENCE INTO DATA(row). - DATA(created) = CONV string( row->created ). - row->created_text = |{ created+6(2) }.{ created+4(2) }.{ created(4) }|. - ENDLOOP. - - last_sort = `not sorted yet`. - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - IF client->check_on_event( `SORT` ). - - " the same event for every column: the sort property and the order - " the user asked for ride as arguments - DATA(property) = client->get_event_arg( ). - sort_order = client->get_event_arg( 2 ). - - IF property = `CREATED_TEXT`. - " the veto held on the client, so nothing is sorted yet: sort the - " ABAP table by the real date, then re-render so the column shows - " the indicator the client sort would have set - IF sort_order = `Descending`. - SORT t_row BY created DESCENDING. - ELSE. - SORT t_row BY created ASCENDING. - ENDIF. - - last_sort = |Date { sort_order } - sorted in the BACKEND by the real date, the client sort was cancelled|. - view_display( ). - - ELSE. - " the client sorted already; the backend only takes note. Nothing - " is re-rendered, the bound text below reaches the view on its own - last_sort = |{ property } { sort_order } - sorted by the CLIENT, the default ran|. - ENDIF. - - ENDIF. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -207,4 +152,58 @@ CLASS z2ui5_cl_smp_app_505 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->check_on_event( `SORT` ). + + " the same event for every column: the sort property and the order + " the user asked for ride as arguments + DATA(property) = client->get_event_arg( ). + sort_order = client->get_event_arg( 2 ). + + IF property = `CREATED_TEXT`. + " the veto held on the client, so nothing is sorted yet: sort the + " ABAP table by the real date, then re-render so the column shows + " the indicator the client sort would have set + IF sort_order = `Descending`. + SORT t_row BY created DESCENDING. + ELSE. + SORT t_row BY created ASCENDING. + ENDIF. + + last_sort = |Date { sort_order } - sorted in the BACKEND by the real date, the client sort was cancelled|. + view_display( ). + + ELSE. + " the client sorted already; the backend only takes note. Nothing + " is re-rendered, the bound text below reaches the view on its own + last_sort = |{ property } { sort_order } - sorted by the CLIENT, the default ran|. + ENDIF. + + ENDIF. + + ENDMETHOD. + + + METHOD model_init. + + " the display text is what the column shows - day first, which sorts + " wrong as text; the real date next to it is what the backend sorts by + t_row = VALUE #( + ( product = `Notebook 15"` stock = 12 created = `20260115` ) + ( product = `Monitor 27"` stock = 5 created = `20251203` ) + ( product = `USB-C Dock` stock = 40 created = `20260302` ) + ( product = `Keyboard` stock = 71 created = `20250928` ) + ( product = `Headset` stock = 9 created = `20260107` ) ). + + LOOP AT t_row REFERENCE INTO DATA(row). + DATA(created) = CONV string( row->created ). + row->created_text = |{ created+6(2) }.{ created+4(2) }.{ created(4) }|. + ENDLOOP. + + last_sort = `not sorted yet`. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_506.clas.abap b/src/z2ui5_cl_smp_app_506.clas.abap index 5f0af910..3bcd32c1 100644 --- a/src/z2ui5_cl_smp_app_506.clas.abap +++ b/src/z2ui5_cl_smp_app_506.clas.abap @@ -24,8 +24,8 @@ CLASS z2ui5_cl_smp_app_506 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -55,31 +55,6 @@ CLASS z2ui5_cl_smp_app_506 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `RAW`. - " what the client resolved: `${/PRICE}` names the bound price, so - " its value arrives, not the text - raw_arg = client->get_event_arg( ). - - WHEN `LITERAL`. - " the same argument, quoted by check_arg_literal: the text arrives - lit_arg = client->get_event_arg( ). - - WHEN `REBUILD`. - " the argument is written into the view at render time, so a new - " text needs a new view - the two wires below carry it from then on - raw_arg = `-`. - lit_arg = `-`. - view_display( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -151,4 +126,29 @@ CLASS z2ui5_cl_smp_app_506 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `RAW`. + " what the client resolved: `${/PRICE}` names the bound price, so + " its value arrives, not the text + raw_arg = client->get_event_arg( ). + + WHEN `LITERAL`. + " the same argument, quoted by check_arg_literal: the text arrives + lit_arg = client->get_event_arg( ). + + WHEN `REBUILD`. + " the argument is written into the view at render time, so a new + " text needs a new view - the two wires below carry it from then on + raw_arg = `-`. + lit_arg = `-`. + view_display( ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_510.clas.abap b/src/z2ui5_cl_smp_app_510.clas.abap index 77ab1c85..8ff09c95 100644 --- a/src/z2ui5_cl_smp_app_510.clas.abap +++ b/src/z2ui5_cl_smp_app_510.clas.abap @@ -21,8 +21,8 @@ CLASS z2ui5_cl_smp_app_510 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS nest_display IMPORTING slot TYPE string. @@ -50,6 +50,76 @@ CLASS z2ui5_cl_smp_app_510 IMPLEMENTATION. ENDMETHOD. + METHOD view_display. + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Nested View - Destroy and Target a Slot` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Show and destroy the two nested views, then send the focus into one of them: the ` && + `view parameter of follow_up_action decides which slot the id lookup is scoped to - ` && + `a slot that is not open finds nothing.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + page->ele( `HBox` + )->a( n = `wrap` v = `Wrap` + )->a( n = `class` v = `sapUiSmallMargin` + )->tag( `Button` + )->a( n = `text` v = `show nested view 1` + )->a( n = `press` v = client->_event( `NEST_SHOW` ) + )->tag( `Button` + )->a( n = `text` v = `destroy nested view 1` + )->a( n = `press` v = client->_event( `NEST_DESTROY` ) + )->tag( `Button` + )->a( n = `text` v = `focus the input in slot nested` + )->a( n = `press` v = client->_event( `FOCUS_NEST` ) + )->tag( `ToolbarSpacer` + )->a( n = `width` v = `1rem` + )->tag( `Button` + )->a( n = `text` v = `show nested view 2` + )->a( n = `press` v = client->_event( `NEST2_SHOW` ) + )->tag( `Button` + )->a( n = `text` v = `destroy nested view 2` + )->a( n = `press` v = client->_event( `NEST2_DESTROY` ) + )->tag( `Button` + )->a( n = `text` v = `focus the input in slot nested2` + )->a( n = `press` v = client->_event( `FOCUS_NEST2` ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = client->_bind( status ) + )->a( n = `type` v = `Success` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + " the two containers the nested views are inserted into - a VBox each, + " addItem inserts, removeAllItems clears before a repeated display + page->ele( `HBox` + )->a( n = `class` v = `sapUiSmallMargin` + )->tag( `VBox` + )->a( n = `id` v = `box_nest` + )->a( n = `width` v = `20rem` + )->a( n = `class` v = `sapUiSmallMarginEnd` + )->tag( `VBox` + )->a( n = `id` v = `box_nest2` + )->a( n = `width` v = `20rem` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. CASE client->get_event( ). @@ -132,74 +202,4 @@ CLASS z2ui5_cl_smp_app_510 IMPLEMENTATION. ENDMETHOD. - - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Nested View - Destroy and Target a Slot` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Show and destroy the two nested views, then send the focus into one of them: the ` && - `view parameter of follow_up_action decides which slot the id lookup is scoped to - ` && - `a slot that is not open finds nothing.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - page->ele( `HBox` - )->a( n = `wrap` v = `Wrap` - )->a( n = `class` v = `sapUiSmallMargin` - )->tag( `Button` - )->a( n = `text` v = `show nested view 1` - )->a( n = `press` v = client->_event( `NEST_SHOW` ) - )->tag( `Button` - )->a( n = `text` v = `destroy nested view 1` - )->a( n = `press` v = client->_event( `NEST_DESTROY` ) - )->tag( `Button` - )->a( n = `text` v = `focus the input in slot nested` - )->a( n = `press` v = client->_event( `FOCUS_NEST` ) - )->tag( `ToolbarSpacer` - )->a( n = `width` v = `1rem` - )->tag( `Button` - )->a( n = `text` v = `show nested view 2` - )->a( n = `press` v = client->_event( `NEST2_SHOW` ) - )->tag( `Button` - )->a( n = `text` v = `destroy nested view 2` - )->a( n = `press` v = client->_event( `NEST2_DESTROY` ) - )->tag( `Button` - )->a( n = `text` v = `focus the input in slot nested2` - )->a( n = `press` v = client->_event( `FOCUS_NEST2` ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = client->_bind( status ) - )->a( n = `type` v = `Success` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - " the two containers the nested views are inserted into - a VBox each, - " addItem inserts, removeAllItems clears before a repeated display - page->ele( `HBox` - )->a( n = `class` v = `sapUiSmallMargin` - )->tag( `VBox` - )->a( n = `id` v = `box_nest` - )->a( n = `width` v = `20rem` - )->a( n = `class` v = `sapUiSmallMarginEnd` - )->tag( `VBox` - )->a( n = `id` v = `box_nest2` - )->a( n = `width` v = `20rem` ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_512.clas.abap b/src/z2ui5_cl_smp_app_512.clas.abap index cab9fde4..a5f6ae35 100644 --- a/src/z2ui5_cl_smp_app_512.clas.abap +++ b/src/z2ui5_cl_smp_app_512.clas.abap @@ -11,8 +11,8 @@ CLASS z2ui5_cl_smp_app_512 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS render_demo IMPORTING form TYPE REF TO z2ui5_cl_ui5_view_builder @@ -39,71 +39,6 @@ CLASS z2ui5_cl_smp_app_512 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `TYPE`. - " The display method IS the box type: show, alert, confirm, - " information, warning, error, success - the seven methods - " sap.m.MessageBox carries, called by name. No mapping, no - " translation, nothing this sample has to keep in sync with UI5 - client->follow_up_action( val = client->cs_event-control_global - t_arg = VALUE #( ( `MESSAGE_BOX` ) - ( client->get_event_arg( ) ) - ( |MessageBox.{ client->get_event_arg( ) }( ) - called by its own name| ) ) ). - - WHEN `OPTIONS`. - " Everything sap.m.MessageBox takes, in the option object of the - " call: a t_arg that starts with a brace is embedded as REAL JSON, - " so this arrives as an object and the names are the UI5 names. - " These five have no parameter on client->message_box_display( ) - - " they belong to the control, not to the ABAP app, and this is - " where they are set. Z2UI5_CL_SMP_APP_502 is the other half: the - " same box, filled with whatever data the app already holds - client->follow_up_action( - val = client->cs_event-control_global - t_arg = VALUE #( ( `MESSAGE_BOX` ) - ( `warning` ) - ( `The delivery date lies in the past.` ) - ( `{"title":"Please check","icon":"WARNING","contentWidth":"25rem",` && - `"textDirection":"Inherit","closeOnNavigation":false,"styleClass":"sapUiSizeCompact"}` ) ) ). - - WHEN `DEPENDENT`. - " dependentOn ties the box to the lifecycle of a control - it is - " destroyed with it. The backend sends the control id and the - " frontend resolves it; an id it cannot resolve drops the option - " rather than handing UI5 a string it would choke on. UI5 1.124 on - client->follow_up_action( - val = client->cs_event-control_global - t_arg = VALUE #( ( `MESSAGE_BOX` ) - ( `information` ) - ( `This box is a dependent of the panel below - it dies with it.` ) - ( `{"dependentOn":"demoPanel"}` ) ) ). - - WHEN `ACTIONS`. - " onClose is a BACKEND event name even here: the frontend turns it - " into the round-trip that reaches the ANSWERED branch below, with - " the pressed action as the first event argument. So the raw call - " is not a one-way street - it reaches the app again like any event - client->follow_up_action( - val = client->cs_event-control_global - t_arg = VALUE #( ( `MESSAGE_BOX` ) - ( `warning` ) - ( `Delete document 4711?` ) - ( `{"title":"Delete","actions":["DELETE","Later","CANCEL"],` && - `"emphasizedAction":"DELETE","initialFocus":"CANCEL","onClose":"ANSWERED"}` ) ) ). - - WHEN `ANSWERED`. - " the answer of the box above. Nothing is rendered here: `answer` is - " bound, and changed bound data reaches the open view on its own - answer = client->get_event_arg( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -201,6 +136,71 @@ CLASS z2ui5_cl_smp_app_512 IMPLEMENTATION. ENDMETHOD. + METHOD on_event. + + CASE client->get_event( ). + + WHEN `TYPE`. + " The display method IS the box type: show, alert, confirm, + " information, warning, error, success - the seven methods + " sap.m.MessageBox carries, called by name. No mapping, no + " translation, nothing this sample has to keep in sync with UI5 + client->follow_up_action( val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) + ( client->get_event_arg( ) ) + ( |MessageBox.{ client->get_event_arg( ) }( ) - called by its own name| ) ) ). + + WHEN `OPTIONS`. + " Everything sap.m.MessageBox takes, in the option object of the + " call: a t_arg that starts with a brace is embedded as REAL JSON, + " so this arrives as an object and the names are the UI5 names. + " These five have no parameter on client->message_box_display( ) - + " they belong to the control, not to the ABAP app, and this is + " where they are set. Z2UI5_CL_SMP_APP_502 is the other half: the + " same box, filled with whatever data the app already holds + client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) + ( `warning` ) + ( `The delivery date lies in the past.` ) + ( `{"title":"Please check","icon":"WARNING","contentWidth":"25rem",` && + `"textDirection":"Inherit","closeOnNavigation":false,"styleClass":"sapUiSizeCompact"}` ) ) ). + + WHEN `DEPENDENT`. + " dependentOn ties the box to the lifecycle of a control - it is + " destroyed with it. The backend sends the control id and the + " frontend resolves it; an id it cannot resolve drops the option + " rather than handing UI5 a string it would choke on. UI5 1.124 on + client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) + ( `information` ) + ( `This box is a dependent of the panel below - it dies with it.` ) + ( `{"dependentOn":"demoPanel"}` ) ) ). + + WHEN `ACTIONS`. + " onClose is a BACKEND event name even here: the frontend turns it + " into the round-trip that reaches the ANSWERED branch below, with + " the pressed action as the first event argument. So the raw call + " is not a one-way street - it reaches the app again like any event + client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) + ( `warning` ) + ( `Delete document 4711?` ) + ( `{"title":"Delete","actions":["DELETE","Later","CANCEL"],` && + `"emphasizedAction":"DELETE","initialFocus":"CANCEL","onClose":"ANSWERED"}` ) ) ). + + WHEN `ANSWERED`. + " the answer of the box above. Nothing is rendered here: `answer` is + " bound, and changed bound data reaches the open view on its own + answer = client->get_event_arg( ). + + ENDCASE. + + ENDMETHOD. + + METHOD render_demo. form->tag( `Label` diff --git a/src/z2ui5_cl_smp_app_513.clas.abap b/src/z2ui5_cl_smp_app_513.clas.abap index b5cf1f4a..21b1ebb1 100644 --- a/src/z2ui5_cl_smp_app_513.clas.abap +++ b/src/z2ui5_cl_smp_app_513.clas.abap @@ -36,59 +36,6 @@ CLASS z2ui5_cl_smp_app_513 IMPLEMENTATION. ENDMETHOD. - METHOD css_set. - - " t_arg is positional: id, the pseudo-method `css`, the property, the value. - " `css` is not a UI5 method - it is a frontend capability in method form, - " and only ten properties are allowed: width, min-width, max-width, - " height, min-height, max-height, color, background-color, font-size and - " opacity. Anything else is refused and logged, never applied. - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `demoPanel` ) - ( `css` ) - ( property ) - ( value ) ) ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `HIGHLIGHT`. - highlighted = xsdbool( highlighted = abap_false ). - " sap.m.Panel carries no background colour and no font size, so there - " is no property to bind and nothing a formatter could reach. The - " declaration lands on the panel's own DOM node. - IF highlighted = abap_true. - css_set( property = `background-color` - value = `#fff4e5` ). - css_set( property = `font-size` - value = `1.25rem` ). - ELSE. - " an empty value removes the declaration again - css_set( property = `background-color` - value = `` ). - css_set( property = `font-size` - value = `` ). - ENDIF. - - WHEN `FADE`. - css_set( property = `opacity` - value = `0.35` ). - - WHEN `RESET`. - " the declaration lives on the element and is gone after a re-render, - " so a fresh view is the other way back to the control's own styling - highlighted = abap_false. - view_display( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -147,4 +94,57 @@ CLASS z2ui5_cl_smp_app_513 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `HIGHLIGHT`. + highlighted = xsdbool( highlighted = abap_false ). + " sap.m.Panel carries no background colour and no font size, so there + " is no property to bind and nothing a formatter could reach. The + " declaration lands on the panel's own DOM node. + IF highlighted = abap_true. + css_set( property = `background-color` + value = `#fff4e5` ). + css_set( property = `font-size` + value = `1.25rem` ). + ELSE. + " an empty value removes the declaration again + css_set( property = `background-color` + value = `` ). + css_set( property = `font-size` + value = `` ). + ENDIF. + + WHEN `FADE`. + css_set( property = `opacity` + value = `0.35` ). + + WHEN `RESET`. + " the declaration lives on the element and is gone after a re-render, + " so a fresh view is the other way back to the control's own styling + highlighted = abap_false. + view_display( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD css_set. + + " t_arg is positional: id, the pseudo-method `css`, the property, the value. + " `css` is not a UI5 method - it is a frontend capability in method form, + " and only ten properties are allowed: width, min-width, max-width, + " height, min-height, max-height, color, background-color, font-size and + " opacity. Anything else is refused and logged, never applied. + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `demoPanel` ) + ( `css` ) + ( property ) + ( value ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_514.clas.abap b/src/z2ui5_cl_smp_app_514.clas.abap index 6482ca7b..a5cb2b5e 100644 --- a/src/z2ui5_cl_smp_app_514.clas.abap +++ b/src/z2ui5_cl_smp_app_514.clas.abap @@ -21,8 +21,8 @@ CLASS z2ui5_cl_smp_app_514 DEFINITION PUBLIC. DATA current TYPE i. METHODS view_display. - METHODS model_init. METHODS on_event. + METHODS model_init. METHODS page_show IMPORTING index TYPE i. @@ -48,61 +48,6 @@ CLASS z2ui5_cl_smp_app_514 IMPLEMENTATION. ENDMETHOD. - METHOD model_init. - - t_pages = VALUE #( ( title = `Bicycle` text = `The first page of the carousel.` ) - ( title = `Car` text = `The second page - and the one the buttons below jump to.` ) - ( title = `Train` text = `The third page.` ) - ( title = `Aircraft` text = `The fourth and last page.` ) ). - current = 1. - - ENDMETHOD. - - - METHOD page_show. - - current = index. - " A page of this carousel is a CLONE of the aggregation template, and a - " clone has no id the backend can spell: UI5 mints it from the template - " id, the parent id and the position, and the parent id carries the view - " prefix assigned at runtime. So the item is addressed POSITIONALLY - - " `//`, 0-based - which the frontend - " resolves against the live aggregation. It is the equivalent of the UI5 - " controller idiom oCarousel.setActivePage( oCarousel.getPages()[ i ] ). - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id - t_arg = VALUE #( ( `demoCarousel` ) - ( `setActivePage` ) - ( |demoCarousel/pages/{ index - 1 }| ) ) ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `FIRST`. - page_show( 1 ). - - WHEN `NEXT`. - " wrap around at the end - the count is ABAP's, not the carousel's - page_show( COND #( WHEN current >= lines( t_pages ) THEN 1 ELSE current + 1 ) ). - - WHEN `LAST`. - page_show( lines( t_pages ) ). - - WHEN `PAGE_CHANGED`. - " swiped or jumped - activePages is 0-based, current counts from 1 - DATA(active) = client->get_event_arg( ). - IF active CO `0123456789` AND active IS NOT INITIAL. - current = active + 1. - ENDIF. - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -178,4 +123,59 @@ CLASS z2ui5_cl_smp_app_514 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `FIRST`. + page_show( 1 ). + + WHEN `NEXT`. + " wrap around at the end - the count is ABAP's, not the carousel's + page_show( COND #( WHEN current >= lines( t_pages ) THEN 1 ELSE current + 1 ) ). + + WHEN `LAST`. + page_show( lines( t_pages ) ). + + WHEN `PAGE_CHANGED`. + " swiped or jumped - activePages is 0-based, current counts from 1 + DATA(active) = client->get_event_arg( ). + IF active CO `0123456789` AND active IS NOT INITIAL. + current = active + 1. + ENDIF. + + ENDCASE. + + ENDMETHOD. + + + METHOD page_show. + + current = index. + " A page of this carousel is a CLONE of the aggregation template, and a + " clone has no id the backend can spell: UI5 mints it from the template + " id, the parent id and the position, and the parent id carries the view + " prefix assigned at runtime. So the item is addressed POSITIONALLY - + " `//`, 0-based - which the frontend + " resolves against the live aggregation. It is the equivalent of the UI5 + " controller idiom oCarousel.setActivePage( oCarousel.getPages()[ i ] ). + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id + t_arg = VALUE #( ( `demoCarousel` ) + ( `setActivePage` ) + ( |demoCarousel/pages/{ index - 1 }| ) ) ). + + ENDMETHOD. + + + METHOD model_init. + + t_pages = VALUE #( ( title = `Bicycle` text = `The first page of the carousel.` ) + ( title = `Car` text = `The second page - and the one the buttons below jump to.` ) + ( title = `Train` text = `The third page.` ) + ( title = `Aircraft` text = `The fourth and last page.` ) ). + current = 1. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_515.clas.abap b/src/z2ui5_cl_smp_app_515.clas.abap index b1cb5759..ee04c8d2 100644 --- a/src/z2ui5_cl_smp_app_515.clas.abap +++ b/src/z2ui5_cl_smp_app_515.clas.abap @@ -39,45 +39,6 @@ CLASS z2ui5_cl_smp_app_515 IMPLEMENTATION. ENDMETHOD. - METHOD busy_call. - - " sap.ui.core.BusyIndicator renders nothing of its own and has no id, so - " control_by_id cannot address it - control_global is the only wire that - " reaches a singleton like this one. t_arg is positional: the object, the - " method, then its arguments. show( ) takes the delay in milliseconds - " before the spinner appears; hide( ) takes none. - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_global - t_arg = COND #( WHEN arg IS INITIAL - THEN VALUE #( ( `BUSY_INDICATOR` ) ( method ) ) - ELSE VALUE #( ( `BUSY_INDICATOR` ) ( method ) ( arg ) ) ) ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `START`. - " The indicator blocks the whole screen, so nothing the user does can - " take it away again - something in this response has to. A client - " timer is what fills the gap here; a real app would hide it in the - " handler of whatever it was waiting for. - status = `Running - the BusyIndicator is up, the timer takes it away.`. - busy_call( method = `show` - arg = `0` ). - client->follow_up_action( val = z2ui5_if_client=>cs_event-start_timer - t_arg = VALUE #( ( `FINISHED` ) ( `2500` ) ) ). - - WHEN `FINISHED`. - status = `Done - hide( ) was called from the timer's handler.`. - busy_call( `hide` ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -119,4 +80,43 @@ CLASS z2ui5_cl_smp_app_515 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `START`. + " The indicator blocks the whole screen, so nothing the user does can + " take it away again - something in this response has to. A client + " timer is what fills the gap here; a real app would hide it in the + " handler of whatever it was waiting for. + status = `Running - the BusyIndicator is up, the timer takes it away.`. + busy_call( method = `show` + arg = `0` ). + client->follow_up_action( val = z2ui5_if_client=>cs_event-start_timer + t_arg = VALUE #( ( `FINISHED` ) ( `2500` ) ) ). + + WHEN `FINISHED`. + status = `Done - hide( ) was called from the timer's handler.`. + busy_call( `hide` ). + + ENDCASE. + + ENDMETHOD. + + + METHOD busy_call. + + " sap.ui.core.BusyIndicator renders nothing of its own and has no id, so + " control_by_id cannot address it - control_global is the only wire that + " reaches a singleton like this one. t_arg is positional: the object, the + " method, then its arguments. show( ) takes the delay in milliseconds + " before the spinner appears; hide( ) takes none. + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_global + t_arg = COND #( WHEN arg IS INITIAL + THEN VALUE #( ( `BUSY_INDICATOR` ) ( method ) ) + ELSE VALUE #( ( `BUSY_INDICATOR` ) ( method ) ( arg ) ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_516.clas.abap b/src/z2ui5_cl_smp_app_516.clas.abap index d833b10d..3f83d18f 100644 --- a/src/z2ui5_cl_smp_app_516.clas.abap +++ b/src/z2ui5_cl_smp_app_516.clas.abap @@ -36,28 +36,6 @@ CLASS z2ui5_cl_smp_app_516 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - " The mode is an ordinary bound attribute, so switching the keyboard is a - " model update and nothing else - no follow-up action travels, and there - " is no ordering to get right between the action and the next render. - CASE client->get_event( ). - WHEN `NUMERIC`. - mode = `numeric`. - WHEN `DECIMAL`. - mode = `decimal`. - WHEN `TEL`. - mode = `tel`. - WHEN `NONE`. - mode = `none`. - WHEN `OFF`. - " empty leaves the field exactly as sap.m.Input rendered it - mode = ``. - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -127,4 +105,26 @@ CLASS z2ui5_cl_smp_app_516 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + " The mode is an ordinary bound attribute, so switching the keyboard is a + " model update and nothing else - no follow-up action travels, and there + " is no ordering to get right between the action and the next render. + CASE client->get_event( ). + WHEN `NUMERIC`. + mode = `numeric`. + WHEN `DECIMAL`. + mode = `decimal`. + WHEN `TEL`. + mode = `tel`. + WHEN `NONE`. + mode = `none`. + WHEN `OFF`. + " empty leaves the field exactly as sap.m.Input rendered it + mode = ``. + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_517.clas.abap b/src/z2ui5_cl_smp_app_517.clas.abap index 065b5fb4..a579acdd 100644 --- a/src/z2ui5_cl_smp_app_517.clas.abap +++ b/src/z2ui5_cl_smp_app_517.clas.abap @@ -46,41 +46,6 @@ CLASS z2ui5_cl_smp_app_517 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `FILE_ADDED`. - " The companion hands over ONE file per roundtrip - several files - " picked at once arrive one after the other, each waiting for the - " previous response. fileData is a base64 DATA URL, so the payload - " starts after the comma. - IF file_name IS NOT INITIAL. - DATA(payload) = substring_after( val = file_data - sub = `,` ). - " the decoded length, so the sample shows the bytes ABAP actually - " received rather than the base64 text: three bytes per four - " characters, less the one or two `=` that pad the last group - DATA(padding) = COND i( WHEN payload CP `*==` THEN 2 - WHEN payload CP `*=` THEN 1 - ELSE 0 ). - INSERT VALUE #( name = file_name - type = file_type - size = file_size - bytes = strlen( payload ) * 3 / 4 - padding ) INTO TABLE t_received. - ENDIF. - - WHEN `FILE_REMOVED`. - DELETE t_received WHERE name = removed. - - WHEN `CLEAR`. - t_received = VALUE #( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -171,4 +136,39 @@ CLASS z2ui5_cl_smp_app_517 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `FILE_ADDED`. + " The companion hands over ONE file per roundtrip - several files + " picked at once arrive one after the other, each waiting for the + " previous response. fileData is a base64 DATA URL, so the payload + " starts after the comma. + IF file_name IS NOT INITIAL. + DATA(payload) = substring_after( val = file_data + sub = `,` ). + " the decoded length, so the sample shows the bytes ABAP actually + " received rather than the base64 text: three bytes per four + " characters, less the one or two `=` that pad the last group + DATA(padding) = COND i( WHEN payload CP `*==` THEN 2 + WHEN payload CP `*=` THEN 1 + ELSE 0 ). + INSERT VALUE #( name = file_name + type = file_type + size = file_size + bytes = strlen( payload ) * 3 / 4 - padding ) INTO TABLE t_received. + ENDIF. + + WHEN `FILE_REMOVED`. + DELETE t_received WHERE name = removed. + + WHEN `CLEAR`. + t_received = VALUE #( ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_518.clas.abap b/src/z2ui5_cl_smp_app_518.clas.abap index 96d1049f..891f3475 100644 --- a/src/z2ui5_cl_smp_app_518.clas.abap +++ b/src/z2ui5_cl_smp_app_518.clas.abap @@ -30,6 +30,8 @@ CLASS z2ui5_cl_smp_app_518 IMPLEMENTATION. ELSEIF client->check_on_event( `FONT_REGISTERED` ). font_registered = abap_true. + " the TNT icon is a control the first view deliberately left out + " (see font_register) - adding it takes a new view, not a model push view_display( ). ENDIF. @@ -37,34 +39,6 @@ CLASS z2ui5_cl_smp_app_518 IMPLEMENTATION. ENDMETHOD. - METHOD font_register. - - " A normal UI5 app does this in its Component's init. An abap2UI5 app has - " no Component of its own, and IconPool is a module SINGLETON rather than - " a control, so no other wire reaches it. t_arg is positional: the font - " family and the font URI - a module path in every real use, resolved - " through sap.ui.require.toUrl, so the registration survives a different - " mount point. - " - " Issue it from the init branch: the collection is registered once per - " session, so a repeat call costs nothing but says the wrong thing. - client->follow_up_action( val = z2ui5_if_client=>cs_event-control_global - t_arg = VALUE #( ( `ICON_POOL` ) - ( `registerFont` ) - ( `SAP-icons-TNT` ) - ( `sap/tnt/themes/base/fonts/` ) ) ). - - " A follow-up action runs AFTER the view of the same roundtrip has - " rendered, so a TNT icon in that view would be drawn while the - " collection is still unknown - empty, and UI5 logs an error for it. The - " timer queues one roundtrip behind the registration, and only the view - " that roundtrip displays carries the icon. - client->follow_up_action( val = z2ui5_if_client=>cs_event-start_timer - t_arg = VALUE #( ( `FONT_REGISTERED` ) ( `0` ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -115,4 +89,32 @@ CLASS z2ui5_cl_smp_app_518 IMPLEMENTATION. ENDMETHOD. + + METHOD font_register. + + " A normal UI5 app does this in its Component's init. An abap2UI5 app has + " no Component of its own, and IconPool is a module SINGLETON rather than + " a control, so no other wire reaches it. t_arg is positional: the font + " family and the font URI - a module path in every real use, resolved + " through sap.ui.require.toUrl, so the registration survives a different + " mount point. + " + " Issue it from the init branch: the collection is registered once per + " session, so a repeat call costs nothing but says the wrong thing. + client->follow_up_action( val = z2ui5_if_client=>cs_event-control_global + t_arg = VALUE #( ( `ICON_POOL` ) + ( `registerFont` ) + ( `SAP-icons-TNT` ) + ( `sap/tnt/themes/base/fonts/` ) ) ). + + " A follow-up action runs AFTER the view of the same roundtrip has + " rendered, so a TNT icon in that view would be drawn while the + " collection is still unknown - empty, and UI5 logs an error for it. The + " timer queues one roundtrip behind the registration, and only the view + " that roundtrip displays carries the icon. + client->follow_up_action( val = z2ui5_if_client=>cs_event-start_timer + t_arg = VALUE #( ( `FONT_REGISTERED` ) ( `0` ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_519.clas.abap b/src/z2ui5_cl_smp_app_519.clas.abap index 47b83f34..53048372 100644 --- a/src/z2ui5_cl_smp_app_519.clas.abap +++ b/src/z2ui5_cl_smp_app_519.clas.abap @@ -32,18 +32,6 @@ CLASS z2ui5_cl_smp_app_519 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - IF client->get_event( ) = `GREET`. - " The text element is translated, the value is not - so the two are - " concatenated here rather than written as one literal. A text element - " with a placeholder would be a message class instead. - client->message_box_display( |{ 'Hello'(004) } { name }| ). - ENDIF. - - ENDMETHOD. - - METHOD view_display. " the three text symbols this app is about - see the block below @@ -115,4 +103,16 @@ CLASS z2ui5_cl_smp_app_519 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + IF client->get_event( ) = `GREET`. + " The text element is translated, the value is not - so the two are + " concatenated here rather than written as one literal. A text element + " with a placeholder would be a message class instead. + client->message_box_display( |{ 'Hello'(004) } { name }| ). + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_530.clas.abap b/src/z2ui5_cl_smp_app_530.clas.abap index c994f5e0..fe658c07 100644 --- a/src/z2ui5_cl_smp_app_530.clas.abap +++ b/src/z2ui5_cl_smp_app_530.clas.abap @@ -52,42 +52,6 @@ CLASS z2ui5_cl_smp_app_530 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `SUBMIT`. - " a scanner types the code and sends Enter - sap.m.Input raises - " submit, and the wire carries the value with it, so the roundtrip - " already has what was scanned - IF value IS NOT INITIAL. - INSERT VALUE #( pos = lines( t_scans ) + 1 - code = value ) INTO TABLE t_scans. - value = ``. - ENDIF. - " back into the empty field, ready for the next code - focus_field( ). - - WHEN `TOGGLE`. - mode = COND #( WHEN mode = `none` THEN `text` ELSE `none` ). - focus_field( ). - - WHEN `CLEAR`. - t_scans = VALUE #( ). - - ENDCASE. - - ENDMETHOD. - - - METHOD focus_field. - - client->follow_up_action( val = client->cs_event-set_focus - t_arg = VALUE #( ( c_field ) ) ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -169,4 +133,40 @@ CLASS z2ui5_cl_smp_app_530 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `SUBMIT`. + " a scanner types the code and sends Enter - sap.m.Input raises + " submit, and the wire carries the value with it, so the roundtrip + " already has what was scanned + IF value IS NOT INITIAL. + INSERT VALUE #( pos = lines( t_scans ) + 1 + code = value ) INTO TABLE t_scans. + value = ``. + ENDIF. + " back into the empty field, ready for the next code + focus_field( ). + + WHEN `TOGGLE`. + mode = COND #( WHEN mode = `none` THEN `text` ELSE `none` ). + focus_field( ). + + WHEN `CLEAR`. + t_scans = VALUE #( ). + + ENDCASE. + + ENDMETHOD. + + + METHOD focus_field. + + client->follow_up_action( val = client->cs_event-set_focus + t_arg = VALUE #( ( c_field ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_532.clas.abap b/src/z2ui5_cl_smp_app_532.clas.abap index 5f3d0a52..5ed925d2 100644 --- a/src/z2ui5_cl_smp_app_532.clas.abap +++ b/src/z2ui5_cl_smp_app_532.clas.abap @@ -34,15 +34,6 @@ ENDCLASS. CLASS z2ui5_cl_smp_app_532 IMPLEMENTATION. - METHOD factory. - - result = NEW #( ). - result->transition = transition. - result->level = level. - - ENDMETHOD. - - METHOD z2ui5_if_app~main. me->client = client. @@ -60,28 +51,6 @@ CLASS z2ui5_cl_smp_app_532 IMPLEMENTATION. ENDMETHOD. - METHOD on_event. - - CASE client->get_event( ). - - WHEN `DEEPER`. - client->nav_app_call( factory( transition = transition level = level + 1 ) ). - - WHEN `RERENDER`. - renders = renders + 1. - view_display( abap_false ). - - WHEN `REPLACE`. - client->nav_app_leave( factory( transition = transition level = level ) ). - - WHEN `POPUP`. - client->nav_app_call( NEW z2ui5_cl_smp_app_534( ) ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. " one color per level, so the two pages can be told apart while they move @@ -156,4 +125,35 @@ CLASS z2ui5_cl_smp_app_532 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `DEEPER`. + client->nav_app_call( factory( transition = transition level = level + 1 ) ). + + WHEN `RERENDER`. + renders = renders + 1. + view_display( abap_false ). + + WHEN `REPLACE`. + client->nav_app_leave( factory( transition = transition level = level ) ). + + WHEN `POPUP`. + client->nav_app_call( NEW z2ui5_cl_smp_app_534( ) ). + + ENDCASE. + + ENDMETHOD. + + + METHOD factory. + + result = NEW #( ). + result->transition = transition. + result->level = level. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_533.clas.abap b/src/z2ui5_cl_smp_app_533.clas.abap index b736bb9c..c71e2bec 100644 --- a/src/z2ui5_cl_smp_app_533.clas.abap +++ b/src/z2ui5_cl_smp_app_533.clas.abap @@ -35,11 +35,14 @@ CLASS z2ui5_cl_smp_app_533 IMPLEMENTATION. ELSEIF client->check_on_event( `NEXT` ). step = step + 1. + " the rebuild is the subject: each step is a new view, and the page + " transition only plays when a view is displayed view_display( ). ELSEIF client->check_on_event( `PREVIOUS` ). step = step - 1. + " as above, and the rebuilt view is what carries transition_back view_display( abap_true ). ELSEIF client->check_on_event( `DONE` ). diff --git a/src/z2ui5_cl_smp_app_535.clas.abap b/src/z2ui5_cl_smp_app_535.clas.abap index 1026ec45..13eba675 100644 --- a/src/z2ui5_cl_smp_app_535.clas.abap +++ b/src/z2ui5_cl_smp_app_535.clas.abap @@ -50,16 +50,6 @@ CLASS z2ui5_cl_smp_app_535 IMPLEMENTATION. ENDMETHOD. - METHOD status_next. - - status = SWITCH #( status - WHEN `new` THEN `shipped` - WHEN `shipped` THEN `delayed` - ELSE `new` ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -211,4 +201,14 @@ CLASS z2ui5_cl_smp_app_535 IMPLEMENTATION. ENDMETHOD. + + METHOD status_next. + + status = SWITCH #( status + WHEN `new` THEN `shipped` + WHEN `shipped` THEN `delayed` + ELSE `new` ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_536.clas.abap b/src/z2ui5_cl_smp_app_536.clas.abap index a1510f27..61380e98 100644 --- a/src/z2ui5_cl_smp_app_536.clas.abap +++ b/src/z2ui5_cl_smp_app_536.clas.abap @@ -44,38 +44,13 @@ CLASS z2ui5_cl_smp_app_536 IMPLEMENTATION. ELSEIF client->check_on_navigated( ). view_display( ). - ELSE. + ELSEIF client->check_on_event( ). on_event( ). ENDIF. ENDMETHOD. - METHOD on_event. - - CASE abap_true. - - WHEN client->check_on_event( `STATIC` ). - client->message_toast_display( |data( "mySuperExtraData" ) = { client->get_event_arg( ) }| ). - - WHEN client->check_on_event( `BOUND` ). - client->message_toast_display( |data( "coords" ) = { client->get_event_arg( ) }| ). - - WHEN client->check_on_event( `ALL` ). - " data( ) without a key answers a plain object - an object argument - " reaches the backend as its JSON text - client->message_toast_display( |data( ) = { client->get_event_arg( ) }| ). - - WHEN client->check_on_event( `SELECT` ). - " the answer is not looked up in t_questions - it arrives as the - " custom data of the list item the user selected - answer = client->get_event_arg( ). - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -161,4 +136,29 @@ CLASS z2ui5_cl_smp_app_536 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE abap_true. + + WHEN client->check_on_event( `STATIC` ). + client->message_toast_display( |data( "mySuperExtraData" ) = { client->get_event_arg( ) }| ). + + WHEN client->check_on_event( `BOUND` ). + client->message_toast_display( |data( "coords" ) = { client->get_event_arg( ) }| ). + + WHEN client->check_on_event( `ALL` ). + " data( ) without a key answers a plain object - an object argument + " reaches the backend as its JSON text + client->message_toast_display( |data( ) = { client->get_event_arg( ) }| ). + + WHEN client->check_on_event( `SELECT` ). + " the answer is not looked up in t_questions - it arrives as the + " custom data of the list item the user selected + answer = client->get_event_arg( ). + + ENDCASE. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_537.clas.abap b/src/z2ui5_cl_smp_app_537.clas.abap index fb0862bc..e6279c33 100644 --- a/src/z2ui5_cl_smp_app_537.clas.abap +++ b/src/z2ui5_cl_smp_app_537.clas.abap @@ -50,21 +50,6 @@ CLASS z2ui5_cl_smp_app_537 IMPLEMENTATION. ENDMETHOD. - METHOD on_event_row. - - " every argument arrives as a string: the number the expression computed - " as its digits, the result of the comparison as abap_true or empty - - " so it is compared like an abap_bool, never asked IS INITIAL - DATA(is_laptop) = COND string( WHEN client->get_event_arg( 3 ) = abap_true THEN `yes` ELSE `no` ). - - client->message_box_display( |Product: { client->get_event_arg( 1 ) }\n| && - |Quantity * 10: { client->get_event_arg( 2 ) }\n| && - |Is a laptop: { is_laptop }\n| && - |Delivery (formatted in the browser): { client->get_event_arg( 4 ) }| ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -154,4 +139,19 @@ CLASS z2ui5_cl_smp_app_537 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event_row. + + " every argument arrives as a string: the number the expression computed + " as its digits, the result of the comparison as abap_true or empty - + " so it is compared like an abap_bool, never asked IS INITIAL + DATA(is_laptop) = COND string( WHEN client->get_event_arg( 3 ) = abap_true THEN `yes` ELSE `no` ). + + client->message_box_display( |Product: { client->get_event_arg( 1 ) }\n| && + |Quantity * 10: { client->get_event_arg( 2 ) }\n| && + |Is a laptop: { is_laptop }\n| && + |Delivery (formatted in the browser): { client->get_event_arg( 4 ) }| ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_538.clas.abap b/src/z2ui5_cl_smp_app_538.clas.abap index 96ce775f..cfe47e38 100644 --- a/src/z2ui5_cl_smp_app_538.clas.abap +++ b/src/z2ui5_cl_smp_app_538.clas.abap @@ -20,10 +20,10 @@ CLASS z2ui5_cl_smp_app_538 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. + METHODS view_display. METHODS on_event. METHODS on_event_paste. - METHODS view_display. + METHODS model_init. METHODS pasted_rows IMPORTING @@ -41,7 +41,8 @@ CLASS z2ui5_cl_smp_app_538 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -51,104 +52,6 @@ CLASS z2ui5_cl_smp_app_538 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - t_products = VALUE #( - ( product_id = `HT-1000` name = `Notebook Basic 15` category = `Laptops` price = `956.00` currency = `EUR` ) - ( product_id = `HT-1001` name = `Notebook Basic 17` category = `Laptops` price = `1249.00` currency = `EUR` ) - ( product_id = `HT-1010` name = `Notebook Professional 15` category = `Laptops` price = `1999.00` currency = `EUR` ) - ( product_id = `HT-1030` name = `Ergo Screen E-I` category = `Flat Screens` price = `230.00` currency = `EUR` ) - ( product_id = `HT-1040` name = `Laser Professional Eco` category = `Printers` price = `830.00` currency = `EUR` ) - ( product_id = `HT-1063` name = `Ergonomic Keyboard` category = `Keyboards` price = `14.00` currency = `EUR` ) - ( product_id = `HT-1070` name = `Photo Scan` category = `Scanners` price = `129.00` currency = `EUR` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - WHEN `COPY`. - " the CopyProvider's copy event - fired before the clipboard is written - client->message_toast_display( `Selection copied to the clipboard` ). - WHEN `PASTE`. - on_event_paste( ). - ENDCASE. - - ENDMETHOD. - - - METHOD on_event_paste. - - " the pasted rows arrive in the backend, which decides what they mean - - " here: the cells, in column order, become new products - DATA(rows) = pasted_rows( client->get_event_arg( ) ). - - LOOP AT rows INTO DATA(cells). - INSERT VALUE #( product_id = VALUE #( cells[ 1 ] OPTIONAL ) - name = VALUE #( cells[ 2 ] OPTIONAL ) - category = VALUE #( cells[ 3 ] OPTIONAL ) - price = VALUE #( cells[ 4 ] OPTIONAL ) - currency = VALUE #( cells[ 5 ] OPTIONAL ) ) INTO TABLE t_products. - ENDLOOP. - - client->message_toast_display( |{ lines( rows ) } row(s) pasted and appended| ). - - ENDMETHOD. - - - METHOD pasted_rows. - - " the paste event's data parameter is string[][], so it reaches the - " backend as JSON: [["HT-2000","Tablet"],["HT-2001","Phone"]]. One pass - " over it - an opening quote starts a cell, a closing one ends it, and a - " bracket that closes the second level ends a row. - DATA row TYPE string_table. - DATA cell TYPE string. - DATA depth TYPE i. - DATA in_string TYPE abap_bool. - DATA escaped TYPE abap_bool. - - DO strlen( json ) TIMES. - DATA(char) = substring( val = json - off = sy-index - 1 - len = 1 ). - - IF in_string = abap_true. - - IF escaped = abap_true. - cell = |{ cell }{ char }|. - escaped = abap_false. - ELSEIF char = `\`. - escaped = abap_true. - ELSEIF char = `"`. - INSERT cell INTO TABLE row. - cell = ``. - in_string = abap_false. - ELSE. - cell = |{ cell }{ char }|. - ENDIF. - - ELSEIF char = `"`. - in_string = abap_true. - ELSEIF char = `[`. - depth = depth + 1. - ELSEIF char = `]`. - - IF depth = 2. - INSERT row INTO TABLE result. - row = VALUE #( ). - ENDIF. - depth = depth - 1. - - ENDIF. - ENDDO. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -271,4 +174,100 @@ CLASS z2ui5_cl_smp_app_538 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + WHEN `COPY`. + " the CopyProvider's copy event - fired before the clipboard is written + client->message_toast_display( `Selection copied to the clipboard` ). + WHEN `PASTE`. + on_event_paste( ). + ENDCASE. + + ENDMETHOD. + + + METHOD on_event_paste. + + " the pasted rows arrive in the backend, which decides what they mean - + " here: the cells, in column order, become new products + DATA(rows) = pasted_rows( client->get_event_arg( ) ). + + LOOP AT rows INTO DATA(cells). + INSERT VALUE #( product_id = VALUE #( cells[ 1 ] OPTIONAL ) + name = VALUE #( cells[ 2 ] OPTIONAL ) + category = VALUE #( cells[ 3 ] OPTIONAL ) + price = VALUE #( cells[ 4 ] OPTIONAL ) + currency = VALUE #( cells[ 5 ] OPTIONAL ) ) INTO TABLE t_products. + ENDLOOP. + + client->message_toast_display( |{ lines( rows ) } row(s) pasted and appended| ). + + ENDMETHOD. + + + METHOD pasted_rows. + + " the paste event's data parameter is string[][], so it reaches the + " backend as JSON: [["HT-2000","Tablet"],["HT-2001","Phone"]]. One pass + " over it - an opening quote starts a cell, a closing one ends it, and a + " bracket that closes the second level ends a row. + DATA row TYPE string_table. + DATA cell TYPE string. + DATA depth TYPE i. + DATA in_string TYPE abap_bool. + DATA escaped TYPE abap_bool. + + DO strlen( json ) TIMES. + DATA(char) = substring( val = json + off = sy-index - 1 + len = 1 ). + + IF in_string = abap_true. + + IF escaped = abap_true. + cell = |{ cell }{ char }|. + escaped = abap_false. + ELSEIF char = `\`. + escaped = abap_true. + ELSEIF char = `"`. + INSERT cell INTO TABLE row. + cell = ``. + in_string = abap_false. + ELSE. + cell = |{ cell }{ char }|. + ENDIF. + + ELSEIF char = `"`. + in_string = abap_true. + ELSEIF char = `[`. + depth = depth + 1. + ELSEIF char = `]`. + + IF depth = 2. + INSERT row INTO TABLE result. + row = VALUE #( ). + ENDIF. + depth = depth - 1. + + ENDIF. + ENDDO. + + ENDMETHOD. + + + METHOD model_init. + + t_products = VALUE #( + ( product_id = `HT-1000` name = `Notebook Basic 15` category = `Laptops` price = `956.00` currency = `EUR` ) + ( product_id = `HT-1001` name = `Notebook Basic 17` category = `Laptops` price = `1249.00` currency = `EUR` ) + ( product_id = `HT-1010` name = `Notebook Professional 15` category = `Laptops` price = `1999.00` currency = `EUR` ) + ( product_id = `HT-1030` name = `Ergo Screen E-I` category = `Flat Screens` price = `230.00` currency = `EUR` ) + ( product_id = `HT-1040` name = `Laser Professional Eco` category = `Printers` price = `830.00` currency = `EUR` ) + ( product_id = `HT-1063` name = `Ergonomic Keyboard` category = `Keyboards` price = `14.00` currency = `EUR` ) + ( product_id = `HT-1070` name = `Photo Scan` category = `Scanners` price = `129.00` currency = `EUR` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_539.clas.abap b/src/z2ui5_cl_smp_app_539.clas.abap index 9adb0207..f47ca781 100644 --- a/src/z2ui5_cl_smp_app_539.clas.abap +++ b/src/z2ui5_cl_smp_app_539.clas.abap @@ -27,9 +27,9 @@ CLASS z2ui5_cl_smp_app_539 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -41,7 +41,8 @@ CLASS z2ui5_cl_smp_app_539 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `INSPECT` ). @@ -51,40 +52,6 @@ CLASS z2ui5_cl_smp_app_539 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - copy_preference = `Cells`. - t_products = VALUE #( - ( product_id = `HT-1000` name = `Notebook Basic 15` supplier = `Very Best Screens` quantity = `10` uom = `PC` price = `956.00` currency = `EUR` ) - ( product_id = `HT-1001` name = `Notebook Basic 17` supplier = `Very Best Screens` quantity = `20` uom = `PC` price = `1249.00` currency = `EUR` ) - ( product_id = `HT-1007` name = `ITelO Vault` supplier = `Technocom` quantity = `15` uom = `PC` price = `299.00` currency = `EUR` ) - ( product_id = `HT-1010` name = `Notebook Professional 15` supplier = `Very Best Screens` quantity = `16` uom = `PC` price = `1999.00` currency = `EUR` ) - ( product_id = `HT-1063` name = `Ergonomic Keyboard` supplier = `Titanium` quantity = `50` uom = `PC` price = `14.00` currency = `EUR` ) - ( product_id = `HT-1070` name = `Photo Scan` supplier = `Red Point Stores` quantity = `8` uom = `PC` price = `129.00` currency = `EUR` ) ). - - view_display( ). - - ENDMETHOD. - - - METHOD on_event. - - " the clipboard's text format is a spreadsheet's: a tab between two - " cells, a line break between two rows - SPLIT clipboard_text AT cl_abap_char_utilities=>newline INTO TABLE DATA(t_line). - DELETE t_line WHERE table_line IS INITIAL. - - DATA(cells) = 0. - LOOP AT t_line INTO DATA(line). - SPLIT line AT cl_abap_char_utilities=>horizontal_tab INTO TABLE DATA(t_cell). - cells = cells + lines( t_cell ). - ENDLOOP. - - client->message_toast_display( |{ lines( t_line ) } row(s) with { cells } cell(s) arrived in the backend| ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -220,4 +187,36 @@ CLASS z2ui5_cl_smp_app_539 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + " the clipboard's text format is a spreadsheet's: a tab between two + " cells, a line break between two rows + SPLIT clipboard_text AT cl_abap_char_utilities=>newline INTO TABLE DATA(t_line). + DELETE t_line WHERE table_line IS INITIAL. + + DATA(cells) = 0. + LOOP AT t_line INTO DATA(line). + SPLIT line AT cl_abap_char_utilities=>horizontal_tab INTO TABLE DATA(t_cell). + cells = cells + lines( t_cell ). + ENDLOOP. + + client->message_toast_display( |{ lines( t_line ) } row(s) with { cells } cell(s) arrived in the backend| ). + + ENDMETHOD. + + + METHOD model_init. + + copy_preference = `Cells`. + t_products = VALUE #( + ( product_id = `HT-1000` name = `Notebook Basic 15` supplier = `Very Best Screens` quantity = `10` uom = `PC` price = `956.00` currency = `EUR` ) + ( product_id = `HT-1001` name = `Notebook Basic 17` supplier = `Very Best Screens` quantity = `20` uom = `PC` price = `1249.00` currency = `EUR` ) + ( product_id = `HT-1007` name = `ITelO Vault` supplier = `Technocom` quantity = `15` uom = `PC` price = `299.00` currency = `EUR` ) + ( product_id = `HT-1010` name = `Notebook Professional 15` supplier = `Very Best Screens` quantity = `16` uom = `PC` price = `1999.00` currency = `EUR` ) + ( product_id = `HT-1063` name = `Ergonomic Keyboard` supplier = `Titanium` quantity = `50` uom = `PC` price = `14.00` currency = `EUR` ) + ( product_id = `HT-1070` name = `Photo Scan` supplier = `Red Point Stores` quantity = `8` uom = `PC` price = `129.00` currency = `EUR` ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_540.clas.abap b/src/z2ui5_cl_smp_app_540.clas.abap index 7beb3829..9e6a2a1d 100644 --- a/src/z2ui5_cl_smp_app_540.clas.abap +++ b/src/z2ui5_cl_smp_app_540.clas.abap @@ -25,8 +25,8 @@ CLASS z2ui5_cl_smp_app_540 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_event. METHODS view_display. + METHODS on_event. METHODS chat_reset. METHODS prompt_send IMPORTING @@ -76,6 +76,88 @@ CLASS z2ui5_cl_smp_app_540 IMPLEMENTATION. ENDMETHOD. + METHOD view_display. + + DATA t_prompts TYPE STANDARD TABLE OF string WITH EMPTY KEY. + + t_prompts = VALUE #( ( `What can you do?` ) + ( `What is abap2UI5?` ) + ( `How do I plug in a real LLM?` ) + ( `How many messages so far?` ) + ( `What did I ask first?` ) ). + + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - AI - Chat Assistant with FeedInput and FeedListItem` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->ele( `headerContent` + )->tag( `Button` + )->a( n = `text` v = `Clear Chat` + )->a( n = `icon` v = `sap-icon://delete` + )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| + )->a( n = `press` v = client->_event( `CLEAR` ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `A chat assistant screen: the question shows at once, the feed stays busy until the answer ` && + `arrives in a second roundtrip. The answer comes from one method that receives the whole conversation - ` && + `here a rule-based stand-in, in a real app the call to your language model.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + DATA(content) = page->ele( `VBox` + )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). + + " the typed text leaves the browser as the event argument - the + " FeedInput clears itself after post, so its value is not bound + content->tag( `FeedInput` + )->a( n = `placeholder` v = `Ask the assistant something...` + )->a( n = `icon` v = `sap-icon://customer` + )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| + )->a( n = `post` v = client->_event( val = `POST` + arg = `${$parameters>/value}` ) ). + + DATA(suggestions) = content->ele( `HBox` + )->a( n = `wrap` v = `Wrap` + )->a( n = `class` v = `sapUiSmallMarginTop` ). + LOOP AT t_prompts INTO DATA(prompt). + suggestions->tag( `Button` + )->a( n = `text` t = prompt + )->a( n = `class` v = `sapUiTinyMarginEnd sapUiTinyMarginBottom` + )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| + )->a( n = `press` v = client->_event( val = `SUGGEST` + arg = prompt ) ). + ENDLOOP. + + content->ele( `List` + )->a( n = `items` v = client->_bind( t_messages ) + )->a( n = `busy` v = client->_bind( busy ) + )->a( n = `busyIndicatorDelay` v = `0` + )->a( n = `showSeparators` v = `Inner` + )->a( n = `noDataText` v = `No messages yet.` + )->ele( `items` + )->tag( `FeedListItem` + )->a( n = `sender` v = `{SENDER}` + )->a( n = `text` v = `{TEXT_HTML}` + )->a( n = `icon` v = `{ICON}` + )->a( n = `info` v = `{INFO}` + )->a( n = `senderActive` b = abap_false + )->a( n = `iconActive` b = abap_false ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + METHOD on_event. CASE client->get_event( ). @@ -219,86 +301,4 @@ CLASS z2ui5_cl_smp_app_540 IMPLEMENTATION. ENDMETHOD. - - METHOD view_display. - - DATA t_prompts TYPE STANDARD TABLE OF string WITH EMPTY KEY. - - t_prompts = VALUE #( ( `What can you do?` ) - ( `What is abap2UI5?` ) - ( `How do I plug in a real LLM?` ) - ( `How many messages so far?` ) - ( `What did I ask first?` ) ). - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - AI - Chat Assistant with FeedInput and FeedListItem` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->ele( `headerContent` - )->tag( `Button` - )->a( n = `text` v = `Clear Chat` - )->a( n = `icon` v = `sap-icon://delete` - )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| - )->a( n = `press` v = client->_event( `CLEAR` ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `A chat assistant screen: the question shows at once, the feed stays busy until the answer ` && - `arrives in a second roundtrip. The answer comes from one method that receives the whole conversation - ` && - `here a rule-based stand-in, in a real app the call to your language model.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - DATA(content) = page->ele( `VBox` - )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). - - " the typed text leaves the browser as the event argument - the - " FeedInput clears itself after post, so its value is not bound - content->tag( `FeedInput` - )->a( n = `placeholder` v = `Ask the assistant something...` - )->a( n = `icon` v = `sap-icon://customer` - )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| - )->a( n = `post` v = client->_event( val = `POST` - arg = `${$parameters>/value}` ) ). - - DATA(suggestions) = content->ele( `HBox` - )->a( n = `wrap` v = `Wrap` - )->a( n = `class` v = `sapUiSmallMarginTop` ). - LOOP AT t_prompts INTO DATA(prompt). - suggestions->tag( `Button` - )->a( n = `text` t = prompt - )->a( n = `class` v = `sapUiTinyMarginEnd sapUiTinyMarginBottom` - )->a( n = `enabled` v = |\{= !${ client->_bind( busy ) } \}| - )->a( n = `press` v = client->_event( val = `SUGGEST` - arg = prompt ) ). - ENDLOOP. - - content->ele( `List` - )->a( n = `items` v = client->_bind( t_messages ) - )->a( n = `busy` v = client->_bind( busy ) - )->a( n = `busyIndicatorDelay` v = `0` - )->a( n = `showSeparators` v = `Inner` - )->a( n = `noDataText` v = `No messages yet.` - )->ele( `items` - )->tag( `FeedListItem` - )->a( n = `sender` v = `{SENDER}` - )->a( n = `text` v = `{TEXT_HTML}` - )->a( n = `icon` v = `{ICON}` - )->a( n = `info` v = `{INFO}` - )->a( n = `senderActive` b = abap_false - )->a( n = `iconActive` b = abap_false ). - - client->view_display( view->stringify( ) ). - - ENDMETHOD. - ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_541.clas.abap b/src/z2ui5_cl_smp_app_541.clas.abap index 71624d25..ee66c3c0 100644 --- a/src/z2ui5_cl_smp_app_541.clas.abap +++ b/src/z2ui5_cl_smp_app_541.clas.abap @@ -33,10 +33,10 @@ CLASS z2ui5_cl_smp_app_541 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. + METHODS view_display. METHODS on_event. METHODS on_event_summarize. - METHODS view_display. + METHODS model_init. "! The provider seam: the rows in, the explanation out. "! @parameter t_rows | the rows to explain @@ -57,7 +57,8 @@ CLASS z2ui5_cl_smp_app_541 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -67,27 +68,129 @@ CLASS z2ui5_cl_smp_app_541 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. + METHOD view_display. - t_orders = VALUE #( - ( id = `4711` customer = `Bike Corner` region = `North` status = `Delivered` amount = 1200 ) - ( id = `4712` customer = `City Cycles` region = `South` status = `Open` amount = 860 ) - ( id = `4713` customer = `Mountain Outfit` region = `North` status = `Overdue` amount = 2400 ) - ( id = `4714` customer = `Velo Point` region = `West` status = `Delivered` amount = 640 ) - ( id = `4715` customer = `Bike Corner` region = `North` status = `Open` amount = 1500 ) - ( id = `4716` customer = `Urban Wheels` region = `East` status = `Delivered` amount = 9800 ) - ( id = `4717` customer = `City Cycles` region = `South` status = `Overdue` amount = 720 ) - ( id = `4718` customer = `Trail Masters` region = `West` status = `Delivered` amount = 1900 ) - ( id = `4719` customer = `Velo Point` region = `West` status = `Open` amount = 1100 ) - ( id = `4720` customer = `Mountain Outfit` region = `North` status = `Delivered` amount = 1350 ) ). + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` + )->a( n = `xmlns:layout` v = `sap.ui.layout` ). - LOOP AT t_orders REFERENCE INTO DATA(order). - order->state = SWITCH #( order->status WHEN `Delivered` THEN `Success` - WHEN `Overdue` THEN `Error` - ELSE `Warning` ). - ENDLOOP. + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - AI - Explain This Data in a DynamicSideContent Panel` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Explain This Data opens a panel beside the table and fills it with a short explanation ` && + `of the selected rows, or of all of them. One method turns rows into findings - here a deterministic ` && + `summary, in a real app the call to your language model.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + " on a narrow screen the panel falls below the table instead of hiding + DATA(side_content) = page->ele( n = `DynamicSideContent` ns = `layout` + )->a( n = `showSideContent` v = client->_bind( panel_visible ) + )->a( n = `sideContentVisibility` v = `AlwaysShow` + )->a( n = `sideContentFallDown` v = `BelowM` + )->a( n = `containerQuery` b = abap_true ). + + DATA(tab) = side_content->ele( n = `mainContent` ns = `layout` + )->ele( `Table` + )->a( n = `items` v = client->_bind( t_orders ) + )->a( n = `mode` v = `MultiSelect` ). + + tab->ele( `headerToolbar` + )->ele( `OverflowToolbar` + )->tag( `Title` + )->a( n = `text` v = `Sales Orders` + )->tag( `ToolbarSpacer` + )->tag( `Button` + )->a( n = `text` v = `Explain This Data` + )->a( n = `icon` v = `sap-icon://hint` + )->a( n = `type` v = `Emphasized` + )->a( n = `press` v = client->_event( `EXPLAIN` ) ). + + DATA(columns) = tab->ele( `columns` ). + columns->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `Order` ). + columns->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `Customer` ). + columns->ele( `Column` + )->a( n = `minScreenWidth` v = `Tablet` + )->a( n = `demandPopin` b = abap_true + )->tag( `Text` + )->a( n = `text` v = `Region` ). + columns->ele( `Column` + )->a( n = `minScreenWidth` v = `Tablet` + )->a( n = `demandPopin` b = abap_true + )->tag( `Text` + )->a( n = `text` v = `Status` ). + columns->ele( `Column` + )->a( n = `hAlign` v = `End` + )->tag( `Text` + )->a( n = `text` v = `Amount` ). + + DATA(cells) = tab->ele( `items` + )->ele( `ColumnListItem` + )->a( n = `selected` v = `{SELECTED}` + )->ele( `cells` ). + cells->tag( `Text` + )->a( n = `text` v = `{ID}` ). + cells->tag( `Text` + )->a( n = `text` v = `{CUSTOMER}` ). + cells->tag( `Text` + )->a( n = `text` v = `{REGION}` ). + cells->tag( `ObjectStatus` + )->a( n = `text` v = `{STATUS}` + )->a( n = `state` v = `{STATE}` ). + cells->tag( `ObjectNumber` + )->a( n = `number` v = `{AMOUNT}` + )->a( n = `unit` v = `EUR` ). + + DATA(panel) = side_content->ele( n = `sideContent` ns = `layout` + )->ele( `VBox` + )->a( n = `busy` v = client->_bind( busy ) + )->a( n = `busyIndicatorDelay` v = `0` + )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). + + panel->ele( `Toolbar` + )->a( n = `style` v = `Clear` + )->tag( `Title` + )->a( n = `text` v = `Explanation` + )->tag( `ToolbarSpacer` + )->tag( `Button` + )->a( n = `icon` v = `sap-icon://decline` + )->a( n = `tooltip` v = `Close` + )->a( n = `type` v = `Transparent` + )->a( n = `press` v = client->_event( `CLOSE` ) ). + + panel->tag( `Text` + )->a( n = `text` v = client->_bind( headline ) + )->a( n = `class` v = `sapUiTinyMarginBottom` ). + + panel->ele( `List` + )->a( n = `items` v = client->_bind( t_findings ) + )->a( n = `showSeparators` v = `Inner` + )->a( n = `noDataText` v = `The explanation is on its way.` + )->ele( `items` + )->tag( `StandardListItem` + )->a( n = `title` v = `{TITLE}` + )->a( n = `description` v = `{DESCRIPTION}` + )->a( n = `icon` v = `{ICON}` + )->a( n = `wrapping` b = abap_true ). + + panel->tag( `Text` + )->a( n = `text` v = `Written by the built-in rule-based provider - no language model involved.` + )->a( n = `class` v = `sapUiTinyMarginTop` ). - view_display( ). + client->view_display( view->stringify( ) ). ENDMETHOD. @@ -255,129 +358,25 @@ CLASS z2ui5_cl_smp_app_541 IMPLEMENTATION. ENDMETHOD. - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` - )->a( n = `xmlns:layout` v = `sap.ui.layout` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - AI - Explain This Data in a DynamicSideContent Panel` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Explain This Data opens a panel beside the table and fills it with a short explanation ` && - `of the selected rows, or of all of them. One method turns rows into findings - here a deterministic ` && - `summary, in a real app the call to your language model.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - " on a narrow screen the panel falls below the table instead of hiding - DATA(side_content) = page->ele( n = `DynamicSideContent` ns = `layout` - )->a( n = `showSideContent` v = client->_bind( panel_visible ) - )->a( n = `sideContentVisibility` v = `AlwaysShow` - )->a( n = `sideContentFallDown` v = `BelowM` - )->a( n = `containerQuery` b = abap_true ). - - DATA(tab) = side_content->ele( n = `mainContent` ns = `layout` - )->ele( `Table` - )->a( n = `items` v = client->_bind( t_orders ) - )->a( n = `mode` v = `MultiSelect` ). - - tab->ele( `headerToolbar` - )->ele( `OverflowToolbar` - )->tag( `Title` - )->a( n = `text` v = `Sales Orders` - )->tag( `ToolbarSpacer` - )->tag( `Button` - )->a( n = `text` v = `Explain This Data` - )->a( n = `icon` v = `sap-icon://hint` - )->a( n = `type` v = `Emphasized` - )->a( n = `press` v = client->_event( `EXPLAIN` ) ). - - DATA(columns) = tab->ele( `columns` ). - columns->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `Order` ). - columns->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `Customer` ). - columns->ele( `Column` - )->a( n = `minScreenWidth` v = `Tablet` - )->a( n = `demandPopin` b = abap_true - )->tag( `Text` - )->a( n = `text` v = `Region` ). - columns->ele( `Column` - )->a( n = `minScreenWidth` v = `Tablet` - )->a( n = `demandPopin` b = abap_true - )->tag( `Text` - )->a( n = `text` v = `Status` ). - columns->ele( `Column` - )->a( n = `hAlign` v = `End` - )->tag( `Text` - )->a( n = `text` v = `Amount` ). - - DATA(cells) = tab->ele( `items` - )->ele( `ColumnListItem` - )->a( n = `selected` v = `{SELECTED}` - )->ele( `cells` ). - cells->tag( `Text` - )->a( n = `text` v = `{ID}` ). - cells->tag( `Text` - )->a( n = `text` v = `{CUSTOMER}` ). - cells->tag( `Text` - )->a( n = `text` v = `{REGION}` ). - cells->tag( `ObjectStatus` - )->a( n = `text` v = `{STATUS}` - )->a( n = `state` v = `{STATE}` ). - cells->tag( `ObjectNumber` - )->a( n = `number` v = `{AMOUNT}` - )->a( n = `unit` v = `EUR` ). - - DATA(panel) = side_content->ele( n = `sideContent` ns = `layout` - )->ele( `VBox` - )->a( n = `busy` v = client->_bind( busy ) - )->a( n = `busyIndicatorDelay` v = `0` - )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). + METHOD model_init. - panel->ele( `Toolbar` - )->a( n = `style` v = `Clear` - )->tag( `Title` - )->a( n = `text` v = `Explanation` - )->tag( `ToolbarSpacer` - )->tag( `Button` - )->a( n = `icon` v = `sap-icon://decline` - )->a( n = `tooltip` v = `Close` - )->a( n = `type` v = `Transparent` - )->a( n = `press` v = client->_event( `CLOSE` ) ). - - panel->tag( `Text` - )->a( n = `text` v = client->_bind( headline ) - )->a( n = `class` v = `sapUiTinyMarginBottom` ). - - panel->ele( `List` - )->a( n = `items` v = client->_bind( t_findings ) - )->a( n = `showSeparators` v = `Inner` - )->a( n = `noDataText` v = `The explanation is on its way.` - )->ele( `items` - )->tag( `StandardListItem` - )->a( n = `title` v = `{TITLE}` - )->a( n = `description` v = `{DESCRIPTION}` - )->a( n = `icon` v = `{ICON}` - )->a( n = `wrapping` b = abap_true ). - - panel->tag( `Text` - )->a( n = `text` v = `Written by the built-in rule-based provider - no language model involved.` - )->a( n = `class` v = `sapUiTinyMarginTop` ). + t_orders = VALUE #( + ( id = `4711` customer = `Bike Corner` region = `North` status = `Delivered` amount = 1200 ) + ( id = `4712` customer = `City Cycles` region = `South` status = `Open` amount = 860 ) + ( id = `4713` customer = `Mountain Outfit` region = `North` status = `Overdue` amount = 2400 ) + ( id = `4714` customer = `Velo Point` region = `West` status = `Delivered` amount = 640 ) + ( id = `4715` customer = `Bike Corner` region = `North` status = `Open` amount = 1500 ) + ( id = `4716` customer = `Urban Wheels` region = `East` status = `Delivered` amount = 9800 ) + ( id = `4717` customer = `City Cycles` region = `South` status = `Overdue` amount = 720 ) + ( id = `4718` customer = `Trail Masters` region = `West` status = `Delivered` amount = 1900 ) + ( id = `4719` customer = `Velo Point` region = `West` status = `Open` amount = 1100 ) + ( id = `4720` customer = `Mountain Outfit` region = `North` status = `Delivered` amount = 1350 ) ). - client->view_display( view->stringify( ) ). + LOOP AT t_orders REFERENCE INTO DATA(order). + order->state = SWITCH #( order->status WHEN `Delivered` THEN `Success` + WHEN `Overdue` THEN `Error` + ELSE `Warning` ). + ENDLOOP. ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_542.clas.abap b/src/z2ui5_cl_smp_app_542.clas.abap index 7d2b2f48..266e31be 100644 --- a/src/z2ui5_cl_smp_app_542.clas.abap +++ b/src/z2ui5_cl_smp_app_542.clas.abap @@ -18,9 +18,9 @@ CLASS z2ui5_cl_smp_app_542 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. + METHODS model_init. METHODS csv_build RETURNING @@ -65,7 +65,8 @@ CLASS z2ui5_cl_smp_app_542 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( ). @@ -75,18 +76,92 @@ CLASS z2ui5_cl_smp_app_542 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. + METHOD view_display. - " the second and third name hold the separator and quotes on purpose - - " the CSV has to escape them - t_products = VALUE #( - ( id = `P-001` name = `Notebook Basic 15` quantity = 3 price = `956.00` ) - ( id = `P-002` name = `Cable "USB-C"; 2 m` quantity = 25 price = `9.90` ) - ( id = `P-003` name = `Monitor 27"` quantity = 4 price = `289.00` ) - ( id = `P-004` name = `Wireless Mouse` quantity = 12 price = `24.50` ) ). - note = `Stock list exported from abap2UI5.`. + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). + + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - File - ZIP and CSV Download with cl_abap_zip` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Download CSV turns the table into a CSV file in plain ABAP - separator ;, values with a ` && + `separator or a quote enclosed in quotes, CRLF line ends - encoded as UTF-8. Download ZIP packs that CSV ` && + `and the note as note.txt into one archive with cl_abap_zip. Both reach the browser via download_b64_file.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + DATA(table) = page->ele( `Table` + )->a( n = `items` v = client->_bind( t_products ) + )->a( n = `class` v = `sapUiSmallMargin` ). + + table->ele( `headerToolbar` + )->ele( `OverflowToolbar` + )->tag( `Title` + )->a( n = `text` v = `Products - edit a cell, then download` ). + + table->ele( `columns` + )->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `ID` + )->end( + )->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `Name` + )->end( + )->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `Quantity` + )->end( + )->ele( `Column` + )->tag( `Text` + )->a( n = `text` v = `Price` ). + + table->ele( `items` + )->ele( `ColumnListItem` + )->ele( `cells` + )->tag( `Input` + )->a( n = `value` v = `{ID}` + )->tag( `Input` + )->a( n = `value` v = `{NAME}` + )->tag( `Input` + )->a( n = `value` v = `{QUANTITY}` + )->tag( `Input` + )->a( n = `value` v = `{PRICE}` ). + + page->ele( `VBox` + )->a( n = `class` v = `sapUiSmallMargin` + )->tag( `Label` + )->a( n = `text` v = `Note (note.txt in the ZIP)` + )->a( n = `labelFor` v = `note` + )->tag( `TextArea` + )->a( n = `id` v = `note` + )->a( n = `value` v = client->_bind( note ) + )->a( n = `rows` v = `3` + )->a( n = `width` v = `100%` ). + + page->ele( `footer` + )->ele( `OverflowToolbar` + )->tag( `ToolbarSpacer` + )->tag( `Button` + )->a( n = `text` v = `Download CSV` + )->a( n = `icon` v = `sap-icon://download` + )->a( n = `press` v = client->_event( `DOWNLOAD_CSV` ) + )->tag( `Button` + )->a( n = `text` v = `Download ZIP` + )->a( n = `icon` v = `sap-icon://attachment-zip-file` + )->a( n = `type` v = `Emphasized` + )->a( n = `press` v = client->_event( `DOWNLOAD_ZIP` ) ). - view_display( ). + client->view_display( view->stringify( ) ). ENDMETHOD. @@ -210,92 +285,16 @@ CLASS z2ui5_cl_smp_app_542 IMPLEMENTATION. ENDMETHOD. - METHOD view_display. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ). - - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - File - ZIP and CSV Download with cl_abap_zip` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Download CSV turns the table into a CSV file in plain ABAP - separator ;, values with a ` && - `separator or a quote enclosed in quotes, CRLF line ends - encoded as UTF-8. Download ZIP packs that CSV ` && - `and the note as note.txt into one archive with cl_abap_zip. Both reach the browser via download_b64_file.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - DATA(table) = page->ele( `Table` - )->a( n = `items` v = client->_bind( t_products ) - )->a( n = `class` v = `sapUiSmallMargin` ). - - table->ele( `headerToolbar` - )->ele( `OverflowToolbar` - )->tag( `Title` - )->a( n = `text` v = `Products - edit a cell, then download` ). - - table->ele( `columns` - )->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `ID` - )->end( - )->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `Name` - )->end( - )->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `Quantity` - )->end( - )->ele( `Column` - )->tag( `Text` - )->a( n = `text` v = `Price` ). - - table->ele( `items` - )->ele( `ColumnListItem` - )->ele( `cells` - )->tag( `Input` - )->a( n = `value` v = `{ID}` - )->tag( `Input` - )->a( n = `value` v = `{NAME}` - )->tag( `Input` - )->a( n = `value` v = `{QUANTITY}` - )->tag( `Input` - )->a( n = `value` v = `{PRICE}` ). - - page->ele( `VBox` - )->a( n = `class` v = `sapUiSmallMargin` - )->tag( `Label` - )->a( n = `text` v = `Note (note.txt in the ZIP)` - )->a( n = `labelFor` v = `note` - )->tag( `TextArea` - )->a( n = `id` v = `note` - )->a( n = `value` v = client->_bind( note ) - )->a( n = `rows` v = `3` - )->a( n = `width` v = `100%` ). + METHOD model_init. - page->ele( `footer` - )->ele( `OverflowToolbar` - )->tag( `ToolbarSpacer` - )->tag( `Button` - )->a( n = `text` v = `Download CSV` - )->a( n = `icon` v = `sap-icon://download` - )->a( n = `press` v = client->_event( `DOWNLOAD_CSV` ) - )->tag( `Button` - )->a( n = `text` v = `Download ZIP` - )->a( n = `icon` v = `sap-icon://attachment-zip-file` - )->a( n = `type` v = `Emphasized` - )->a( n = `press` v = client->_event( `DOWNLOAD_ZIP` ) ). - - client->view_display( view->stringify( ) ). + " the second and third name hold the separator and quotes on purpose - + " the CSV has to escape them + t_products = VALUE #( + ( id = `P-001` name = `Notebook Basic 15` quantity = 3 price = `956.00` ) + ( id = `P-002` name = `Cable "USB-C"; 2 m` quantity = 25 price = `9.90` ) + ( id = `P-003` name = `Monitor 27"` quantity = 4 price = `289.00` ) + ( id = `P-004` name = `Wireless Mouse` quantity = 12 price = `24.50` ) ). + note = `Stock list exported from abap2UI5.`. ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_543.clas.abap b/src/z2ui5_cl_smp_app_543.clas.abap index 9b7510b6..f52e8349 100644 --- a/src/z2ui5_cl_smp_app_543.clas.abap +++ b/src/z2ui5_cl_smp_app_543.clas.abap @@ -21,8 +21,8 @@ CLASS z2ui5_cl_smp_app_543 DEFINITION PUBLIC. DATA client TYPE REF TO z2ui5_if_client. METHODS on_init. - METHODS on_event. METHODS view_display. + METHODS on_event. PRIVATE SECTION. ENDCLASS. @@ -45,49 +45,6 @@ CLASS z2ui5_cl_smp_app_543 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - bin = `A-01-03`. - view_display( ). - - " SAVE is the one event of this app that may wait for the network: while - " the backend cannot be reached it is kept in the browser - with what was - " typed - and sent once it can, in the order it was made. &1 in the toast - " is how many wait. Every other event (CLEAR here) fails as usual. - client->follow_up_action( val = client->cs_event-offline_queue - t_arg = VALUE #( ( `Saved offline - &1 waiting, sent when the network is back` ) - ( `SAVE` ) ) ). - - ENDMETHOD. - - - METHOD on_event. - - CASE client->get_event( ). - - WHEN `SAVE`. - " a queued SAVE arrives here late, but like any other: the app checks - " what it would check anyway - IF material IS INITIAL OR quantity IS INITIAL. - client->message_box_display( text = `Material and quantity are required.` type = `error` ). - RETURN. - ENDIF. - INSERT VALUE #( pos = lines( t_counts ) + 1 - bin = bin - material = material - quantity = quantity ) INTO TABLE t_counts. - CLEAR material. - CLEAR quantity. - client->message_toast_display( |Counted - { lines( t_counts ) } entries| ). - - WHEN `CLEAR`. - CLEAR t_counts. - - ENDCASE. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -180,4 +137,47 @@ CLASS z2ui5_cl_smp_app_543 IMPLEMENTATION. ENDMETHOD. + + METHOD on_event. + + CASE client->get_event( ). + + WHEN `SAVE`. + " a queued SAVE arrives here late, but like any other: the app checks + " what it would check anyway + IF material IS INITIAL OR quantity IS INITIAL. + client->message_box_display( text = `Material and quantity are required.` type = `error` ). + RETURN. + ENDIF. + INSERT VALUE #( pos = lines( t_counts ) + 1 + bin = bin + material = material + quantity = quantity ) INTO TABLE t_counts. + CLEAR material. + CLEAR quantity. + client->message_toast_display( |Counted - { lines( t_counts ) } entries| ). + + WHEN `CLEAR`. + CLEAR t_counts. + + ENDCASE. + + ENDMETHOD. + + + METHOD on_init. + + bin = `A-01-03`. + view_display( ). + + " SAVE is the one event of this app that may wait for the network: while + " the backend cannot be reached it is kept in the browser - with what was + " typed - and sent once it can, in the order it was made. &1 in the toast + " is how many wait. Every other event (CLEAR here) fails as usual. + client->follow_up_action( val = client->cs_event-offline_queue + t_arg = VALUE #( ( `Saved offline - &1 waiting, sent when the network is back` ) + ( `SAVE` ) ) ). + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_544.clas.abap b/src/z2ui5_cl_smp_app_544.clas.abap index 59600644..8ff0941f 100644 --- a/src/z2ui5_cl_smp_app_544.clas.abap +++ b/src/z2ui5_cl_smp_app_544.clas.abap @@ -71,8 +71,8 @@ CLASS z2ui5_cl_smp_app_544 DEFINITION PUBLIC. DATA t_unit_fields TYPE string_table. DATA kind_column TYPE string. - METHODS on_init. METHODS view_display. + METHODS model_init. METHODS rows_group. "! Adds the row to the sum of its units on the given level @@ -110,7 +110,8 @@ CLASS z2ui5_cl_smp_app_544 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `GROUP` ). @@ -120,31 +121,115 @@ CLASS z2ui5_cl_smp_app_544 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. + METHOD view_display. - t_sales = VALUE #( - ( region = `EMEA` country = `Germany` category = `Hardware` product = `Notebook` quantity = 10 amount = `12000.00` currency = `EUR` ) - ( region = `APAC` country = `Japan` category = `Software` product = `Antivirus` quantity = 50 amount = `2500.00` currency = `USD` ) - ( region = `EMEA` country = `Switzerland` category = `Hardware` product = `Monitor` quantity = 8 amount = `2400.00` currency = `CHF` ) - ( region = `Americas` country = `USA` category = `Hardware` product = `Server` quantity = 2 amount = `18000.00` currency = `USD` ) - ( region = `EMEA` country = `Germany` category = `Software` product = `Office Suite` quantity = 25 amount = `4500.00` currency = `EUR` ) - ( region = `Americas` country = `Canada` category = `Hardware` product = `Monitor` quantity = 5 amount = `1500.00` currency = `CAD` ) - ( region = `EMEA` country = `France` category = `Hardware` product = `Notebook` quantity = 6 amount = `7200.00` currency = `EUR` ) - ( region = `APAC` country = `Australia` category = `Services` product = `Training` quantity = 2 amount = `3000.00` currency = `USD` ) - ( region = `EMEA` country = `Switzerland` category = `Services` product = `Installation` quantity = 3 amount = `1350.00` currency = `CHF` ) - ( region = `Americas` country = `USA` category = `Services` product = `Support Contract` quantity = 12 amount = `6000.00` currency = `USD` ) - ( region = `APAC` country = `Japan` category = `Hardware` product = `Notebook` quantity = 4 amount = `4800.00` currency = `USD` ) - ( region = `Americas` country = `Canada` category = `Software` product = `Office Suite` quantity = 40 amount = `7600.00` currency = `CAD` ) ). + DATA t_layout TYPE STANDARD TABLE OF ty_s_column WITH EMPTY KEY. - " the order of this list is the order of the groups, the first ticked - " column outermost - t_columns = VALUE #( - ( name = `REGION` label = `Region` selected = abap_true ) + DATA(view) = z2ui5_cl_ui5_view_builder=>factory( + )->ele( n = `View` ns = `mvc` + )->a( n = `displayBlock` v = `true` + )->a( n = `height` v = `100%` + )->a( n = `xmlns` v = `sap.m` + )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` + )->a( n = `xmlns:core` v = `sap.ui.core` + )->a( n = `xmlns:table` v = `sap.ui.table` ). + DATA(page) = view->ele( `Shell` + )->ele( `Page` + )->a( n = `title` v = `abap2UI5 - Grid Table - Subtotals and Grand Total per Currency` + )->a( n = `showNavButton` b = client->check_app_prev_stack( ) + )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). + + page->tag( `MessageStrip` + )->a( n = `text` v = `Tick the columns to group by: the backend sorts the rows by them, inserts a subtotal row after ` && + `each group and a grand total at the end. Amounts are summed per currency, so a group in two currencies ` && + `gets two subtotal rows. Each cell writes its row kind into the DOM (CustomData writeToDom), and the ` && + `style below colours the whole row from it.` + )->a( n = `type` v = `Information` + )->a( n = `showIcon` b = abap_true + )->a( n = `class` v = `sapUiSmallMargin` ). + + " a grid table row takes no CSS class from its data, so every cell carries + " the row kind as data-rowkind, and :has( ) lifts it to the row. The + " theme parameters are CSS variables only on newer releases - the colour + " after the comma is the fallback for the ones without + page->tag( n = `HTML` ns = `core` + )->a( n = `content` v = `` ). + + DATA(table) = page->ele( n = `Table` ns = `table` + )->a( n = `rows` v = client->_bind( t_rows ) + )->a( n = `selectionMode` v = `None` + )->a( n = `visibleRowCount` v = client->_bind( visible_rows ) + )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). + + table->ele( n = `extension` ns = `table` + )->ele( `OverflowToolbar` + )->tag( `Title` + )->a( n = `text` v = `Sales` + )->tag( `ToolbarSpacer` + )->tag( `Label` + )->a( n = `text` v = `Group by:` + )->ele( `HBox` + )->a( n = `items` v = client->_bind( t_columns ) + )->tag( `CheckBox` + )->a( n = `text` v = `{LABEL}` + )->a( n = `selected` v = `{SELECTED}` + )->a( n = `select` v = client->_event( `GROUP` ) ). + + " the bar at the start of the row, in the colour of the row + table->ele( n = `rowSettingsTemplate` ns = `table` + )->tag( n = `RowSettings` ns = `table` + )->a( n = `highlight` v = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'Warning' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'Information' : 'None' \}| ). + + " no sortProperty and no filterProperty: sorting in the browser would tear + " the subtotals from their groups + t_layout = VALUE #( + ( name = `REGION` label = `Region` selected = abap_false ) ( name = `COUNTRY` label = `Country` selected = abap_false ) - ( name = `CATEGORY` label = `Category` selected = abap_false ) ). + ( name = `CATEGORY` label = `Category` selected = abap_false ) + ( name = `PRODUCT` label = `Product` selected = abap_false ) + ( name = `QUANTITY` label = `Quantity` selected = abap_false ) + ( name = `AMOUNT` label = `Amount` selected = abap_false ) + ( name = `CURRENCY` label = `Currency` selected = abap_false ) ). - rows_group( ). - view_display( ). + DATA(columns) = table->ele( n = `columns` ns = `table` ). + LOOP AT t_layout INTO DATA(s_layout). + + DATA(text) = |\{{ s_layout-name }\}|. + DATA(align) = `Begin`. + CASE s_layout-name. + WHEN `PRODUCT`. + text = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'Total' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'Subtotal' : $\{PRODUCT\} \}|. + WHEN `QUANTITY`. + align = `End`. + WHEN `AMOUNT`. + text = `{ parts: ['AMOUNT', 'CURRENCY'], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }`. + align = `End`. + ENDCASE. + + DATA(column) = columns->ele( n = `Column` ns = `table` + )->a( n = `width` v = `10rem` ). + column->tag( `Label` )->a( n = `text` t = s_layout-label ). + + " writeToDom renders data-rowkind="S" on the cell's own element. It only + " writes a string, so the expression turns an empty kind into I, an item + column->ele( n = `template` ns = `table` + )->ele( `Text` + )->a( n = `text` v = text + )->a( n = `textAlign` v = align + )->a( n = `wrapping` b = abap_false + )->ele( `customData` + )->tag( n = `CustomData` ns = `core` + )->a( n = `key` v = `rowkind` + )->a( n = `value` v = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'T' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'S' : 'I' \}| + )->a( n = `writeToDom` b = abap_true ). + + ENDLOOP. + + client->view_display( view->stringify( ) ). ENDMETHOD. @@ -380,115 +465,30 @@ CLASS z2ui5_cl_smp_app_544 IMPLEMENTATION. ENDMETHOD. - METHOD view_display. - - DATA t_layout TYPE STANDARD TABLE OF ty_s_column WITH EMPTY KEY. - - DATA(view) = z2ui5_cl_ui5_view_builder=>factory( - )->ele( n = `View` ns = `mvc` - )->a( n = `displayBlock` v = `true` - )->a( n = `height` v = `100%` - )->a( n = `xmlns` v = `sap.m` - )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` - )->a( n = `xmlns:core` v = `sap.ui.core` - )->a( n = `xmlns:table` v = `sap.ui.table` ). - DATA(page) = view->ele( `Shell` - )->ele( `Page` - )->a( n = `title` v = `abap2UI5 - Grid Table - Subtotals and Grand Total per Currency` - )->a( n = `showNavButton` b = client->check_app_prev_stack( ) - )->a( n = `navButtonPress` v = client->_event_nav_app_leave( ) ). - - page->tag( `MessageStrip` - )->a( n = `text` v = `Tick the columns to group by: the backend sorts the rows by them, inserts a subtotal row after ` && - `each group and a grand total at the end. Amounts are summed per currency, so a group in two currencies ` && - `gets two subtotal rows. Each cell writes its row kind into the DOM (CustomData writeToDom), and the ` && - `style below colours the whole row from it.` - )->a( n = `type` v = `Information` - )->a( n = `showIcon` b = abap_true - )->a( n = `class` v = `sapUiSmallMargin` ). - - " a grid table row takes no CSS class from its data, so every cell carries - " the row kind as data-rowkind, and :has( ) lifts it to the row. The - " theme parameters are CSS variables only on newer releases - the colour - " after the comma is the fallback for the ones without - page->tag( n = `HTML` ns = `core` - )->a( n = `content` v = `` ). - - DATA(table) = page->ele( n = `Table` ns = `table` - )->a( n = `rows` v = client->_bind( t_rows ) - )->a( n = `selectionMode` v = `None` - )->a( n = `visibleRowCount` v = client->_bind( visible_rows ) - )->a( n = `class` v = `sapUiSmallMarginBeginEnd` ). + METHOD model_init. - table->ele( n = `extension` ns = `table` - )->ele( `OverflowToolbar` - )->tag( `Title` - )->a( n = `text` v = `Sales` - )->tag( `ToolbarSpacer` - )->tag( `Label` - )->a( n = `text` v = `Group by:` - )->ele( `HBox` - )->a( n = `items` v = client->_bind( t_columns ) - )->tag( `CheckBox` - )->a( n = `text` v = `{LABEL}` - )->a( n = `selected` v = `{SELECTED}` - )->a( n = `select` v = client->_event( `GROUP` ) ). - - " the bar at the start of the row, in the colour of the row - table->ele( n = `rowSettingsTemplate` ns = `table` - )->tag( n = `RowSettings` ns = `table` - )->a( n = `highlight` v = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'Warning' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'Information' : 'None' \}| ). + t_sales = VALUE #( + ( region = `EMEA` country = `Germany` category = `Hardware` product = `Notebook` quantity = 10 amount = `12000.00` currency = `EUR` ) + ( region = `APAC` country = `Japan` category = `Software` product = `Antivirus` quantity = 50 amount = `2500.00` currency = `USD` ) + ( region = `EMEA` country = `Switzerland` category = `Hardware` product = `Monitor` quantity = 8 amount = `2400.00` currency = `CHF` ) + ( region = `Americas` country = `USA` category = `Hardware` product = `Server` quantity = 2 amount = `18000.00` currency = `USD` ) + ( region = `EMEA` country = `Germany` category = `Software` product = `Office Suite` quantity = 25 amount = `4500.00` currency = `EUR` ) + ( region = `Americas` country = `Canada` category = `Hardware` product = `Monitor` quantity = 5 amount = `1500.00` currency = `CAD` ) + ( region = `EMEA` country = `France` category = `Hardware` product = `Notebook` quantity = 6 amount = `7200.00` currency = `EUR` ) + ( region = `APAC` country = `Australia` category = `Services` product = `Training` quantity = 2 amount = `3000.00` currency = `USD` ) + ( region = `EMEA` country = `Switzerland` category = `Services` product = `Installation` quantity = 3 amount = `1350.00` currency = `CHF` ) + ( region = `Americas` country = `USA` category = `Services` product = `Support Contract` quantity = 12 amount = `6000.00` currency = `USD` ) + ( region = `APAC` country = `Japan` category = `Hardware` product = `Notebook` quantity = 4 amount = `4800.00` currency = `USD` ) + ( region = `Americas` country = `Canada` category = `Software` product = `Office Suite` quantity = 40 amount = `7600.00` currency = `CAD` ) ). - " no sortProperty and no filterProperty: sorting in the browser would tear - " the subtotals from their groups - t_layout = VALUE #( - ( name = `REGION` label = `Region` selected = abap_false ) + " the order of this list is the order of the groups, the first ticked + " column outermost + t_columns = VALUE #( + ( name = `REGION` label = `Region` selected = abap_true ) ( name = `COUNTRY` label = `Country` selected = abap_false ) - ( name = `CATEGORY` label = `Category` selected = abap_false ) - ( name = `PRODUCT` label = `Product` selected = abap_false ) - ( name = `QUANTITY` label = `Quantity` selected = abap_false ) - ( name = `AMOUNT` label = `Amount` selected = abap_false ) - ( name = `CURRENCY` label = `Currency` selected = abap_false ) ). - - DATA(columns) = table->ele( n = `columns` ns = `table` ). - LOOP AT t_layout INTO DATA(s_layout). - - DATA(text) = |\{{ s_layout-name }\}|. - DATA(align) = `Begin`. - CASE s_layout-name. - WHEN `PRODUCT`. - text = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'Total' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'Subtotal' : $\{PRODUCT\} \}|. - WHEN `QUANTITY`. - align = `End`. - WHEN `AMOUNT`. - text = `{ parts: ['AMOUNT', 'CURRENCY'], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }`. - align = `End`. - ENDCASE. - - DATA(column) = columns->ele( n = `Column` ns = `table` - )->a( n = `width` v = `10rem` ). - column->tag( `Label` )->a( n = `text` t = s_layout-label ). - - " writeToDom renders data-rowkind="S" on the cell's own element. It only - " writes a string, so the expression turns an empty kind into I, an item - column->ele( n = `template` ns = `table` - )->ele( `Text` - )->a( n = `text` v = text - )->a( n = `textAlign` v = align - )->a( n = `wrapping` b = abap_false - )->ele( `customData` - )->tag( n = `CustomData` ns = `core` - )->a( n = `key` v = `rowkind` - )->a( n = `value` v = |\{= $\{KIND\} === '{ cs_kind-total }' ? 'T' : $\{KIND\} === '{ cs_kind-subtotal }' ? 'S' : 'I' \}| - )->a( n = `writeToDom` b = abap_true ). - - ENDLOOP. + ( name = `CATEGORY` label = `Category` selected = abap_false ) ). - client->view_display( view->stringify( ) ). + rows_group( ). ENDMETHOD. diff --git a/src/z2ui5_cl_smp_app_545.clas.abap b/src/z2ui5_cl_smp_app_545.clas.abap index 114db8b8..775cd1b1 100644 --- a/src/z2ui5_cl_smp_app_545.clas.abap +++ b/src/z2ui5_cl_smp_app_545.clas.abap @@ -66,8 +66,8 @@ CLASS z2ui5_cl_smp_app_545 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. METHODS view_display. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -80,7 +80,8 @@ CLASS z2ui5_cl_smp_app_545 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `EXPAND` ). @@ -95,82 +96,6 @@ CLASS z2ui5_cl_smp_app_545 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - DATA(t_sales) = VALUE ty_t_sales( - ( region = `EMEA` country = `Germany` product = `Notebook` quantity = 10 amount = `12000.00` currency = `EUR` ) - ( region = `APAC` country = `Japan` product = `Antivirus` quantity = 50 amount = `2500.00` currency = `USD` ) - ( region = `EMEA` country = `Switzerland` product = `Monitor` quantity = 8 amount = `2400.00` currency = `CHF` ) - ( region = `Americas` country = `USA` product = `Server` quantity = 2 amount = `18000.00` currency = `USD` ) - ( region = `EMEA` country = `Germany` product = `Office Suite` quantity = 25 amount = `4500.00` currency = `EUR` ) - ( region = `Americas` country = `Canada` product = `Monitor` quantity = 5 amount = `1500.00` currency = `CAD` ) - ( region = `EMEA` country = `France` product = `Notebook` quantity = 6 amount = `7200.00` currency = `EUR` ) - ( region = `APAC` country = `Australia` product = `Training` quantity = 2 amount = `3000.00` currency = `USD` ) - ( region = `EMEA` country = `Switzerland` product = `Installation` quantity = 3 amount = `1350.00` currency = `CHF` ) - ( region = `Americas` country = `USA` product = `Support Contract` quantity = 12 amount = `6000.00` currency = `USD` ) - ( region = `APAC` country = `Japan` product = `Notebook` quantity = 4 amount = `4800.00` currency = `USD` ) - ( region = `Americas` country = `Canada` product = `Office Suite` quantity = 40 amount = `7600.00` currency = `CAD` ) ). - - t_tree = tree_build( t_sales ). - - " room for every node, so expanding all scrolls nothing out of sight - visible_rows = lines( t_sales ). - LOOP AT t_tree INTO DATA(s_total). - visible_rows = visible_rows + 1. - LOOP AT s_total-nodes INTO DATA(s_region). - visible_rows = visible_rows + 1 + lines( s_region-nodes ). - ENDLOOP. - ENDLOOP. - - view_display( ). - - ENDMETHOD. - - - METHOD tree_build. - - DATA t_sorted TYPE ty_t_sales. - FIELD-SYMBOLS TYPE ty_s_total. - FIELD-SYMBOLS TYPE ty_s_region. - FIELD-SYMBOLS TYPE ty_s_country. - - t_sorted = t_sales. - SORT t_sorted STABLE BY currency. - - LOOP AT t_sorted INTO DATA(s_sale). - - READ TABLE result ASSIGNING WITH KEY currency = s_sale-currency. - IF sy-subrc <> 0. - APPEND VALUE #( name = `Grand Total` currency = s_sale-currency kind = cs_kind-total ) TO result ASSIGNING . - ENDIF. - -quantity = -quantity + s_sale-quantity. - -amount = -amount + s_sale-amount. - - READ TABLE -nodes ASSIGNING WITH KEY name = s_sale-region. - IF sy-subrc <> 0. - APPEND VALUE #( name = s_sale-region currency = s_sale-currency kind = cs_kind-subtotal ) TO -nodes ASSIGNING . - ENDIF. - -quantity = -quantity + s_sale-quantity. - -amount = -amount + s_sale-amount. - - READ TABLE -nodes ASSIGNING WITH KEY name = s_sale-country. - IF sy-subrc <> 0. - APPEND VALUE #( name = s_sale-country currency = s_sale-currency kind = cs_kind-subtotal ) TO -nodes ASSIGNING . - ENDIF. - -quantity = -quantity + s_sale-quantity. - -amount = -amount + s_sale-amount. - - APPEND VALUE #( name = s_sale-product - quantity = s_sale-quantity - amount = s_sale-amount - currency = s_sale-currency - kind = `` ) TO -nodes. - - ENDLOOP. - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -267,4 +192,78 @@ CLASS z2ui5_cl_smp_app_545 IMPLEMENTATION. ENDMETHOD. + + METHOD tree_build. + + DATA t_sorted TYPE ty_t_sales. + FIELD-SYMBOLS TYPE ty_s_total. + FIELD-SYMBOLS TYPE ty_s_region. + FIELD-SYMBOLS TYPE ty_s_country. + + t_sorted = t_sales. + SORT t_sorted STABLE BY currency. + + LOOP AT t_sorted INTO DATA(s_sale). + + READ TABLE result ASSIGNING WITH KEY currency = s_sale-currency. + IF sy-subrc <> 0. + APPEND VALUE #( name = `Grand Total` currency = s_sale-currency kind = cs_kind-total ) TO result ASSIGNING . + ENDIF. + -quantity = -quantity + s_sale-quantity. + -amount = -amount + s_sale-amount. + + READ TABLE -nodes ASSIGNING WITH KEY name = s_sale-region. + IF sy-subrc <> 0. + APPEND VALUE #( name = s_sale-region currency = s_sale-currency kind = cs_kind-subtotal ) TO -nodes ASSIGNING . + ENDIF. + -quantity = -quantity + s_sale-quantity. + -amount = -amount + s_sale-amount. + + READ TABLE -nodes ASSIGNING WITH KEY name = s_sale-country. + IF sy-subrc <> 0. + APPEND VALUE #( name = s_sale-country currency = s_sale-currency kind = cs_kind-subtotal ) TO -nodes ASSIGNING . + ENDIF. + -quantity = -quantity + s_sale-quantity. + -amount = -amount + s_sale-amount. + + APPEND VALUE #( name = s_sale-product + quantity = s_sale-quantity + amount = s_sale-amount + currency = s_sale-currency + kind = `` ) TO -nodes. + + ENDLOOP. + + ENDMETHOD. + + + METHOD model_init. + + DATA(t_sales) = VALUE ty_t_sales( + ( region = `EMEA` country = `Germany` product = `Notebook` quantity = 10 amount = `12000.00` currency = `EUR` ) + ( region = `APAC` country = `Japan` product = `Antivirus` quantity = 50 amount = `2500.00` currency = `USD` ) + ( region = `EMEA` country = `Switzerland` product = `Monitor` quantity = 8 amount = `2400.00` currency = `CHF` ) + ( region = `Americas` country = `USA` product = `Server` quantity = 2 amount = `18000.00` currency = `USD` ) + ( region = `EMEA` country = `Germany` product = `Office Suite` quantity = 25 amount = `4500.00` currency = `EUR` ) + ( region = `Americas` country = `Canada` product = `Monitor` quantity = 5 amount = `1500.00` currency = `CAD` ) + ( region = `EMEA` country = `France` product = `Notebook` quantity = 6 amount = `7200.00` currency = `EUR` ) + ( region = `APAC` country = `Australia` product = `Training` quantity = 2 amount = `3000.00` currency = `USD` ) + ( region = `EMEA` country = `Switzerland` product = `Installation` quantity = 3 amount = `1350.00` currency = `CHF` ) + ( region = `Americas` country = `USA` product = `Support Contract` quantity = 12 amount = `6000.00` currency = `USD` ) + ( region = `APAC` country = `Japan` product = `Notebook` quantity = 4 amount = `4800.00` currency = `USD` ) + ( region = `Americas` country = `Canada` product = `Office Suite` quantity = 40 amount = `7600.00` currency = `CAD` ) ). + + t_tree = tree_build( t_sales ). + + " room for every node, so expanding all scrolls nothing out of sight + visible_rows = lines( t_sales ). + LOOP AT t_tree INTO DATA(s_total). + visible_rows = visible_rows + 1. + LOOP AT s_total-nodes INTO DATA(s_region). + visible_rows = visible_rows + 1 + lines( s_region-nodes ). + ENDLOOP. + ENDLOOP. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_546.clas.abap b/src/z2ui5_cl_smp_app_546.clas.abap index 277598ce..90a8ef91 100644 --- a/src/z2ui5_cl_smp_app_546.clas.abap +++ b/src/z2ui5_cl_smp_app_546.clas.abap @@ -22,10 +22,10 @@ CLASS z2ui5_cl_smp_app_546 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. + METHODS view_display. METHODS on_order. METHODS on_details. - METHODS view_display. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -38,7 +38,8 @@ CLASS z2ui5_cl_smp_app_546 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `ORDER` ). @@ -50,69 +51,6 @@ CLASS z2ui5_cl_smp_app_546 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - DATA(t_adjective) = VALUE string_table( ( `Compact` ) ( `Classic` ) ( `Smart` ) ( `Ultra` ) ( `Eco` ) - ( `Pro` ) ( `Mini` ) ( `Rugged` ) ( `Silent` ) ( `Wireless` ) ). - DATA(t_noun) = VALUE string_table( ( `Notebook` ) ( `Monitor` ) ( `Keyboard` ) ( `Mouse` ) ( `Printer` ) - ( `Headset` ) ( `Router` ) ( `Webcam` ) ( `Speaker` ) ( `Docking Station` ) ). - DATA(t_category) = VALUE string_table( ( `Computers` ) ( `Displays` ) ( `Accessories` ) ( `Office` ) ( `Network` ) ). - - DO 10000 TIMES. - DATA(index) = sy-index. - APPEND VALUE #( - id = index - name = |{ t_adjective[ ( index MOD 10 ) + 1 ] } { t_noun[ ( ( index DIV 10 ) MOD 10 ) + 1 ] } { index }| - category = t_category[ ( index MOD 5 ) + 1 ] - price = ( ( index * 7919 ) MOD 100000 ) / 100 - stock = ( index * 31 ) MOD 500 ) TO t_product. - ENDDO. - - view_display( ). - - ENDMETHOD. - - - METHOD on_details. - - " the event names the row as the browser shows it - after a search or - " a sort that is a position in the server's order, not a row of - " t_product. _bind_tab_row( ) answers which row it is - DATA(position) = CONV i( client->get_event_arg( ) ) + 1. - DATA(row) = client->_bind_tab_row( val = t_product - row = position ). - IF row = 0. - RETURN. - ENDIF. - - DATA(s_product) = t_product[ row ]. - client->message_box_display( |{ s_product-name } - row { row } of the table, shown as row { position }: | && - |{ s_product-category }, { s_product-price } EUR, { s_product-stock } in stock.| ). - - ENDMETHOD. - - - METHOD on_order. - - " the checkboxes the user ticked arrive in the rows they were ticked - " in - whatever the search and the sort showed - so the order runs - " over all 10,000 rows, the ones the browser never held included - DATA count TYPE i. - DATA total TYPE p LENGTH 15 DECIMALS 2. - LOOP AT t_product INTO DATA(s_product) WHERE selected = abap_true. - count = count + 1. - total = total + s_product-price. - ENDLOOP. - - IF count = 0. - client->message_toast_display( `Tick a product first.` ). - RETURN. - ENDIF. - client->message_box_display( |{ count } product(s) ordered, { total } EUR in total.| ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -239,4 +177,65 @@ CLASS z2ui5_cl_smp_app_546 IMPLEMENTATION. ENDMETHOD. + + METHOD on_details. + + " the event names the row as the browser shows it - after a search or + " a sort that is a position in the server's order, not a row of + " t_product. _bind_tab_row( ) answers which row it is + DATA(position) = CONV i( client->get_event_arg( ) ) + 1. + DATA(row) = client->_bind_tab_row( val = t_product + row = position ). + IF row = 0. + RETURN. + ENDIF. + + DATA(s_product) = t_product[ row ]. + client->message_box_display( |{ s_product-name } - row { row } of the table, shown as row { position }: | && + |{ s_product-category }, { s_product-price } EUR, { s_product-stock } in stock.| ). + + ENDMETHOD. + + + METHOD on_order. + + " the checkboxes the user ticked arrive in the rows they were ticked + " in - whatever the search and the sort showed - so the order runs + " over all 10,000 rows, the ones the browser never held included + DATA count TYPE i. + DATA total TYPE p LENGTH 15 DECIMALS 2. + LOOP AT t_product INTO DATA(s_product) WHERE selected = abap_true. + count = count + 1. + total = total + s_product-price. + ENDLOOP. + + IF count = 0. + client->message_toast_display( `Tick a product first.` ). + RETURN. + ENDIF. + client->message_box_display( |{ count } product(s) ordered, { total } EUR in total.| ). + + ENDMETHOD. + + + METHOD model_init. + + DATA(t_adjective) = VALUE string_table( ( `Compact` ) ( `Classic` ) ( `Smart` ) ( `Ultra` ) ( `Eco` ) + ( `Pro` ) ( `Mini` ) ( `Rugged` ) ( `Silent` ) ( `Wireless` ) ). + DATA(t_noun) = VALUE string_table( ( `Notebook` ) ( `Monitor` ) ( `Keyboard` ) ( `Mouse` ) ( `Printer` ) + ( `Headset` ) ( `Router` ) ( `Webcam` ) ( `Speaker` ) ( `Docking Station` ) ). + DATA(t_category) = VALUE string_table( ( `Computers` ) ( `Displays` ) ( `Accessories` ) ( `Office` ) ( `Network` ) ). + + DO 10000 TIMES. + DATA(index) = sy-index. + APPEND VALUE #( + id = index + name = |{ t_adjective[ ( index MOD 10 ) + 1 ] } { t_noun[ ( ( index DIV 10 ) MOD 10 ) + 1 ] } { index }| + category = t_category[ ( index MOD 5 ) + 1 ] + price = ( ( index * 7919 ) MOD 100000 ) / 100 + stock = ( index * 31 ) MOD 500 ) TO t_product. + ENDDO. + + ENDMETHOD. + ENDCLASS. diff --git a/src/z2ui5_cl_smp_app_547.clas.abap b/src/z2ui5_cl_smp_app_547.clas.abap index 5bc5cb84..8b445dc9 100644 --- a/src/z2ui5_cl_smp_app_547.clas.abap +++ b/src/z2ui5_cl_smp_app_547.clas.abap @@ -22,9 +22,9 @@ CLASS z2ui5_cl_smp_app_547 DEFINITION PUBLIC. PROTECTED SECTION. DATA client TYPE REF TO z2ui5_if_client. - METHODS on_init. - METHODS on_open. METHODS view_display. + METHODS on_open. + METHODS model_init. PRIVATE SECTION. ENDCLASS. @@ -37,7 +37,8 @@ CLASS z2ui5_cl_smp_app_547 IMPLEMENTATION. me->client = client. IF client->check_on_init( ). - on_init( ). + model_init( ). + view_display( ). ELSEIF client->check_on_navigated( ). view_display( ). ELSEIF client->check_on_event( `OPEN` ). @@ -47,48 +48,6 @@ CLASS z2ui5_cl_smp_app_547 IMPLEMENTATION. ENDMETHOD. - METHOD on_init. - - DATA(t_customer) = VALUE string_table( ( `Adler GmbH` ) ( `Berger AG` ) ( `Calder Ltd` ) ( `Dumont SA` ) ( `Eriksen AB` ) - ( `Ferrari Srl` ) ( `Garcia SL` ) ( `Hansen A/S` ) ( `Ivanov OOO` ) ( `Jansen BV` ) ). - DATA(t_city) = VALUE string_table( ( `Berlin` ) ( `Zurich` ) ( `London` ) ( `Paris` ) ( `Stockholm` ) - ( `Milan` ) ( `Madrid` ) ( `Copenhagen` ) ( `Vienna` ) ( `Amsterdam` ) ). - DATA(t_status) = VALUE string_table( ( `New` ) ( `In Process` ) ( `Shipped` ) ( `Delivered` ) ). - DATA(start) = CONV d( `20250101` ). - - DO 10000 TIMES. - DATA(index) = sy-index. - APPEND VALUE #( id = index - customer = t_customer[ ( ( index * 7 ) MOD 10 ) + 1 ] - city = t_city[ ( ( index * 3 ) MOD 10 ) + 1 ] - status = t_status[ ( index MOD 4 ) + 1 ] - amount = ( ( index * 6151 ) MOD 500000 ) / 100 - created = start + ( ( index * 13 ) MOD 365 ) ) TO t_order. - ENDDO. - - view_display( ). - - ENDMETHOD. - - - METHOD on_open. - - " the link names the row as the grid shows it - sorted and filtered by - " the server, so a position, not a row of t_order: _bind_tab_row( ) - " answers which row it is - DATA(row) = client->_bind_tab_row( val = t_order - row = CONV i( client->get_event_arg( ) ) + 1 ). - IF row = 0. - RETURN. - ENDIF. - - DATA(s_order) = t_order[ row ]. - client->message_box_display( |Order { s_order-id }: { s_order-customer }, { s_order-city }, | && - |{ s_order-status }, { s_order-amount } EUR.| ). - - ENDMETHOD. - - METHOD view_display. DATA(view) = z2ui5_cl_ui5_view_builder=>factory( @@ -203,4 +162,44 @@ CLASS z2ui5_cl_smp_app_547 IMPLEMENTATION. ENDMETHOD. + + METHOD on_open. + + " the link names the row as the grid shows it - sorted and filtered by + " the server, so a position, not a row of t_order: _bind_tab_row( ) + " answers which row it is + DATA(row) = client->_bind_tab_row( val = t_order + row = CONV i( client->get_event_arg( ) ) + 1 ). + IF row = 0. + RETURN. + ENDIF. + + DATA(s_order) = t_order[ row ]. + client->message_box_display( |Order { s_order-id }: { s_order-customer }, { s_order-city }, | && + |{ s_order-status }, { s_order-amount } EUR.| ). + + ENDMETHOD. + + + METHOD model_init. + + DATA(t_customer) = VALUE string_table( ( `Adler GmbH` ) ( `Berger AG` ) ( `Calder Ltd` ) ( `Dumont SA` ) ( `Eriksen AB` ) + ( `Ferrari Srl` ) ( `Garcia SL` ) ( `Hansen A/S` ) ( `Ivanov OOO` ) ( `Jansen BV` ) ). + DATA(t_city) = VALUE string_table( ( `Berlin` ) ( `Zurich` ) ( `London` ) ( `Paris` ) ( `Stockholm` ) + ( `Milan` ) ( `Madrid` ) ( `Copenhagen` ) ( `Vienna` ) ( `Amsterdam` ) ). + DATA(t_status) = VALUE string_table( ( `New` ) ( `In Process` ) ( `Shipped` ) ( `Delivered` ) ). + DATA(start) = CONV d( `20250101` ). + + DO 10000 TIMES. + DATA(index) = sy-index. + APPEND VALUE #( id = index + customer = t_customer[ ( ( index * 7 ) MOD 10 ) + 1 ] + city = t_city[ ( ( index * 3 ) MOD 10 ) + 1 ] + status = t_status[ ( index MOD 4 ) + 1 ] + amount = ( ( index * 6151 ) MOD 500000 ) / 100 + created = start + ( ( index * 13 ) MOD 365 ) ) TO t_order. + ENDDO. + + ENDMETHOD. + ENDCLASS.