From 95093541189cc1e4284e956efea4294f70bb61f8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 25 Jul 2026 18:00:16 +0000 Subject: [PATCH 1/7] Add Navigation routing-modes demo (default / fresh / keep) New sample z2ui5_cl_demo_app_468 ("Navigation - Routing modes") demonstrates the three modes of client->set_nav_routing( ) so the difference is observable with the browser Back button: pick a mode, add some state (type / raise a counter), open the detail page via nav_app_call, then press the browser Back button and watch the page: - default : no #/app route - browser Back leaves the app (in-app Back returns) - fresh : route by class only - browser Back restarts the app empty - keep : route by class + draft - browser Back restores the exact state z2ui5_cl_demo_app_469 is the hidden detail page it navigates to (ZZZ helper). Both live in 01/02 (framework use cases). Regenerated the overview catalogs; the regeneration also synced pre-existing DESCRIPT drift (apps 139, 346, 421, 466). Note: relies on set_nav_routing( mode ) / cs_nav_mode from abap2UI5; samples CI lints against abap2UI5 main and will be green once that framework change lands. --- src/00/z2ui5_cl_sample_app_g01.clas.abap | 4 +- src/01/02/z2ui5_cl_demo_app_468.clas.abap | 179 ++++++++++++++++++++++ src/01/02/z2ui5_cl_demo_app_468.clas.xml | 16 ++ src/01/02/z2ui5_cl_demo_app_469.clas.abap | 60 ++++++++ src/01/02/z2ui5_cl_demo_app_469.clas.xml | 16 ++ src/01/z2ui5_cl_demo_app_g00.clas.abap | 4 +- 6 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 src/01/02/z2ui5_cl_demo_app_468.clas.abap create mode 100644 src/01/02/z2ui5_cl_demo_app_468.clas.xml create mode 100644 src/01/02/z2ui5_cl_demo_app_469.clas.abap create mode 100644 src/01/02/z2ui5_cl_demo_app_469.clas.xml diff --git a/src/00/z2ui5_cl_sample_app_g01.clas.abap b/src/00/z2ui5_cl_sample_app_g01.clas.abap index f1327861..2c880cf8 100644 --- a/src/00/z2ui5_cl_sample_app_g01.clas.abap +++ b/src/00/z2ui5_cl_sample_app_g01.clas.abap @@ -275,7 +275,6 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. ( group = `only with javascript and css and html` header = `Messages with Styles I` sub = `` app = `z2ui5_cl_demo_app_310` ) ( group = `only with javascript and css and html` header = `Messages with Styles II` sub = `` app = `z2ui5_cl_demo_app_311` ) ( group = `only with javascript and css and html` header = `PDF Viewer` sub = `Display PDFs via iframe` app = `z2ui5_cl_demo_app_079` ) - ( group = `only with javascript and css and html` header = `tab` sub = `focus edit controls` app = `z2ui5_cl_demo_app_346` ) ( group = `only with javascript and css and html` header = `Tile` sub = `KPI Tile` app = `z2ui5_cl_demo_app_277` ) ( group = `only with javascript and css and html` header = `tree` sub = `drag & drop` app = `z2ui5_cl_demo_app_317` ) ( group = `only with javascript and css and html` header = `tree` sub = `popup select - state` app = `z2ui5_cl_demo_app_178` ) @@ -322,7 +321,6 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. ( group = `only testing` header = `ZZZ Data Object for Sample 328` sub = `` app = `z2ui5_cl_demo_app_329` ) ( group = `experimental, TODO` header = `gantt` sub = `test` app = `z2ui5_cl_demo_app_076` ) ( group = `experimental, TODO` header = `gantt II` sub = `` app = `z2ui5_cl_demo_app_179` ) - ( group = `experimental, TODO` header = `History` sub = `` app = `z2ui5_cl_demo_app_139` ) ( group = `experimental, TODO` header = `Navigation` sub = `app state` app = `z2ui5_cl_demo_app_321` ) ( group = `experimental, TODO` header = `Navigation` sub = `app state share` app = `z2ui5_cl_demo_app_323` ) ( group = `experimental, TODO` header = `Navigation` sub = `push state` app = `z2ui5_cl_demo_app_322` ) @@ -332,6 +330,7 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. ( group = `experimental, TODO` header = `Storage` sub = `Store data inside localStorage or sessionStorage` app = `z2ui5_cl_demo_app_327` ) ( group = `experimental, TODO` header = `ViewSettingsDialog` sub = `` app = `z2ui5_cl_demo_app_099` ) ( group = `obsolete` header = `follow_up_action with JS` sub = `` app = `z2ui5_cl_demo_app_309_0` ) + ( group = `obsolete` header = `History` sub = `` app = `z2ui5_cl_demo_app_139` ) ( group = `obsolete` header = `landing page` sub = `` app = `z2ui5_cl_demo_app_000` ) ( group = `obsolete` header = `obsolete` sub = `custom control UploadSet` app = `z2ui5_cl_demo_app_354` ) ( group = `obsolete` header = `obsolete` sub = `old focus demo, use Focus custom control` app = `z2ui5_cl_demo_app_133_0` ) @@ -349,6 +348,7 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. ( group = `obsolete` header = `obsolete` sub = `uses deprecated sap.f.Avatar, use sap.m.Avatar` app = `z2ui5_cl_demo_app_269` ) ( group = `obsolete` header = `obsolete` sub = `uses deprecated sap.ui.table.AnalyticalTable` app = `z2ui5_cl_demo_app_284` ) ( group = `obsolete` header = `obsolete` sub = `uses deprecated sap.ui.table.AnalyticalTable` app = `z2ui5_cl_demo_app_285` ) + ( group = `obsolete` header = `obsolete tab` sub = `focus edit controls, replaced by 421` app = `z2ui5_cl_demo_app_346` ) ( group = `obsolete` header = `sap.m.ActionSheet` sub = `Action Sheet provides an easier way of showing a list of actions and allowing the user to select one. Title and Cancel button can be shown or hidden. Without an icon the entry will be left-aligned (see the last action in the list).` app = `z2ui5_cl_demo_app_373` ) diff --git a/src/01/02/z2ui5_cl_demo_app_468.clas.abap b/src/01/02/z2ui5_cl_demo_app_468.clas.abap new file mode 100644 index 00000000..0070258d --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_468.clas.abap @@ -0,0 +1,179 @@ +"! Hash-based app routing (UI5 Router style) - demonstrates the three modes of +"! client->set_nav_routing( ) so the difference between them can be observed +"! directly with the browser's Back button: +"! +"! - default : routing off (framework behaviour before hash routing). The URL +"! keeps no '#/app/...' route, so the browser Back button leaves +"! the app entirely - only the in-app Back button returns. +"! - fresh : the URL mirrors the running app by CLASS only ('#/app/'). +"! Browser Back/Forward (and reload / bookmark) start the app FRESH +"! - the input, counter and picked mode are gone. +"! - keep : the URL also carries the app-state draft ('#/app//') +"! so browser Back/Forward restore the EXACT state - input, counter +"! and mode come back unchanged. +"! +"! Pick a mode, put in some state (type / raise the counter), open the detail +"! page (z2ui5_cl_demo_app_469) via client->nav_app_call( ), then press the +"! BROWSER Back button and watch this page. +CLASS z2ui5_cl_demo_app_468 DEFINITION PUBLIC. + + PUBLIC SECTION. + INTERFACES z2ui5_if_app. + + DATA mode TYPE string. + DATA input TYPE string. + DATA counter TYPE i. + + PROTECTED SECTION. + DATA client TYPE REF TO z2ui5_if_client. + + METHODS on_event. + METHODS view_display. + METHODS button_type + IMPORTING + val TYPE string + RETURNING + VALUE(result) TYPE string. + METHODS mode_hint + RETURNING + VALUE(result) TYPE string. + + PRIVATE SECTION. +ENDCLASS. + + + +CLASS z2ui5_cl_demo_app_468 IMPLEMENTATION. + + + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + mode = client->cs_nav_mode-keep. + 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. + + WHEN `MODE_DEFAULT`. + mode = client->cs_nav_mode-default. + view_display( ). + + WHEN `MODE_FRESH`. + mode = client->cs_nav_mode-fresh. + view_display( ). + + WHEN `MODE_KEEP`. + mode = client->cs_nav_mode-keep. + view_display( ). + + WHEN `INC`. + counter = counter + 1. + view_display( ). + + WHEN `GO_DETAIL`. + client->nav_app_call( NEW z2ui5_cl_demo_app_469( ) ). + + ENDCASE. + + ENDMETHOD. + + + METHOD view_display. + + " assert the picked routing mode on every render, so THIS page's history + " entry (the one the browser Back button returns to) is written under it + client->set_nav_routing( mode ). + + DATA(view) = z2ui5_cl_xml_view=>factory( ). + DATA(page) = view->shell( )->page( + title = `abap2UI5 - Navigation - Routing Modes` + navbuttonpress = client->_event_nav_app_leave( ) + shownavbutton = client->check_app_prev_stack( ) ). + + page->message_strip( + text = `Pick a routing mode, add some state (type / raise the counter), open the detail page, ` && + `then press your BROWSER Back button and watch this page.` + type = `Information` + showicon = abap_true + class = `sapUiSmallMargin` ). + + DATA(form) = page->grid( `L6 M12 S12` + )->content( `layout` + )->simple_form( `Try the routing modes` + )->content( `form` ). + + form->label( |1. Routing mode (current: { mode })| ). + form->button( + text = `default` + type = button_type( client->cs_nav_mode-default ) + press = client->_event( `MODE_DEFAULT` ) ). + form->button( + text = `fresh` + type = button_type( client->cs_nav_mode-fresh ) + press = client->_event( `MODE_FRESH` ) ). + form->button( + text = `keep` + type = button_type( client->cs_nav_mode-keep ) + press = client->_event( `MODE_KEEP` ) ). + + form->label( `2. Some state - type here` ). + form->input( client->_bind_edit( input ) ). + + form->label( `and raise a counter` ). + form->button( + text = |increment ({ counter })| + press = client->_event( `INC` ) ). + + form->label( `3. Navigate forward` ). + form->button( + text = `go to the detail page (nav_app_call)` + type = `Emphasized` + press = client->_event( `GO_DETAIL` ) ). + + page->message_strip( + text = mode_hint( ) + type = COND #( WHEN mode = client->cs_nav_mode-default THEN `Warning` ELSE `Success` ) + showicon = abap_true + class = `sapUiSmallMargin` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + + METHOD button_type. + + result = COND #( WHEN val = mode THEN `Emphasized` ELSE `Transparent` ). + + ENDMETHOD. + + + METHOD mode_hint. + + result = SWITCH #( mode + WHEN client->cs_nav_mode-keep THEN + `keep: the URL carries the app-state draft (#/app//). After the detail page, the ` && + `browser Back button restores this page EXACTLY - input, counter and mode come back.` + WHEN client->cs_nav_mode-fresh THEN + `fresh: the URL carries the class only (#/app/). After the detail page, the browser Back ` && + `button starts this app FRESH - input, counter and mode are reset.` + ELSE + `default: no #/app route is written. After the detail page, the browser Back button leaves the ` && + `app entirely (as before hash routing) - use the in-app Back button to return.` ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/01/02/z2ui5_cl_demo_app_468.clas.xml b/src/01/02/z2ui5_cl_demo_app_468.clas.xml new file mode 100644 index 00000000..9f80810b --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_468.clas.xml @@ -0,0 +1,16 @@ + + + + + + Z2UI5_CL_DEMO_APP_468 + E + Navigation - Routing modes (default / fresh / keep) + 1 + X + X + X + + + + diff --git a/src/01/02/z2ui5_cl_demo_app_469.clas.abap b/src/01/02/z2ui5_cl_demo_app_469.clas.abap new file mode 100644 index 00000000..86d55898 --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_469.clas.abap @@ -0,0 +1,60 @@ +"! Detail page for the routing-modes demo (z2ui5_cl_demo_app_468). It is reached +"! via client->nav_app_call( ), which - when hash routing is on - pushes a new +"! route history entry, so the browser Back button returns to the hub. This app +"! only shows what to do next; it is a hidden helper (never listed on its own in +"! the overview). +CLASS z2ui5_cl_demo_app_469 DEFINITION PUBLIC. + + PUBLIC SECTION. + INTERFACES z2ui5_if_app. + + PROTECTED SECTION. + DATA client TYPE REF TO z2ui5_if_client. + + METHODS view_display. + + PRIVATE SECTION. +ENDCLASS. + + + +CLASS z2ui5_cl_demo_app_469 IMPLEMENTATION. + + + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + view_display( ). + ENDIF. + + ENDMETHOD. + + + METHOD view_display. + + DATA(view) = z2ui5_cl_xml_view=>factory( ). + DATA(page) = view->shell( )->page( + title = `abap2UI5 - Navigation - Detail Page` + navbuttonpress = client->_event_nav_app_leave( ) + shownavbutton = client->check_app_prev_stack( ) ). + + page->message_strip( + text = `You navigated here from the routing-modes hub via nav_app_call. Now press your ` && + `BROWSER Back button and watch the hub: keep restores its state, fresh restarts it ` && + `empty, default leaves the app (use the in-app Back button then).` + type = `Information` + showicon = abap_true + class = `sapUiSmallMargin` ). + + page->button( + text = `back (in-app)` + icon = `sap-icon://nav-back` + press = client->_event_nav_app_leave( ) + class = `sapUiSmallMargin` ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/01/02/z2ui5_cl_demo_app_469.clas.xml b/src/01/02/z2ui5_cl_demo_app_469.clas.xml new file mode 100644 index 00000000..137e6927 --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_469.clas.xml @@ -0,0 +1,16 @@ + + + + + + Z2UI5_CL_DEMO_APP_469 + E + ZZZ - called by Navigation routing modes + 1 + X + X + X + + + + diff --git a/src/01/z2ui5_cl_demo_app_g00.clas.abap b/src/01/z2ui5_cl_demo_app_g00.clas.abap index 69b4c274..3dabfa3a 100644 --- a/src/01/z2ui5_cl_demo_app_g00.clas.abap +++ b/src/01/z2ui5_cl_demo_app_g00.clas.abap @@ -218,6 +218,7 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Event` sub = `Handle events & change the view` app = `z2ui5_cl_demo_app_004` ) ( group = `Basic I` header = `Formatter` sub = `Date Object for DatePicker` app = `z2ui5_cl_demo_app_457` ) ( group = `Basic I` header = `Formatter` sub = `Date Objects for PlanningCalendar` app = `z2ui5_cl_demo_app_456` ) + ( group = `Basic I` header = `Formatter` sub = `Inline Icons` app = `z2ui5_cl_demo_app_466` ) ( group = `Basic I` header = `Formatter` sub = `Simple` app = `z2ui5_cl_demo_app_453` ) ( group = `Basic I` header = `Formatter` sub = `Use via core:require` app = `z2ui5_cl_demo_app_450` ) ( group = `Basic I` header = `Message` sub = `Backend Processing` app = `z2ui5_cl_demo_app_008` ) @@ -249,6 +250,7 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) ( group = `Basic II` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) ( group = `Basic II` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) + ( group = `Basic II` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) ( group = `Basic II` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) ( group = `Basic II` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) ( group = `Basic II` header = `Input` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) @@ -261,7 +263,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `File Uploader (C)` app = `z2ui5_cl_demo_app_074` ) ( group = `Basic II` header = `More` sub = `Geoloaction (C)` app = `z2ui5_cl_demo_app_120` ) ( group = `Basic II` header = `More` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) - ( group = `Basic II` header = `More` sub = `MessageStrip Inline Icons` app = `z2ui5_cl_demo_app_466` ) ( group = `Basic II` header = `More` sub = `Multi Input (C)` app = `z2ui5_cl_demo_app_078` ) ( group = `Basic II` header = `More` sub = `Panel, setExpanded (A)` app = `z2ui5_cl_demo_app_448` ) ( group = `Basic II` header = `More` sub = `PDF Viewer Display (A)` app = `z2ui5_cl_demo_app_449` ) @@ -269,6 +270,7 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Wizard Control (A)` app = `z2ui5_cl_demo_app_202` ) ( group = `Basic II` header = `NavContainer` sub = `Popup (A)` app = `z2ui5_cl_demo_app_170` ) ( group = `Basic II` header = `NavContainer` sub = `Simple (A)` app = `z2ui5_cl_demo_app_088` ) + ( group = `Basic II` header = `Navigation` sub = `Routing modes (default / fresh / keep)` app = `z2ui5_cl_demo_app_468` ) ( group = `Basic II` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) ( group = `Basic II` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic II` header = `Table` sub = `Backend Filter` app = `z2ui5_cl_demo_app_045` ) From c46a94704d5373d810eff61a3fcbee6fc0ad39ac Mon Sep 17 00:00:00 2001 From: oblomov Date: Sun, 26 Jul 2026 09:49:48 +0000 Subject: [PATCH 2/7] fix --- .../z2ui5_cl_demo_app_028.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_028.clas.xml | 0 .../z2ui5_cl_demo_app_064.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_064.clas.xml | 0 .../z2ui5_cl_demo_app_073.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_073.clas.xml | 0 .../z2ui5_cl_demo_app_125.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_125.clas.xml | 0 .../z2ui5_cl_demo_app_133.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_133.clas.xml | 0 .../z2ui5_cl_demo_app_189.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_189.clas.xml | 0 .../01}/z2ui5_cl_demo_app_314.clas.abap | 35 ++++++++++--------- .../01}/z2ui5_cl_demo_app_314.clas.xml | 2 +- .../01}/z2ui5_cl_demo_app_315.clas.abap | 0 .../01}/z2ui5_cl_demo_app_315.clas.xml | 2 +- .../z2ui5_cl_demo_app_316.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_316.clas.xml | 0 .../z2ui5_cl_demo_app_325.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_325.clas.xml | 2 +- .../z2ui5_cl_demo_app_352.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_352.clas.xml | 2 +- .../z2ui5_cl_demo_app_361.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_361.clas.xml | 0 .../z2ui5_cl_demo_app_362.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_362.clas.xml | 0 .../z2ui5_cl_demo_app_363.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_363.clas.xml | 0 .../z2ui5_cl_demo_app_421.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_421.clas.xml | 0 src/01/01/z2ui5_cl_demo_app_458.clas.abap | 5 +-- src/01/01/z2ui5_cl_demo_app_458.clas.xml | 2 +- .../z2ui5_cl_demo_app_467.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_467.clas.xml | 2 +- .../z2ui5_cl_demo_app_468.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_468.clas.xml | 2 +- .../z2ui5_cl_demo_app_469.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_469.clas.xml | 0 38 files changed, 29 insertions(+), 25 deletions(-) rename src/01/{02 => 01}/z2ui5_cl_demo_app_028.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_028.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_064.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_064.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_073.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_073.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_125.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_125.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_133.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_133.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_189.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_189.clas.xml (100%) rename src/{00/00 => 01/01}/z2ui5_cl_demo_app_314.clas.abap (75%) rename src/{00/00 => 01/01}/z2ui5_cl_demo_app_314.clas.xml (86%) rename src/{00/00 => 01/01}/z2ui5_cl_demo_app_315.clas.abap (100%) rename src/{00/00 => 01/01}/z2ui5_cl_demo_app_315.clas.xml (89%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_316.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_316.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_325.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_325.clas.xml (89%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_352.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_352.clas.xml (87%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_361.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_361.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_362.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_362.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_363.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_363.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_421.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_421.clas.xml (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_467.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_467.clas.xml (88%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_468.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_468.clas.xml (85%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_469.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_469.clas.xml (100%) diff --git a/src/01/02/z2ui5_cl_demo_app_028.clas.abap b/src/01/01/z2ui5_cl_demo_app_028.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_028.clas.abap rename to src/01/01/z2ui5_cl_demo_app_028.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_028.clas.xml b/src/01/01/z2ui5_cl_demo_app_028.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_028.clas.xml rename to src/01/01/z2ui5_cl_demo_app_028.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_064.clas.abap b/src/01/01/z2ui5_cl_demo_app_064.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_064.clas.abap rename to src/01/01/z2ui5_cl_demo_app_064.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_064.clas.xml b/src/01/01/z2ui5_cl_demo_app_064.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_064.clas.xml rename to src/01/01/z2ui5_cl_demo_app_064.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_073.clas.abap b/src/01/01/z2ui5_cl_demo_app_073.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_073.clas.abap rename to src/01/01/z2ui5_cl_demo_app_073.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_073.clas.xml b/src/01/01/z2ui5_cl_demo_app_073.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_073.clas.xml rename to src/01/01/z2ui5_cl_demo_app_073.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_125.clas.abap b/src/01/01/z2ui5_cl_demo_app_125.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_125.clas.abap rename to src/01/01/z2ui5_cl_demo_app_125.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_125.clas.xml b/src/01/01/z2ui5_cl_demo_app_125.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_125.clas.xml rename to src/01/01/z2ui5_cl_demo_app_125.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_133.clas.abap b/src/01/01/z2ui5_cl_demo_app_133.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_133.clas.abap rename to src/01/01/z2ui5_cl_demo_app_133.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_133.clas.xml b/src/01/01/z2ui5_cl_demo_app_133.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_133.clas.xml rename to src/01/01/z2ui5_cl_demo_app_133.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_189.clas.abap b/src/01/01/z2ui5_cl_demo_app_189.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_189.clas.abap rename to src/01/01/z2ui5_cl_demo_app_189.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_189.clas.xml b/src/01/01/z2ui5_cl_demo_app_189.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_189.clas.xml rename to src/01/01/z2ui5_cl_demo_app_189.clas.xml diff --git a/src/00/00/z2ui5_cl_demo_app_314.clas.abap b/src/01/01/z2ui5_cl_demo_app_314.clas.abap similarity index 75% rename from src/00/00/z2ui5_cl_demo_app_314.clas.abap rename to src/01/01/z2ui5_cl_demo_app_314.clas.abap index f2f90d31..895f95bc 100644 --- a/src/00/00/z2ui5_cl_demo_app_314.clas.abap +++ b/src/01/01/z2ui5_cl_demo_app_314.clas.abap @@ -75,7 +75,7 @@ CLASS z2ui5_cl_demo_app_314 IMPLEMENTATION. )->text( `{http>DESCR}`). tab = page->table( - items = `{/BookingSupplement}` + items = `{/BusinessPartnerSet}` growing = abap_true ). tab->header_toolbar( @@ -83,25 +83,28 @@ CLASS z2ui5_cl_demo_app_314 IMPLEMENTATION. )->title( `table with odata model` ). tab->columns( - )->column( )->text( `TravelID` )->get_parent( - )->column( )->text( `BookingID` )->get_parent( - )->column( )->text( `BookingSupplementID` )->get_parent( - )->column( )->text( `SupplementID` )->get_parent( - )->column( )->text( `SupplementText` )->get_parent( - )->column( )->text( `Price` )->get_parent( - )->column( )->text( `CurrencyCode` )->get_parent( ). + )->column( )->text( `BusinessPartnerID` )->get_parent( + )->column( )->text( `CompanyName` )->get_parent( + )->column( )->text( `WebAddress` )->get_parent( +* )->column( )->text( `SupplementID` )->get_parent( +* )->column( )->text( `SupplementText` )->get_parent( +* )->column( )->text( `Price` )->get_parent( +* )->column( )->text( `CurrencyCode` )->get_parent( ). + ). tab->items( )->column_list_item( )->cells( - )->text( `{TravelID}` - )->text( `{BookingID}` - )->text( `{BookingSupplementID}` - )->text( `{SupplementID}` - )->text( `{SupplementText}` - )->text( `{Price}` - )->text( `{CurrencyCode}` ). + )->text( `{BusinessPartnerID}` + )->text( `{CompanyName}` + )->text( `{WebAddress}` +* )->text( `{SupplementID}` +* )->text( `{SupplementText}` +* )->text( `{Price}` +* )->text( `{CurrencyCode}` + ). client->view_display( val = view->stringify( ) - switch_default_model_path = `/sap/opu/odata/DMO/API_TRAVEL_U_V2/` ). + switch_default_model_path = `/sap/opu/odata/iwbep/gwsample_basic/` ). +* switch_default_model_path = `/sap/opu/odata/DMO/API_TRAVEL_U_V2/` ). ENDIF. diff --git a/src/00/00/z2ui5_cl_demo_app_314.clas.xml b/src/01/01/z2ui5_cl_demo_app_314.clas.xml similarity index 86% rename from src/00/00/z2ui5_cl_demo_app_314.clas.xml rename to src/01/01/z2ui5_cl_demo_app_314.clas.xml index c76cd5c6..213ea6c0 100644 --- a/src/00/00/z2ui5_cl_demo_app_314.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_314.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_314 E - tab - odata, device, http + EXPERIMENTAL - OData - Switch default Model 1 X X diff --git a/src/00/00/z2ui5_cl_demo_app_315.clas.abap b/src/01/01/z2ui5_cl_demo_app_315.clas.abap similarity index 100% rename from src/00/00/z2ui5_cl_demo_app_315.clas.abap rename to src/01/01/z2ui5_cl_demo_app_315.clas.abap diff --git a/src/00/00/z2ui5_cl_demo_app_315.clas.xml b/src/01/01/z2ui5_cl_demo_app_315.clas.xml similarity index 89% rename from src/00/00/z2ui5_cl_demo_app_315.clas.xml rename to src/01/01/z2ui5_cl_demo_app_315.clas.xml index bf671752..515390c6 100644 --- a/src/00/00/z2ui5_cl_demo_app_315.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_315.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_315 E - tab - different odata models + Model - Use OData models 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_316.clas.abap b/src/01/01/z2ui5_cl_demo_app_316.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_316.clas.abap rename to src/01/01/z2ui5_cl_demo_app_316.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_316.clas.xml b/src/01/01/z2ui5_cl_demo_app_316.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_316.clas.xml rename to src/01/01/z2ui5_cl_demo_app_316.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_325.clas.abap b/src/01/01/z2ui5_cl_demo_app_325.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_325.clas.abap rename to src/01/01/z2ui5_cl_demo_app_325.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_325.clas.xml b/src/01/01/z2ui5_cl_demo_app_325.clas.xml similarity index 89% rename from src/01/02/z2ui5_cl_demo_app_325.clas.xml rename to src/01/01/z2ui5_cl_demo_app_325.clas.xml index af68fee4..efdee0e6 100644 --- a/src/01/02/z2ui5_cl_demo_app_325.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_325.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_325 E - Input - Clipboard (A) + Browser - Clipboard (A) 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_352.clas.abap b/src/01/01/z2ui5_cl_demo_app_352.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_352.clas.abap rename to src/01/01/z2ui5_cl_demo_app_352.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_352.clas.xml b/src/01/01/z2ui5_cl_demo_app_352.clas.xml similarity index 87% rename from src/01/02/z2ui5_cl_demo_app_352.clas.xml rename to src/01/01/z2ui5_cl_demo_app_352.clas.xml index 0d497313..a9afc99a 100644 --- a/src/01/02/z2ui5_cl_demo_app_352.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_352.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_352 E - Input - Hide/show Soft Keyboard (A) + Browser - Hide/show Soft Keyboard (A) 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_361.clas.abap b/src/01/01/z2ui5_cl_demo_app_361.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_361.clas.abap rename to src/01/01/z2ui5_cl_demo_app_361.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_361.clas.xml b/src/01/01/z2ui5_cl_demo_app_361.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_361.clas.xml rename to src/01/01/z2ui5_cl_demo_app_361.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_362.clas.abap b/src/01/01/z2ui5_cl_demo_app_362.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_362.clas.abap rename to src/01/01/z2ui5_cl_demo_app_362.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_362.clas.xml b/src/01/01/z2ui5_cl_demo_app_362.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_362.clas.xml rename to src/01/01/z2ui5_cl_demo_app_362.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_363.clas.abap b/src/01/01/z2ui5_cl_demo_app_363.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_363.clas.abap rename to src/01/01/z2ui5_cl_demo_app_363.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_363.clas.xml b/src/01/01/z2ui5_cl_demo_app_363.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_363.clas.xml rename to src/01/01/z2ui5_cl_demo_app_363.clas.xml diff --git a/src/01/02/z2ui5_cl_demo_app_421.clas.abap b/src/01/01/z2ui5_cl_demo_app_421.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_421.clas.abap rename to src/01/01/z2ui5_cl_demo_app_421.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_421.clas.xml b/src/01/01/z2ui5_cl_demo_app_421.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_421.clas.xml rename to src/01/01/z2ui5_cl_demo_app_421.clas.xml diff --git a/src/01/01/z2ui5_cl_demo_app_458.clas.abap b/src/01/01/z2ui5_cl_demo_app_458.clas.abap index 1a02ba40..535f4db5 100644 --- a/src/01/01/z2ui5_cl_demo_app_458.clas.abap +++ b/src/01/01/z2ui5_cl_demo_app_458.clas.abap @@ -14,7 +14,9 @@ CLASS z2ui5_cl_demo_app_458 DEFINITION PUBLIC. ENDCLASS. -CLASS z2ui5_cl_demo_app_458 IMPLEMENTATION. + +CLASS Z2UI5_CL_DEMO_APP_458 IMPLEMENTATION. + METHOD z2ui5_if_app~main. @@ -64,5 +66,4 @@ CLASS z2ui5_cl_demo_app_458 IMPLEMENTATION. client->view_display( view->stringify( ) ). ENDMETHOD. - ENDCLASS. diff --git a/src/01/01/z2ui5_cl_demo_app_458.clas.xml b/src/01/01/z2ui5_cl_demo_app_458.clas.xml index 5d8a554d..aa4708fa 100644 --- a/src/01/01/z2ui5_cl_demo_app_458.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_458.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_458 E - Model - Message Model + Message - Message Model 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_467.clas.abap b/src/01/01/z2ui5_cl_demo_app_467.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_467.clas.abap rename to src/01/01/z2ui5_cl_demo_app_467.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_467.clas.xml b/src/01/01/z2ui5_cl_demo_app_467.clas.xml similarity index 88% rename from src/01/02/z2ui5_cl_demo_app_467.clas.xml rename to src/01/01/z2ui5_cl_demo_app_467.clas.xml index 468e7917..b0b31442 100644 --- a/src/01/02/z2ui5_cl_demo_app_467.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_467.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_467 E - More - Message Manager (C) + Message - Message Manager (C) 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_468.clas.abap b/src/01/01/z2ui5_cl_demo_app_468.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_468.clas.abap rename to src/01/01/z2ui5_cl_demo_app_468.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_468.clas.xml b/src/01/01/z2ui5_cl_demo_app_468.clas.xml similarity index 85% rename from src/01/02/z2ui5_cl_demo_app_468.clas.xml rename to src/01/01/z2ui5_cl_demo_app_468.clas.xml index 9f80810b..607ac5ff 100644 --- a/src/01/02/z2ui5_cl_demo_app_468.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_468.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_468 E - Navigation - Routing modes (default / fresh / keep) + EXPERIMENTAL - Navigation - Routing modes 1 X X diff --git a/src/01/02/z2ui5_cl_demo_app_469.clas.abap b/src/01/01/z2ui5_cl_demo_app_469.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_469.clas.abap rename to src/01/01/z2ui5_cl_demo_app_469.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_469.clas.xml b/src/01/01/z2ui5_cl_demo_app_469.clas.xml similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_469.clas.xml rename to src/01/01/z2ui5_cl_demo_app_469.clas.xml From 6325e03676855093f3e488186c7a296de2265665 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 26 Jul 2026 09:57:39 +0000 Subject: [PATCH 3/7] Add Popup aggregation-binding sample (element bind) New sample z2ui5_cl_demo_app_470 ("Popup - Aggregation binding") shows how to bind a popup to one row of an aggregation with client->follow_up_action( cs_event-bind_element, view = cs_view-popup ): the main table is bound to the product aggregation, and pressing a row's "components" button opens a popup that uses relative bindings only ({NAME}, {CATEGORY}, and the nested aggregation {T_ITEM}). The element bind points the whole popup slot at /T_PRODUCT/ (the index arrives as the event arg from the pressed control's binding context), so the popup - including its component list's aggregation binding - resolves against the selected product without copying any data into event args. Regenerated the overview catalog: adds the app_470 tile and syncs the catalog to the tree (the preceding file moves to src/01/01 had left it stale). --- src/00/z2ui5_cl_sample_app_g01.clas.abap | 2 - src/01/02/z2ui5_cl_demo_app_470.clas.abap | 156 ++++++++++++++++++++++ src/01/02/z2ui5_cl_demo_app_470.clas.xml | 16 +++ src/01/z2ui5_cl_demo_app_g00.clas.abap | 35 ++--- 4 files changed, 191 insertions(+), 18 deletions(-) create mode 100644 src/01/02/z2ui5_cl_demo_app_470.clas.abap create mode 100644 src/01/02/z2ui5_cl_demo_app_470.clas.xml diff --git a/src/00/z2ui5_cl_sample_app_g01.clas.abap b/src/00/z2ui5_cl_sample_app_g01.clas.abap index 2c880cf8..1e70e75d 100644 --- a/src/00/z2ui5_cl_sample_app_g01.clas.abap +++ b/src/00/z2ui5_cl_sample_app_g01.clas.abap @@ -214,8 +214,6 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. METHOD get_catalog. result = VALUE #( - ( group = `extended` header = `tab` sub = `different odata models` app = `z2ui5_cl_demo_app_315` ) - ( group = `extended` header = `tab` sub = `odata, device, http` app = `z2ui5_cl_demo_app_314` ) ( group = `only non-abap-cloud` header = `Conversion Exits` sub = `` app = `z2ui5_cl_demo_app_s_04` ) ( group = `only non-abap-cloud` header = `Generated APC WebSocket protocol impementation class` sub = `` app = `z2ui5_cl_demo_app_s_05_ws` ) ( group = `only non-abap-cloud` header = `Navigation with app state change v2` sub = `` app = `z2ui5_cl_demo_app_s_06` ) diff --git a/src/01/02/z2ui5_cl_demo_app_470.clas.abap b/src/01/02/z2ui5_cl_demo_app_470.clas.abap new file mode 100644 index 00000000..52d5bedb --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_470.clas.abap @@ -0,0 +1,156 @@ +"! Aggregation binding on a popup via an element bind. The main table is bound +"! to the product aggregation ({/T_PRODUCT}); pressing a row's "components" +"! button opens a popup that uses RELATIVE bindings only ({NAME}, {CATEGORY}, and +"! the nested aggregation {T_ITEM}). Instead of copying the row's data into event +"! args, the app element-binds the whole popup slot to /T_PRODUCT/ with +"! client->follow_up_action( cs_event-bind_element, view = cs_view-popup ), so the +"! popup's relative bindings - including its component list's aggregation binding - +"! resolve against the selected product. The row index arrives as the event arg +"! (the pressed control's binding-context path). +CLASS z2ui5_cl_demo_app_470 DEFINITION PUBLIC. + + PUBLIC SECTION. + INTERFACES z2ui5_if_app. + + TYPES: + BEGIN OF ty_s_item, + name TYPE string, + qty TYPE i, + unit TYPE string, + END OF ty_s_item, + BEGIN OF ty_s_product, + name TYPE string, + category TYPE string, + price TYPE string, + t_item TYPE STANDARD TABLE OF ty_s_item WITH EMPTY KEY, + END OF ty_s_product. + DATA t_product TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY. + + PROTECTED SECTION. + DATA client TYPE REF TO z2ui5_if_client. + + METHODS on_event. + METHODS view_display. + METHODS popup_components + IMPORTING + index TYPE string. + + PRIVATE SECTION. +ENDCLASS. + + + +CLASS z2ui5_cl_demo_app_470 IMPLEMENTATION. + + + METHOD z2ui5_if_app~main. + + me->client = client. + + IF client->check_on_init( ). + t_product = VALUE #( + ( name = `Notebook 15"` category = `Hardware` price = `1299` + t_item = VALUE #( ( name = `SSD 1 TB` qty = 1 unit = `pc` ) + ( name = `RAM 16 GB` qty = 2 unit = `pc` ) + ( name = `Charger 90W` qty = 1 unit = `pc` ) ) ) + ( name = `Wireless Mouse` category = `Accessories` price = `39` + t_item = VALUE #( ( name = `AA Battery` qty = 2 unit = `pc` ) ) ) + ( name = `USB-C Dock` category = `Accessories` price = `189` + t_item = VALUE #( ( name = `Power Supply` qty = 1 unit = `pc` ) + ( name = `Cable 1 m` qty = 1 unit = `pc` ) + ( name = `Quick Guide` qty = 1 unit = `pc` ) ) ) ). + view_display( ). + + ELSEIF client->check_on_event( ). + on_event( ). + ENDIF. + + ENDMETHOD. + + + METHOD on_event. + + CASE client->get( )-event. + WHEN `SHOW`. + popup_components( client->get_event_arg( ) ). + ENDCASE. + + ENDMETHOD. + + + METHOD view_display. + + DATA(view) = z2ui5_cl_xml_view=>factory( ). + DATA(page) = view->shell( )->page( `abap2UI5 - Aggregation binding on a popup` ). + + page->message_strip( + text = `The table is bound to the product aggregation. Press a row's "components" button - the ` && + `popup is element-bound to that product, so its relative bindings (incl. the component ` && + `list's aggregation binding) resolve without copying any data into event args.` + type = `Information` + showicon = abap_true + class = `sapUiSmallMargin` ). + + DATA(tab) = page->table( client->_bind( t_product ) ). + + tab->columns( + )->column( )->text( `Product` )->get_parent( + )->column( )->text( `Category` )->get_parent( + )->column( )->text( `Price` )->get_parent( + )->column( )->text( `Components` ). + + tab->items( + )->column_list_item( + )->cells( + )->text( `{NAME}` + )->text( `{CATEGORY}` + )->text( `{PRICE} EUR` + )->button( + text = `components` + icon = `sap-icon://product` + press = client->_event( + val = `SHOW` + t_arg = VALUE #( ( `$event.oSource.getBindingContext().getPath().split('/').pop()` ) ) ) ). + + client->view_display( view->stringify( ) ). + + ENDMETHOD. + + + METHOD popup_components. + + DATA(popup) = z2ui5_cl_xml_view=>factory_popup( ). + DATA(dialog) = popup->dialog( + title = `{NAME}` + contentwidth = `24rem` ). + + " relative bindings - resolved by the element bind below + DATA(box) = dialog->vbox( class = `sapUiSmallMarginBegin sapUiSmallMarginTop` ). + box->object_status( title = `Category` text = `{CATEGORY}` ). + box->object_status( title = `Price` text = `{PRICE} EUR` ). + + " the popup's own aggregation binding: the product's component list ({T_ITEM}) + dialog->list( + items = `{T_ITEM}` + headertext = `Components` + )->standard_list_item( + title = `{NAME}` + info = `{QTY} {UNIT}` ). + + dialog->buttons( + )->button( + text = `Close` + type = `Emphasized` + press = client->_event_client( client->cs_event-popup_close ) ). + + client->popup_display( popup->stringify( ) ). + + " element-bind the whole popup slot to the selected product, so every relative + " binding in the popup (and its component list aggregation) resolves against it + client->follow_up_action( + val = client->cs_event-bind_element + view = client->cs_view-popup + t_arg = VALUE #( ( index ) ( client->_bind( t_product ) ) ) ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/01/02/z2ui5_cl_demo_app_470.clas.xml b/src/01/02/z2ui5_cl_demo_app_470.clas.xml new file mode 100644 index 00000000..5467059f --- /dev/null +++ b/src/01/02/z2ui5_cl_demo_app_470.clas.xml @@ -0,0 +1,16 @@ + + + + + + Z2UI5_CL_DEMO_APP_470 + E + Popup - Aggregation binding to the selected row (element bind) + 1 + X + X + X + + + + diff --git a/src/01/z2ui5_cl_demo_app_g00.clas.abap b/src/01/z2ui5_cl_demo_app_g00.clas.abap index 3dabfa3a..49ecd03c 100644 --- a/src/01/z2ui5_cl_demo_app_g00.clas.abap +++ b/src/01/z2ui5_cl_demo_app_g00.clas.abap @@ -213,21 +213,34 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Binding` sub = `Formatting Integers, Decimals, Dates & Time` app = `z2ui5_cl_demo_app_047` ) ( group = `Basic I` header = `Binding` sub = `Level Structure/Component` app = `z2ui5_cl_demo_app_166` ) ( group = `Basic I` header = `Binding` sub = `Level Table/Cell` app = `z2ui5_cl_demo_app_144` ) + ( group = `Basic I` header = `Browser` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) + ( group = `Basic I` header = `Browser` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) + ( group = `Basic I` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) + ( group = `Basic I` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) + ( group = `Basic I` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) + ( group = `Basic I` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) ( group = `Basic I` header = `Event` sub = `Additional Infos with t_args` app = `z2ui5_cl_demo_app_167` ) ( group = `Basic I` header = `Event` sub = `Facet Filter T_arg with Objects` app = `z2ui5_cl_demo_app_197` ) ( group = `Basic I` header = `Event` sub = `Handle events & change the view` app = `z2ui5_cl_demo_app_004` ) + ( group = `Basic I` header = `EXPERIMENTAL` sub = `Navigation - Routing modes` app = `z2ui5_cl_demo_app_468` ) + ( group = `Basic I` header = `EXPERIMENTAL` sub = `OData - Switch default Model` app = `z2ui5_cl_demo_app_314` ) + ( group = `Basic I` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) + ( group = `Basic I` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) + ( group = `Basic I` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) ( group = `Basic I` header = `Formatter` sub = `Date Object for DatePicker` app = `z2ui5_cl_demo_app_457` ) ( group = `Basic I` header = `Formatter` sub = `Date Objects for PlanningCalendar` app = `z2ui5_cl_demo_app_456` ) ( group = `Basic I` header = `Formatter` sub = `Inline Icons` app = `z2ui5_cl_demo_app_466` ) ( group = `Basic I` header = `Formatter` sub = `Simple` app = `z2ui5_cl_demo_app_453` ) ( group = `Basic I` header = `Formatter` sub = `Use via core:require` app = `z2ui5_cl_demo_app_450` ) ( group = `Basic I` header = `Message` sub = `Backend Processing` app = `z2ui5_cl_demo_app_008` ) + ( group = `Basic I` header = `Message` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) + ( group = `Basic I` header = `Message` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Message` sub = `MessageBox` app = `z2ui5_cl_demo_app_382` ) ( group = `Basic I` header = `Message` sub = `MessageToast` app = `z2ui5_cl_demo_app_381` ) ( group = `Basic I` header = `Message` sub = `MessageView` app = `z2ui5_cl_demo_app_452` ) ( group = `Basic I` header = `Model` sub = `Device Model` app = `z2ui5_cl_demo_app_445` ) - ( group = `Basic I` header = `Model` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Model` sub = `Set Size Limit` app = `z2ui5_cl_demo_app_071` ) + ( group = `Basic I` header = `Model` sub = `Use OData models` app = `z2ui5_cl_demo_app_315` ) ( group = `Basic I` header = `More` sub = `Call and leave to apps` app = `z2ui5_cl_demo_app_024` ) ( group = `Basic I` header = `More` sub = `Error Handling` app = `z2ui5_cl_demo_app_464` ) ( group = `Basic I` header = `More` sub = `Generic Data Reference` app = `z2ui5_cl_demo_app_061` ) @@ -244,17 +257,12 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Popup` sub = `Different ways of calling Popups` app = `z2ui5_cl_demo_app_012` ) ( group = `Basic I` header = `Popup` sub = `Popup in Popup - Backend Stack Handling` app = `z2ui5_cl_demo_app_161` ) ( group = `Basic I` header = `Popup` sub = `Value Help with Popups` app = `z2ui5_cl_demo_app_009` ) + ( group = `Basic I` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) + ( group = `Basic I` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic I` header = `Templating` sub = `Basic Example` app = `z2ui5_cl_demo_app_173` ) ( group = `Basic I` header = `Templating` sub = `Nested Views` app = `z2ui5_cl_demo_app_176` ) - ( group = `Basic II` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) - ( group = `Basic II` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) - ( group = `Basic II` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) - ( group = `Basic II` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) - ( group = `Basic II` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) - ( group = `Basic II` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) - ( group = `Basic II` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) - ( group = `Basic II` header = `Input` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) - ( group = `Basic II` header = `Input` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) + ( group = `Basic I` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) + ( group = `Basic I` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) ( group = `Basic II` header = `List` sub = `Events & Visualization` app = `z2ui5_cl_demo_app_048` ) ( group = `Basic II` header = `List` sub = `Frontend Filter/Sort via Backend Event (A)` app = `z2ui5_cl_demo_app_454` ) ( group = `Basic II` header = `List` sub = `Frontend Live Filter without Backend (A)` app = `z2ui5_cl_demo_app_455` ) @@ -262,7 +270,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Data Loss Protection (C)` app = `z2ui5_cl_demo_app_279` ) ( group = `Basic II` header = `More` sub = `File Uploader (C)` app = `z2ui5_cl_demo_app_074` ) ( group = `Basic II` header = `More` sub = `Geoloaction (C)` app = `z2ui5_cl_demo_app_120` ) - ( group = `Basic II` header = `More` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) ( group = `Basic II` header = `More` sub = `Multi Input (C)` app = `z2ui5_cl_demo_app_078` ) ( group = `Basic II` header = `More` sub = `Panel, setExpanded (A)` app = `z2ui5_cl_demo_app_448` ) ( group = `Basic II` header = `More` sub = `PDF Viewer Display (A)` app = `z2ui5_cl_demo_app_449` ) @@ -270,9 +277,7 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Wizard Control (A)` app = `z2ui5_cl_demo_app_202` ) ( group = `Basic II` header = `NavContainer` sub = `Popup (A)` app = `z2ui5_cl_demo_app_170` ) ( group = `Basic II` header = `NavContainer` sub = `Simple (A)` app = `z2ui5_cl_demo_app_088` ) - ( group = `Basic II` header = `Navigation` sub = `Routing modes (default / fresh / keep)` app = `z2ui5_cl_demo_app_468` ) - ( group = `Basic II` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) - ( group = `Basic II` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) + ( group = `Basic II` header = `Popup` sub = `Aggregation binding to the selected row (element bind)` app = `z2ui5_cl_demo_app_470` ) ( group = `Basic II` header = `Table` sub = `Backend Filter` app = `z2ui5_cl_demo_app_045` ) ( group = `Basic II` header = `Table` sub = `Drag and Drop (A)` app = `z2ui5_cl_demo_app_459` ) ( group = `Basic II` header = `Table` sub = `Editable` app = `z2ui5_cl_demo_app_011` ) @@ -280,8 +285,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `Table` sub = `Search via Backend` app = `z2ui5_cl_demo_app_053` ) ( group = `Basic II` header = `Table` sub = `Selection Modes: Single Select & Multi Select` app = `z2ui5_cl_demo_app_019` ) ( group = `Basic II` header = `Table` sub = `Table with ScrollContainer` app = `z2ui5_cl_demo_app_006` ) - ( group = `Basic II` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) - ( group = `Basic II` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) ( group = `Basic II` header = `Tree` sub = `Drag and Drop (A,C)` app = `z2ui5_cl_demo_app_461` ) ( group = `Basic II` header = `Tree` sub = `Editable with Custom Item (C)` app = `z2ui5_cl_demo_app_463` ) ( group = `Basic II` header = `Tree` sub = `Inside Popup (C)` app = `z2ui5_cl_demo_app_462` ) From d7f0549af69e478659bd76abcdb408982c660871 Mon Sep 17 00:00:00 2001 From: oblomov Date: Sun, 26 Jul 2026 10:30:51 +0000 Subject: [PATCH 4/7] fixes --- .../z2ui5_cl_demo_app_313.clas.abap | 48 ++++++++++++++++--- .../{02 => 00}/z2ui5_cl_demo_app_313.clas.xml | 2 +- .../00}/z2ui5_cl_demo_app_314.clas.abap | 0 .../00}/z2ui5_cl_demo_app_314.clas.xml | 2 +- .../z2ui5_cl_demo_app_319.clas.abap | 19 ++++---- .../{02 => 00}/z2ui5_cl_demo_app_319.clas.xml | 2 +- src/00/z2ui5_cl_sample_app_g01.clas.abap | 2 + src/01/01/z2ui5_cl_demo_app_315.clas.abap | 3 +- .../z2ui5_cl_demo_app_470.clas.abap | 0 .../{02 => 01}/z2ui5_cl_demo_app_470.clas.xml | 2 +- src/01/z2ui5_cl_demo_app_g00.clas.abap | 35 +++++++------- 11 files changed, 77 insertions(+), 38 deletions(-) rename src/00/{02 => 00}/z2ui5_cl_demo_app_313.clas.abap (51%) rename src/00/{02 => 00}/z2ui5_cl_demo_app_313.clas.xml (87%) rename src/{01/01 => 00/00}/z2ui5_cl_demo_app_314.clas.abap (100%) rename src/{01/01 => 00/00}/z2ui5_cl_demo_app_314.clas.xml (86%) rename src/00/{02 => 00}/z2ui5_cl_demo_app_319.clas.abap (77%) rename src/00/{02 => 00}/z2ui5_cl_demo_app_319.clas.xml (88%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_470.clas.abap (100%) rename src/01/{02 => 01}/z2ui5_cl_demo_app_470.clas.xml (83%) diff --git a/src/00/02/z2ui5_cl_demo_app_313.clas.abap b/src/00/00/z2ui5_cl_demo_app_313.clas.abap similarity index 51% rename from src/00/02/z2ui5_cl_demo_app_313.clas.abap rename to src/00/00/z2ui5_cl_demo_app_313.clas.abap index 5ac206a3..a714de6b 100644 --- a/src/00/02/z2ui5_cl_demo_app_313.clas.abap +++ b/src/00/00/z2ui5_cl_demo_app_313.clas.abap @@ -30,6 +30,42 @@ CLASS z2ui5_cl_demo_app_313 IMPLEMENTATION. IF client->check_on_init( ). +* DATA(view) = z2ui5_cl_xml_view=>factory( ). +* +* DATA(page) = view->shell( +* )->page( +* title = `abap2UI5 - Smart Controls with Variants` +* navbuttonpress = client->_event_nav_app_leave( ) +* shownavbutton = client->check_app_prev_stack( ) ). +* +* page->smart_filter_bar( +* id = `smartFilterBar` +* persistencykey = `SmartFilterPKey` +* entityset = `BookingSupplement` +* )->_control_configuration( +* )->control_configuration( +* previnitdatafetchinvalhelpdia = abap_false +* visibleinadvancedarea = abap_true +* key = `TravelID` +* )->get_parent( +* )->smart_table( +* id = `smartFiltertable` +* smartfilterid = `smartFilterBar` +* tabletype = `ResponsiveTable` +* editable = abap_false +* initiallyvisiblefields = `TravelID,BookingID` +* entityset = `BookingSupplement` +* usevariantmanagement = abap_true +* useexporttoexcel = abap_true +* usetablepersonalisation = abap_true +* header = `Test` +* showrowcount = abap_true +* enableexport = abap_false +* enableautobinding = abap_true ). +* +* client->view_display( val = view->stringify( ) +* switch_default_model_path = `/sap/opu/odata/DMO/API_TRAVEL_U_V2/` ). + DATA(view) = z2ui5_cl_xml_view=>factory( ). DATA(page) = view->shell( @@ -41,30 +77,30 @@ CLASS z2ui5_cl_demo_app_313 IMPLEMENTATION. page->smart_filter_bar( id = `smartFilterBar` persistencykey = `SmartFilterPKey` - entityset = `BookingSupplement` + entityset = `ProductType_2` )->_control_configuration( )->control_configuration( previnitdatafetchinvalhelpdia = abap_false visibleinadvancedarea = abap_true - key = `TravelID` + key = `ProductType` )->get_parent( )->smart_table( id = `smartFiltertable` smartfilterid = `smartFilterBar` tabletype = `ResponsiveTable` editable = abap_false - initiallyvisiblefields = `TravelID,BookingID` - entityset = `BookingSupplement` + initiallyvisiblefields = `ProductType,ProductType_Text` + entityset = `ProductType_2` usevariantmanagement = abap_true useexporttoexcel = abap_true usetablepersonalisation = abap_true header = `Test` showrowcount = abap_true enableexport = abap_false - enableautobinding = abap_true ). + enableautobinding = abap_false ). client->view_display( val = view->stringify( ) - switch_default_model_path = `/sap/opu/odata/DMO/API_TRAVEL_U_V2/` ). + switch_default_model_path = `/sap/opu/odata/sap/UI_PRODUCTLIST/` ). ENDIF. diff --git a/src/00/02/z2ui5_cl_demo_app_313.clas.xml b/src/00/00/z2ui5_cl_demo_app_313.clas.xml similarity index 87% rename from src/00/02/z2ui5_cl_demo_app_313.clas.xml rename to src/00/00/z2ui5_cl_demo_app_313.clas.xml index 20667d06..9bbb59eb 100644 --- a/src/00/02/z2ui5_cl_demo_app_313.clas.xml +++ b/src/00/00/z2ui5_cl_demo_app_313.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_313 E - tab - smart controls + EXPERIMENTAL - Smart Table and Variants 1 X X diff --git a/src/01/01/z2ui5_cl_demo_app_314.clas.abap b/src/00/00/z2ui5_cl_demo_app_314.clas.abap similarity index 100% rename from src/01/01/z2ui5_cl_demo_app_314.clas.abap rename to src/00/00/z2ui5_cl_demo_app_314.clas.abap diff --git a/src/01/01/z2ui5_cl_demo_app_314.clas.xml b/src/00/00/z2ui5_cl_demo_app_314.clas.xml similarity index 86% rename from src/01/01/z2ui5_cl_demo_app_314.clas.xml rename to src/00/00/z2ui5_cl_demo_app_314.clas.xml index 213ea6c0..2259ce1e 100644 --- a/src/01/01/z2ui5_cl_demo_app_314.clas.xml +++ b/src/00/00/z2ui5_cl_demo_app_314.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_314 E - EXPERIMENTAL - OData - Switch default Model + EXPERIMENTAL - Switch default Model 1 X X diff --git a/src/00/02/z2ui5_cl_demo_app_319.clas.abap b/src/00/00/z2ui5_cl_demo_app_319.clas.abap similarity index 77% rename from src/00/02/z2ui5_cl_demo_app_319.clas.abap rename to src/00/00/z2ui5_cl_demo_app_319.clas.abap index 2d0f73b8..81c34a2c 100644 --- a/src/00/02/z2ui5_cl_demo_app_319.clas.abap +++ b/src/00/00/z2ui5_cl_demo_app_319.clas.abap @@ -74,17 +74,19 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. l_page->smart_multi_input( id = `ProductTypeMultiInput` -* value = '{ProductType}' - value = `{CurrencyCode}` - entityset = `Booking` + value = '{ProductType}' +* value = `{CurrencyCode}` +* entityset = `Booking` + entityset = `ProductType_2` supportranges = `true` enableodataselect = `true` ). m_client->view_display( val = l_page->stringify( ) -* switch_default_model_path = `/sap/opu/odata/sap/UI_PRODUCTLIST` - switch_default_model_path = `/sap/opu/odata/DMO/UI_TRAVEL_A_D_O2` -* switchdefaultmodelannouri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='UI_PRODUCTLIST_VAN',Version='0001')/$value` - switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='%2FDMO%2FUI_TRAVEL_A_D_O2_VAN',Version='0001')/$value` ). + switch_default_model_path = `/sap/opu/odata/sap/UI_PRODUCTLIST` +* switch_default_model_path = `/sap/opu/odata/DMO/UI_TRAVEL_A_D_O2` + switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='UI_PRODUCTLIST_VAN',Version='0001')/$value` +* switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='%2FDMO%2FUI_TRAVEL_A_D_O2_VAN',Version='0001')/$value` + ). ENDMETHOD. @@ -92,7 +94,8 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. METHOD on_event. IF m_client->check_on_event( `PRODTYPE_CHANGED` ). - INSERT VALUE #( operation = `EQ` value1 = `EUR` keyfield = `CurrencyCode` tokentext = `Euro (auto added line)` ) INTO TABLE m_selection-product_type-ranges. +* INSERT VALUE #( operation = `EQ` value1 = `EUR` keyfield = `CurrencyCode` tokentext = `Euro (auto added line)` ) INTO TABLE m_selection-product_type-ranges. +* INSERT VALUE #( operation = `EQ` value1 = `EUR` keyfield = `ProductType` tokentext = `Euro (auto added line)` ) INTO TABLE m_selection-product_type-ranges. m_client->view_model_update( ). TRY. m_client->message_box_display( diff --git a/src/00/02/z2ui5_cl_demo_app_319.clas.xml b/src/00/00/z2ui5_cl_demo_app_319.clas.xml similarity index 88% rename from src/00/02/z2ui5_cl_demo_app_319.clas.xml rename to src/00/00/z2ui5_cl_demo_app_319.clas.xml index a2fe5bbc..13e5b2fb 100644 --- a/src/00/02/z2ui5_cl_demo_app_319.clas.xml +++ b/src/00/00/z2ui5_cl_demo_app_319.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_319 E - odata, smartmultiinput + EXPERIMENTAL - Smart Multi Input 1 X X diff --git a/src/00/z2ui5_cl_sample_app_g01.clas.abap b/src/00/z2ui5_cl_sample_app_g01.clas.abap index 1e70e75d..2c880cf8 100644 --- a/src/00/z2ui5_cl_sample_app_g01.clas.abap +++ b/src/00/z2ui5_cl_sample_app_g01.clas.abap @@ -214,6 +214,8 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. METHOD get_catalog. result = VALUE #( + ( group = `extended` header = `tab` sub = `different odata models` app = `z2ui5_cl_demo_app_315` ) + ( group = `extended` header = `tab` sub = `odata, device, http` app = `z2ui5_cl_demo_app_314` ) ( group = `only non-abap-cloud` header = `Conversion Exits` sub = `` app = `z2ui5_cl_demo_app_s_04` ) ( group = `only non-abap-cloud` header = `Generated APC WebSocket protocol impementation class` sub = `` app = `z2ui5_cl_demo_app_s_05_ws` ) ( group = `only non-abap-cloud` header = `Navigation with app state change v2` sub = `` app = `z2ui5_cl_demo_app_s_06` ) diff --git a/src/01/01/z2ui5_cl_demo_app_315.clas.abap b/src/01/01/z2ui5_cl_demo_app_315.clas.abap index 29b2ebe4..55382f5c 100644 --- a/src/01/01/z2ui5_cl_demo_app_315.clas.abap +++ b/src/01/01/z2ui5_cl_demo_app_315.clas.abap @@ -60,7 +60,8 @@ CLASS z2ui5_cl_demo_app_315 IMPLEMENTATION. )->text( `{FLIGHT>CountryCode}` ). client->view_display( val = view->stringify( ) - switch_default_model_path = `` ). +* switch_default_model_path = `` + ). client->follow_up_action( val = z2ui5_if_client=>cs_event-set_odata_model diff --git a/src/01/02/z2ui5_cl_demo_app_470.clas.abap b/src/01/01/z2ui5_cl_demo_app_470.clas.abap similarity index 100% rename from src/01/02/z2ui5_cl_demo_app_470.clas.abap rename to src/01/01/z2ui5_cl_demo_app_470.clas.abap diff --git a/src/01/02/z2ui5_cl_demo_app_470.clas.xml b/src/01/01/z2ui5_cl_demo_app_470.clas.xml similarity index 83% rename from src/01/02/z2ui5_cl_demo_app_470.clas.xml rename to src/01/01/z2ui5_cl_demo_app_470.clas.xml index 5467059f..db5637b8 100644 --- a/src/01/02/z2ui5_cl_demo_app_470.clas.xml +++ b/src/01/01/z2ui5_cl_demo_app_470.clas.xml @@ -5,7 +5,7 @@ Z2UI5_CL_DEMO_APP_470 E - Popup - Aggregation binding to the selected row (element bind) + Popup - Aggregation binding to the selected row 1 X X diff --git a/src/01/z2ui5_cl_demo_app_g00.clas.abap b/src/01/z2ui5_cl_demo_app_g00.clas.abap index 49ecd03c..3dabfa3a 100644 --- a/src/01/z2ui5_cl_demo_app_g00.clas.abap +++ b/src/01/z2ui5_cl_demo_app_g00.clas.abap @@ -213,34 +213,21 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Binding` sub = `Formatting Integers, Decimals, Dates & Time` app = `z2ui5_cl_demo_app_047` ) ( group = `Basic I` header = `Binding` sub = `Level Structure/Component` app = `z2ui5_cl_demo_app_166` ) ( group = `Basic I` header = `Binding` sub = `Level Table/Cell` app = `z2ui5_cl_demo_app_144` ) - ( group = `Basic I` header = `Browser` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) - ( group = `Basic I` header = `Browser` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) - ( group = `Basic I` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) - ( group = `Basic I` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) - ( group = `Basic I` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) - ( group = `Basic I` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) ( group = `Basic I` header = `Event` sub = `Additional Infos with t_args` app = `z2ui5_cl_demo_app_167` ) ( group = `Basic I` header = `Event` sub = `Facet Filter T_arg with Objects` app = `z2ui5_cl_demo_app_197` ) ( group = `Basic I` header = `Event` sub = `Handle events & change the view` app = `z2ui5_cl_demo_app_004` ) - ( group = `Basic I` header = `EXPERIMENTAL` sub = `Navigation - Routing modes` app = `z2ui5_cl_demo_app_468` ) - ( group = `Basic I` header = `EXPERIMENTAL` sub = `OData - Switch default Model` app = `z2ui5_cl_demo_app_314` ) - ( group = `Basic I` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) - ( group = `Basic I` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) - ( group = `Basic I` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) ( group = `Basic I` header = `Formatter` sub = `Date Object for DatePicker` app = `z2ui5_cl_demo_app_457` ) ( group = `Basic I` header = `Formatter` sub = `Date Objects for PlanningCalendar` app = `z2ui5_cl_demo_app_456` ) ( group = `Basic I` header = `Formatter` sub = `Inline Icons` app = `z2ui5_cl_demo_app_466` ) ( group = `Basic I` header = `Formatter` sub = `Simple` app = `z2ui5_cl_demo_app_453` ) ( group = `Basic I` header = `Formatter` sub = `Use via core:require` app = `z2ui5_cl_demo_app_450` ) ( group = `Basic I` header = `Message` sub = `Backend Processing` app = `z2ui5_cl_demo_app_008` ) - ( group = `Basic I` header = `Message` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) - ( group = `Basic I` header = `Message` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Message` sub = `MessageBox` app = `z2ui5_cl_demo_app_382` ) ( group = `Basic I` header = `Message` sub = `MessageToast` app = `z2ui5_cl_demo_app_381` ) ( group = `Basic I` header = `Message` sub = `MessageView` app = `z2ui5_cl_demo_app_452` ) ( group = `Basic I` header = `Model` sub = `Device Model` app = `z2ui5_cl_demo_app_445` ) + ( group = `Basic I` header = `Model` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Model` sub = `Set Size Limit` app = `z2ui5_cl_demo_app_071` ) - ( group = `Basic I` header = `Model` sub = `Use OData models` app = `z2ui5_cl_demo_app_315` ) ( group = `Basic I` header = `More` sub = `Call and leave to apps` app = `z2ui5_cl_demo_app_024` ) ( group = `Basic I` header = `More` sub = `Error Handling` app = `z2ui5_cl_demo_app_464` ) ( group = `Basic I` header = `More` sub = `Generic Data Reference` app = `z2ui5_cl_demo_app_061` ) @@ -257,12 +244,17 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Popup` sub = `Different ways of calling Popups` app = `z2ui5_cl_demo_app_012` ) ( group = `Basic I` header = `Popup` sub = `Popup in Popup - Backend Stack Handling` app = `z2ui5_cl_demo_app_161` ) ( group = `Basic I` header = `Popup` sub = `Value Help with Popups` app = `z2ui5_cl_demo_app_009` ) - ( group = `Basic I` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) - ( group = `Basic I` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic I` header = `Templating` sub = `Basic Example` app = `z2ui5_cl_demo_app_173` ) ( group = `Basic I` header = `Templating` sub = `Nested Views` app = `z2ui5_cl_demo_app_176` ) - ( group = `Basic I` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) - ( group = `Basic I` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) + ( group = `Basic II` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) + ( group = `Basic II` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) + ( group = `Basic II` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) + ( group = `Basic II` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) + ( group = `Basic II` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) + ( group = `Basic II` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) + ( group = `Basic II` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) + ( group = `Basic II` header = `Input` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) + ( group = `Basic II` header = `Input` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) ( group = `Basic II` header = `List` sub = `Events & Visualization` app = `z2ui5_cl_demo_app_048` ) ( group = `Basic II` header = `List` sub = `Frontend Filter/Sort via Backend Event (A)` app = `z2ui5_cl_demo_app_454` ) ( group = `Basic II` header = `List` sub = `Frontend Live Filter without Backend (A)` app = `z2ui5_cl_demo_app_455` ) @@ -270,6 +262,7 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Data Loss Protection (C)` app = `z2ui5_cl_demo_app_279` ) ( group = `Basic II` header = `More` sub = `File Uploader (C)` app = `z2ui5_cl_demo_app_074` ) ( group = `Basic II` header = `More` sub = `Geoloaction (C)` app = `z2ui5_cl_demo_app_120` ) + ( group = `Basic II` header = `More` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) ( group = `Basic II` header = `More` sub = `Multi Input (C)` app = `z2ui5_cl_demo_app_078` ) ( group = `Basic II` header = `More` sub = `Panel, setExpanded (A)` app = `z2ui5_cl_demo_app_448` ) ( group = `Basic II` header = `More` sub = `PDF Viewer Display (A)` app = `z2ui5_cl_demo_app_449` ) @@ -277,7 +270,9 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Wizard Control (A)` app = `z2ui5_cl_demo_app_202` ) ( group = `Basic II` header = `NavContainer` sub = `Popup (A)` app = `z2ui5_cl_demo_app_170` ) ( group = `Basic II` header = `NavContainer` sub = `Simple (A)` app = `z2ui5_cl_demo_app_088` ) - ( group = `Basic II` header = `Popup` sub = `Aggregation binding to the selected row (element bind)` app = `z2ui5_cl_demo_app_470` ) + ( group = `Basic II` header = `Navigation` sub = `Routing modes (default / fresh / keep)` app = `z2ui5_cl_demo_app_468` ) + ( group = `Basic II` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) + ( group = `Basic II` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic II` header = `Table` sub = `Backend Filter` app = `z2ui5_cl_demo_app_045` ) ( group = `Basic II` header = `Table` sub = `Drag and Drop (A)` app = `z2ui5_cl_demo_app_459` ) ( group = `Basic II` header = `Table` sub = `Editable` app = `z2ui5_cl_demo_app_011` ) @@ -285,6 +280,8 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `Table` sub = `Search via Backend` app = `z2ui5_cl_demo_app_053` ) ( group = `Basic II` header = `Table` sub = `Selection Modes: Single Select & Multi Select` app = `z2ui5_cl_demo_app_019` ) ( group = `Basic II` header = `Table` sub = `Table with ScrollContainer` app = `z2ui5_cl_demo_app_006` ) + ( group = `Basic II` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) + ( group = `Basic II` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) ( group = `Basic II` header = `Tree` sub = `Drag and Drop (A,C)` app = `z2ui5_cl_demo_app_461` ) ( group = `Basic II` header = `Tree` sub = `Editable with Custom Item (C)` app = `z2ui5_cl_demo_app_463` ) ( group = `Basic II` header = `Tree` sub = `Inside Popup (C)` app = `z2ui5_cl_demo_app_462` ) From da220f95fdbeadf3ebf943e1fd7d2194e4b0920f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 26 Jul 2026 11:06:54 +0000 Subject: [PATCH 5/7] Build out app_319 into a full SmartMultiInput SELECT-OPTIONS demo Turns the WIP SmartMultiInput sample into an end-to-end demo of the control's strength: define conditions on Product Type via the OData value help (contains, between, greater-than, exclude, several at once) and the backend translates the returned ranges into a real ABAP RANGE (do_search: Contains -> CP *x*, StartsWith/EndsWith -> CP, BT, GT/GE/LT/LE, exclude -> SIGN 'E') and filters a local demo product list with `... WHERE product_type IN `. The derived SELECT-OPTIONS (SIGN/OPTION/LOW/HIGH) and the matching rows are both shown, plus a live match count. Removed the debug range-content message box; kept the ProductType / UI_PRODUCTLIST OData wiring. Also regenerated the overview catalog to mirror the current tree. --- src/00/00/z2ui5_cl_demo_app_319.clas.abap | 196 +++++++++++++++++++--- src/00/z2ui5_cl_sample_app_g01.clas.abap | 7 +- src/01/z2ui5_cl_demo_app_g00.clas.abap | 34 ++-- 3 files changed, 192 insertions(+), 45 deletions(-) diff --git a/src/00/00/z2ui5_cl_demo_app_319.clas.abap b/src/00/00/z2ui5_cl_demo_app_319.clas.abap index 81c34a2c..4327b7ab 100644 --- a/src/00/00/z2ui5_cl_demo_app_319.clas.abap +++ b/src/00/00/z2ui5_cl_demo_app_319.clas.abap @@ -1,3 +1,17 @@ +"! SmartMultiInput (sap.ui.comp) - the strength of one control: it gives the user +"! a full SELECT-OPTIONS experience (value help from OData, multiple conditions, +"! operators like contains / between / greater-than, and include/exclude) and +"! hands the backend a structured range that maps 1:1 onto an ABAP SELECT-OPTIONS. +"! +"! This demo wires that end to end: define conditions on "Product Type" via the +"! value help, and the backend translates the returned ranges into an ABAP range +"! table (r in ty_s_range -> SIGN/OPTION/LOW/HIGH) and filters a local product +"! list with `... WHERE product_type IN `. Both the derived SELECT-OPTIONS +"! and the matching rows are shown, so the "UI condition -> ABAP range" mapping is +"! visible. +"! +"! Needs SAPUI5 (sap.ui.comp is SAPUI5-only) and a reachable, value-list-annotated +"! OData V2 service - see the OData service block in on_init. CLASS z2ui5_cl_demo_app_319 DEFINITION PUBLIC. PUBLIC SECTION. @@ -20,6 +34,20 @@ CLASS z2ui5_cl_demo_app_319 DEFINITION PUBLIC. tokenlongkey TYPE string, END OF ty_s_range, t_ranges TYPE STANDARD TABLE OF ty_s_range WITH EMPTY KEY. + TYPES: + BEGIN OF ty_s_product, + product_type TYPE string, + name TYPE string, + END OF ty_s_product. + TYPES: + " display row for the derived SELECT-OPTIONS (plain strings so binding + " serializes safely everywhere; the real RANGE is only built locally) + BEGIN OF ty_s_selopt, + sign TYPE string, + option TYPE string, + low TYPE string, + high TYPE string, + END OF ty_s_selopt. DATA: BEGIN OF m_selection, @@ -30,11 +58,18 @@ CLASS z2ui5_cl_demo_app_319 DEFINITION PUBLIC. END OF product_type, END OF m_selection. + " local demo data (source) + the filtered result + the derived SELECT-OPTIONS + DATA t_product TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY. + DATA t_result TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY. + DATA t_selopt TYPE STANDARD TABLE OF ty_s_selopt WITH EMPTY KEY. + DATA hint TYPE string. + PROTECTED SECTION. DATA m_client TYPE REF TO z2ui5_if_client. METHODS on_init. METHODS on_event. + METHODS do_search. PRIVATE SECTION. ENDCLASS. @@ -47,7 +82,6 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. m_client = client. IF m_client->check_on_init( ). - on_init( ). RETURN. ENDIF. @@ -59,51 +93,163 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. METHOD on_init. - DATA(l_view) = z2ui5_cl_xml_view=>factory( ). + " local demo product list the derived range filters (see class doc). The + " product types are readable words so the "contains"/"starts with" operators + " visibly hit something when you type free text into the value help. + t_product = VALUE #( + ( product_type = `SERVICE` name = `Cloud Hosting` ) + ( product_type = `SERVER` name = `Rack Server X1` ) + ( product_type = `SENSOR` name = `IoT Sensor` ) + ( product_type = `SOFTWARE` name = `ERP License` ) + ( product_type = `HARDWARE` name = `Laptop Pro` ) + ( product_type = `MATERIAL` name = `Steel Sheet` ) + ( product_type = `SUPPORT` name = `Gold Support` ) + ( product_type = `TRAINING` name = `ABAP Course` ) + ( product_type = `LICENSE` name = `DB License` ) + ( product_type = `SEMIFIN` name = `Semi-finished Part` ) ). + t_result = t_product. + hint = `No conditions yet - showing all demo products. Open the value help and add conditions.`. + + DATA(view) = z2ui5_cl_xml_view=>factory( ). - DATA(l_page) = l_view->shell( )->page( title = `SearchPage` + DATA(page) = view->shell( )->page( title = `SmartMultiInput - conditions to ABAP SELECT-OPTIONS` navbuttonpress = m_client->_event_nav_app_leave( ) shownavbutton = m_client->check_app_prev_stack( ) ). - l_page->_z2ui5( )->smartmultiinput_ext( + page->message_strip( + text = `Open the value help (icon on the right), add one or more conditions on Product Type ` && + `(contains, between, greater than, exclude ...). Each condition is turned into an ABAP ` && + `SELECT-OPTIONS row and filters the demo product list below.` + type = `Information` + showicon = abap_true + class = `sapUiSmallMargin` ). + + " the invisible companion mirrors tokens + range data into the (switched) app + " model so the backend can read AND restore the input across roundtrips + page->_z2ui5( )->smartmultiinput_ext( addedtokens = m_client->_bind_edit( val = m_selection-product_type-tokens_added switch_default_model = abap_true ) removedtokens = m_client->_bind_edit( val = m_selection-product_type-tokens_removed switch_default_model = abap_true ) rangedata = m_client->_bind_edit( val = m_selection-product_type-ranges switch_default_model = abap_true ) change = m_client->_event( `PRODTYPE_CHANGED` ) multiinputid = `ProductTypeMultiInput` ). - l_page->smart_multi_input( + page->smart_multi_input( id = `ProductTypeMultiInput` - value = '{ProductType}' -* value = `{CurrencyCode}` -* entityset = `Booking` + value = `{ProductType}` entityset = `ProductType_2` supportranges = `true` enableodataselect = `true` ). - m_client->view_display( val = l_page->stringify( ) - switch_default_model_path = `/sap/opu/odata/sap/UI_PRODUCTLIST` -* switch_default_model_path = `/sap/opu/odata/DMO/UI_TRAVEL_A_D_O2` - switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='UI_PRODUCTLIST_VAN',Version='0001')/$value` -* switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='%2FDMO%2FUI_TRAVEL_A_D_O2_VAN',Version='0001')/$value` - ). + page->button( text = `Search` + type = `Emphasized` + icon = `sap-icon://search` + press = m_client->_event( `SEARCH` ) + class = `sapUiSmallMarginBegin` ). + + page->object_status( text = m_client->_bind( val = hint switch_default_model = abap_true ) + class = `sapUiSmallMargin` ). + + " derived ABAP SELECT-OPTIONS (r_product_type): SIGN / OPTION / LOW / HIGH + DATA(sel) = page->table( m_client->_bind( val = t_selopt switch_default_model = abap_true ) ). + sel->header_toolbar( )->overflow_toolbar( )->title( `Derived ABAP SELECT-OPTIONS ( ... WHERE ProductType IN r_product_type )` ). + sel->columns( + )->column( )->text( `SIGN` )->get_parent( + )->column( )->text( `OPTION` )->get_parent( + )->column( )->text( `LOW` )->get_parent( + )->column( )->text( `HIGH` ). + sel->items( + )->column_list_item( + )->cells( + )->text( `{SIGN}` + )->text( `{OPTION}` + )->text( `{LOW}` + )->text( `{HIGH}` ). + + " the rows the range selects out of the demo product list + DATA(res) = page->table( m_client->_bind( val = t_result switch_default_model = abap_true ) ). + res->header_toolbar( )->overflow_toolbar( )->title( `Matching demo products (local sample data)` ). + res->columns( + )->column( )->text( `Product Type` )->get_parent( + )->column( )->text( `Name` ). + res->items( + )->column_list_item( + )->cells( + )->text( `{PRODUCT_TYPE}` + )->text( `{NAME}` ). + + " OData service block - adjust to your value-list-annotated Gateway service. + " The SmartMultiInput's value help (Product Type) comes from here; the demo + " filter above is pure ABAP and independent of it. + m_client->view_display( val = page->stringify( ) + switch_default_model_path = `/sap/opu/odata/sap/UI_PRODUCTLIST` + switch_default_model_anno_uri = `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/Annotations(TechnicalName='UI_PRODUCTLIST_VAN',Version='0001')/$value` ). ENDMETHOD. METHOD on_event. - IF m_client->check_on_event( `PRODTYPE_CHANGED` ). -* INSERT VALUE #( operation = `EQ` value1 = `EUR` keyfield = `CurrencyCode` tokentext = `Euro (auto added line)` ) INTO TABLE m_selection-product_type-ranges. -* INSERT VALUE #( operation = `EQ` value1 = `EUR` keyfield = `ProductType` tokentext = `Euro (auto added line)` ) INTO TABLE m_selection-product_type-ranges. - m_client->view_model_update( ). - TRY. - m_client->message_box_display( - text = z2ui5_cl_ajson=>new( )->set( iv_path = `/` iv_val = m_selection-product_type-ranges )->stringify( ) - title = `range content` ). - CATCH z2ui5_cx_ajson_error INTO DATA(lx_ajson). - m_client->message_toast_display( lx_ajson->get_text( ) ). - ENDTRY. + CASE m_client->get( )-event. + WHEN `PRODTYPE_CHANGED` OR `SEARCH`. + do_search( ). + m_client->view_model_update( ). + ENDCASE. + + ENDMETHOD. + + + METHOD do_search. + + " translate the UI5 range operators the SmartMultiInput returns into ABAP + " SELECT-OPTIONS. This is the payoff: a rich UI filter becomes a real ABAP + " RANGE (lr_type) you drop straight into any SELECT; t_selopt is just its + " readable copy for the display table. + DATA lr_type TYPE RANGE OF string. + DATA sign TYPE c LENGTH 1. + DATA option TYPE c LENGTH 2. + DATA low TYPE string. + DATA high TYPE string. + + t_selopt = VALUE #( ). + lr_type = VALUE #( ). + LOOP AT m_selection-product_type-ranges INTO DATA(s). + + sign = COND #( WHEN s-exclude = abap_true THEN `E` ELSE `I` ). + option = `EQ`. + low = s-value1. + high = s-value2. + + CASE to_upper( s-operation ). + WHEN `EQ`. option = `EQ`. + WHEN `NE`. option = `NE`. + WHEN `CONTAINS`. option = `CP`. low = |*{ s-value1 }*|. + WHEN `NOTCONTAINS`. option = `CP`. low = |*{ s-value1 }*|. sign = `E`. + WHEN `STARTSWITH`. option = `CP`. low = |{ s-value1 }*|. + WHEN `ENDSWITH`. option = `CP`. low = |*{ s-value1 }|. + WHEN `BT`. option = `BT`. + WHEN `NB`. option = `NB`. + WHEN `GT`. option = `GT`. + WHEN `GE`. option = `GE`. + WHEN `LT`. option = `LT`. + WHEN `LE`. option = `LE`. + WHEN `EMPTY`. option = `EQ`. low = ``. + WHEN OTHERS. option = `EQ`. + ENDCASE. + + APPEND VALUE #( sign = sign option = option low = low high = high ) TO lr_type. + APPEND VALUE #( sign = sign option = option low = low high = high ) TO t_selopt. + ENDLOOP. + + " apply the derived SELECT-OPTIONS just like any ABAP query would + t_result = VALUE #( ). + IF lr_type IS INITIAL. + t_result = t_product. + hint = |No conditions - showing all { lines( t_product ) } demo products.|. + ELSE. + LOOP AT t_product INTO DATA(p) WHERE product_type IN lr_type. + APPEND p TO t_result. + ENDLOOP. + hint = |{ lines( t_selopt ) } condition(s) -> { lines( t_result ) } of { lines( t_product ) } demo products match.|. ENDIF. ENDMETHOD. diff --git a/src/00/z2ui5_cl_sample_app_g01.clas.abap b/src/00/z2ui5_cl_sample_app_g01.clas.abap index 2c880cf8..7aac5a12 100644 --- a/src/00/z2ui5_cl_sample_app_g01.clas.abap +++ b/src/00/z2ui5_cl_sample_app_g01.clas.abap @@ -214,8 +214,9 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. METHOD get_catalog. result = VALUE #( - ( group = `extended` header = `tab` sub = `different odata models` app = `z2ui5_cl_demo_app_315` ) - ( group = `extended` header = `tab` sub = `odata, device, http` app = `z2ui5_cl_demo_app_314` ) + ( group = `extended` header = `EXPERIMENTAL` sub = `Smart Multi Input` app = `z2ui5_cl_demo_app_319` ) + ( group = `extended` header = `EXPERIMENTAL` sub = `Smart Table and Variants` app = `z2ui5_cl_demo_app_313` ) + ( group = `extended` header = `EXPERIMENTAL` sub = `Switch default Model` app = `z2ui5_cl_demo_app_314` ) ( group = `only non-abap-cloud` header = `Conversion Exits` sub = `` app = `z2ui5_cl_demo_app_s_04` ) ( group = `only non-abap-cloud` header = `Generated APC WebSocket protocol impementation class` sub = `` app = `z2ui5_cl_demo_app_s_05_ws` ) ( group = `only non-abap-cloud` header = `Navigation with app state change v2` sub = `` app = `z2ui5_cl_demo_app_s_06` ) @@ -234,13 +235,11 @@ CLASS z2ui5_cl_sample_app_g01 IMPLEMENTATION. ( group = `only non-openui5 or higher UI5 1.71` header = `more` sub = `ndc scanner (since 1.102)` app = `z2ui5_cl_demo_app_124` ) ( group = `only non-openui5 or higher UI5 1.71` header = `more` sub = `timeline` app = `z2ui5_cl_demo_app_113` ) ( group = `only non-openui5 or higher UI5 1.71` header = `networkgraph` sub = `org tree` app = `z2ui5_cl_demo_app_182` ) - ( group = `only non-openui5 or higher UI5 1.71` header = `odata, smartmultiinput` sub = `` app = `z2ui5_cl_demo_app_319` ) ( group = `only non-openui5 or higher UI5 1.71` header = `sap.ui.RichTextEditor` sub = `` app = `z2ui5_cl_demo_app_106` ) ( group = `only non-openui5 or higher UI5 1.71` header = `sap.webc.TabContainer` sub = `Multiple Items` app = `z2ui5_cl_demo_app_380` ) ( group = `only non-openui5 or higher UI5 1.71` header = `Side Panel (since 1.107)` sub = `` app = `z2ui5_cl_demo_app_108` ) ( group = `only non-openui5 or higher UI5 1.71` header = `Standard List Item` sub = `Info State Inverted (since 1.74)` app = `z2ui5_cl_demo_app_286` ) ( group = `only non-openui5 or higher UI5 1.71` header = `status indicator` sub = `` app = `z2ui5_cl_demo_app_196` ) - ( group = `only non-openui5 or higher UI5 1.71` header = `tab` sub = `smart controls` app = `z2ui5_cl_demo_app_313` ) ( group = `only non-openui5 or higher UI5 1.71` header = `tab` sub = `toolbar container sort` app = `z2ui5_cl_demo_app_177` ) ( group = `only non-openui5 or higher UI5 1.71` header = `table columnmenu (since 1.110)` sub = `` app = `z2ui5_cl_demo_app_183` ) ( group = `only non-openui5 or higher UI5 1.71` header = `ui table` sub = `` app = `z2ui5_cl_demo_app_100` ) diff --git a/src/01/z2ui5_cl_demo_app_g00.clas.abap b/src/01/z2ui5_cl_demo_app_g00.clas.abap index 3dabfa3a..93baa935 100644 --- a/src/01/z2ui5_cl_demo_app_g00.clas.abap +++ b/src/01/z2ui5_cl_demo_app_g00.clas.abap @@ -213,21 +213,33 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Binding` sub = `Formatting Integers, Decimals, Dates & Time` app = `z2ui5_cl_demo_app_047` ) ( group = `Basic I` header = `Binding` sub = `Level Structure/Component` app = `z2ui5_cl_demo_app_166` ) ( group = `Basic I` header = `Binding` sub = `Level Table/Cell` app = `z2ui5_cl_demo_app_144` ) + ( group = `Basic I` header = `Browser` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) + ( group = `Basic I` header = `Browser` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) + ( group = `Basic I` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) + ( group = `Basic I` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) + ( group = `Basic I` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) + ( group = `Basic I` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) ( group = `Basic I` header = `Event` sub = `Additional Infos with t_args` app = `z2ui5_cl_demo_app_167` ) ( group = `Basic I` header = `Event` sub = `Facet Filter T_arg with Objects` app = `z2ui5_cl_demo_app_197` ) ( group = `Basic I` header = `Event` sub = `Handle events & change the view` app = `z2ui5_cl_demo_app_004` ) + ( group = `Basic I` header = `EXPERIMENTAL` sub = `Navigation - Routing modes` app = `z2ui5_cl_demo_app_468` ) + ( group = `Basic I` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) + ( group = `Basic I` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) + ( group = `Basic I` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) ( group = `Basic I` header = `Formatter` sub = `Date Object for DatePicker` app = `z2ui5_cl_demo_app_457` ) ( group = `Basic I` header = `Formatter` sub = `Date Objects for PlanningCalendar` app = `z2ui5_cl_demo_app_456` ) ( group = `Basic I` header = `Formatter` sub = `Inline Icons` app = `z2ui5_cl_demo_app_466` ) ( group = `Basic I` header = `Formatter` sub = `Simple` app = `z2ui5_cl_demo_app_453` ) ( group = `Basic I` header = `Formatter` sub = `Use via core:require` app = `z2ui5_cl_demo_app_450` ) ( group = `Basic I` header = `Message` sub = `Backend Processing` app = `z2ui5_cl_demo_app_008` ) + ( group = `Basic I` header = `Message` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) + ( group = `Basic I` header = `Message` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Message` sub = `MessageBox` app = `z2ui5_cl_demo_app_382` ) ( group = `Basic I` header = `Message` sub = `MessageToast` app = `z2ui5_cl_demo_app_381` ) ( group = `Basic I` header = `Message` sub = `MessageView` app = `z2ui5_cl_demo_app_452` ) ( group = `Basic I` header = `Model` sub = `Device Model` app = `z2ui5_cl_demo_app_445` ) - ( group = `Basic I` header = `Model` sub = `Message Model` app = `z2ui5_cl_demo_app_458` ) ( group = `Basic I` header = `Model` sub = `Set Size Limit` app = `z2ui5_cl_demo_app_071` ) + ( group = `Basic I` header = `Model` sub = `Use OData models` app = `z2ui5_cl_demo_app_315` ) ( group = `Basic I` header = `More` sub = `Call and leave to apps` app = `z2ui5_cl_demo_app_024` ) ( group = `Basic I` header = `More` sub = `Error Handling` app = `z2ui5_cl_demo_app_464` ) ( group = `Basic I` header = `More` sub = `Generic Data Reference` app = `z2ui5_cl_demo_app_061` ) @@ -241,20 +253,16 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic I` header = `Popover` sub = `Item Level of Table` app = `z2ui5_cl_demo_app_052` ) ( group = `Basic I` header = `Popover` sub = `List to select in Popover` app = `z2ui5_cl_demo_app_081` ) ( group = `Basic I` header = `Popover` sub = `Simple Example` app = `z2ui5_cl_demo_app_026` ) + ( group = `Basic I` header = `Popup` sub = `Aggregation binding to the selected row` app = `z2ui5_cl_demo_app_470` ) ( group = `Basic I` header = `Popup` sub = `Different ways of calling Popups` app = `z2ui5_cl_demo_app_012` ) ( group = `Basic I` header = `Popup` sub = `Popup in Popup - Backend Stack Handling` app = `z2ui5_cl_demo_app_161` ) ( group = `Basic I` header = `Popup` sub = `Value Help with Popups` app = `z2ui5_cl_demo_app_009` ) + ( group = `Basic I` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) + ( group = `Basic I` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic I` header = `Templating` sub = `Basic Example` app = `z2ui5_cl_demo_app_173` ) ( group = `Basic I` header = `Templating` sub = `Nested Views` app = `z2ui5_cl_demo_app_176` ) - ( group = `Basic II` header = `Browser` sub = `Logout (A)` app = `z2ui5_cl_demo_app_361` ) - ( group = `Basic II` header = `Browser` sub = `Open an URL in a new tab (A)` app = `z2ui5_cl_demo_app_073` ) - ( group = `Basic II` header = `Browser` sub = `Open Telephon, Email usw (A)` app = `z2ui5_cl_demo_app_316` ) - ( group = `Basic II` header = `Browser` sub = `Title (A)` app = `z2ui5_cl_demo_app_125` ) - ( group = `Basic II` header = `Focus` sub = `Focus Aggregations` app = `z2ui5_cl_demo_app_421` ) - ( group = `Basic II` header = `Focus` sub = `Jump with the focus (A)` app = `z2ui5_cl_demo_app_189` ) - ( group = `Basic II` header = `Focus` sub = `Set Focus in Textfield (A)` app = `z2ui5_cl_demo_app_133` ) - ( group = `Basic II` header = `Input` sub = `Clipboard (A)` app = `z2ui5_cl_demo_app_325` ) - ( group = `Basic II` header = `Input` sub = `Hide/show Soft Keyboard (A)` app = `z2ui5_cl_demo_app_352` ) + ( group = `Basic I` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) + ( group = `Basic I` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) ( group = `Basic II` header = `List` sub = `Events & Visualization` app = `z2ui5_cl_demo_app_048` ) ( group = `Basic II` header = `List` sub = `Frontend Filter/Sort via Backend Event (A)` app = `z2ui5_cl_demo_app_454` ) ( group = `Basic II` header = `List` sub = `Frontend Live Filter without Backend (A)` app = `z2ui5_cl_demo_app_455` ) @@ -262,7 +270,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Data Loss Protection (C)` app = `z2ui5_cl_demo_app_279` ) ( group = `Basic II` header = `More` sub = `File Uploader (C)` app = `z2ui5_cl_demo_app_074` ) ( group = `Basic II` header = `More` sub = `Geoloaction (C)` app = `z2ui5_cl_demo_app_120` ) - ( group = `Basic II` header = `More` sub = `Message Manager (C)` app = `z2ui5_cl_demo_app_467` ) ( group = `Basic II` header = `More` sub = `Multi Input (C)` app = `z2ui5_cl_demo_app_078` ) ( group = `Basic II` header = `More` sub = `Panel, setExpanded (A)` app = `z2ui5_cl_demo_app_448` ) ( group = `Basic II` header = `More` sub = `PDF Viewer Display (A)` app = `z2ui5_cl_demo_app_449` ) @@ -270,9 +277,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `More` sub = `Wizard Control (A)` app = `z2ui5_cl_demo_app_202` ) ( group = `Basic II` header = `NavContainer` sub = `Popup (A)` app = `z2ui5_cl_demo_app_170` ) ( group = `Basic II` header = `NavContainer` sub = `Simple (A)` app = `z2ui5_cl_demo_app_088` ) - ( group = `Basic II` header = `Navigation` sub = `Routing modes (default / fresh / keep)` app = `z2ui5_cl_demo_app_468` ) - ( group = `Basic II` header = `Scroll` sub = `Scroll into view (A)` app = `z2ui5_cl_demo_app_363` ) - ( group = `Basic II` header = `Scroll` sub = `Scroll to position (A)` app = `z2ui5_cl_demo_app_362` ) ( group = `Basic II` header = `Table` sub = `Backend Filter` app = `z2ui5_cl_demo_app_045` ) ( group = `Basic II` header = `Table` sub = `Drag and Drop (A)` app = `z2ui5_cl_demo_app_459` ) ( group = `Basic II` header = `Table` sub = `Editable` app = `z2ui5_cl_demo_app_011` ) @@ -280,8 +284,6 @@ CLASS z2ui5_cl_demo_app_g00 IMPLEMENTATION. ( group = `Basic II` header = `Table` sub = `Search via Backend` app = `z2ui5_cl_demo_app_053` ) ( group = `Basic II` header = `Table` sub = `Selection Modes: Single Select & Multi Select` app = `z2ui5_cl_demo_app_019` ) ( group = `Basic II` header = `Table` sub = `Table with ScrollContainer` app = `z2ui5_cl_demo_app_006` ) - ( group = `Basic II` header = `Timer` sub = `Loading Indicator with WAIT UP Backend (A)` app = `z2ui5_cl_demo_app_064` ) - ( group = `Basic II` header = `Timer` sub = `Wait n MS and call again the server (A)` app = `z2ui5_cl_demo_app_028` ) ( group = `Basic II` header = `Tree` sub = `Drag and Drop (A,C)` app = `z2ui5_cl_demo_app_461` ) ( group = `Basic II` header = `Tree` sub = `Editable with Custom Item (C)` app = `z2ui5_cl_demo_app_463` ) ( group = `Basic II` header = `Tree` sub = `Inside Popup (C)` app = `z2ui5_cl_demo_app_462` ) From a0a9d7a823fbc201447daaacfa1fd8cf85ecf7af Mon Sep 17 00:00:00 2001 From: oblomov Date: Sun, 26 Jul 2026 11:39:00 +0000 Subject: [PATCH 6/7] fix --- src/00/00/z2ui5_cl_demo_app_319.clas.abap | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/00/00/z2ui5_cl_demo_app_319.clas.abap b/src/00/00/z2ui5_cl_demo_app_319.clas.abap index 4327b7ab..59752e4e 100644 --- a/src/00/00/z2ui5_cl_demo_app_319.clas.abap +++ b/src/00/00/z2ui5_cl_demo_app_319.clas.abap @@ -160,10 +160,10 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. sel->items( )->column_list_item( )->cells( - )->text( `{SIGN}` - )->text( `{OPTION}` - )->text( `{LOW}` - )->text( `{HIGH}` ). + )->text( `{http>SIGN}` + )->text( `{http>OPTION}` + )->text( `{http>LOW}` + )->text( `{http>HIGH}` ). " the rows the range selects out of the demo product list DATA(res) = page->table( m_client->_bind( val = t_result switch_default_model = abap_true ) ). @@ -174,8 +174,8 @@ CLASS z2ui5_cl_demo_app_319 IMPLEMENTATION. res->items( )->column_list_item( )->cells( - )->text( `{PRODUCT_TYPE}` - )->text( `{NAME}` ). + )->text( `{http>PRODUCT_TYPE}` + )->text( `{http>NAME}` ). " OData service block - adjust to your value-list-annotated Gateway service. " The SmartMultiInput's value help (Product Type) comes from here; the demo From 15579f6ba5f029682b6db3923a9996295474580b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 26 Jul 2026 11:58:07 +0000 Subject: [PATCH 7/7] Fix abaplint omit_parameter_name in samples 470 and 315 - app_470: vbox( class = ... ) -> vbox( ... ) (class is the PREFERRED parameter) - app_315: view_display( val = ... ) -> view_display( ... ) (val is the first, mandatory parameter) These only surface with full framework symbol resolution (CI), not in a formatting-only lint. The remaining ABAP_STANDARD errors on app_468 (cs_nav_mode / set_nav_routing) are the cross-repo dependency on abap2UI5#2476 and clear once that framework change is on main. --- src/01/01/z2ui5_cl_demo_app_315.clas.abap | 2 +- src/01/01/z2ui5_cl_demo_app_470.clas.abap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/01/01/z2ui5_cl_demo_app_315.clas.abap b/src/01/01/z2ui5_cl_demo_app_315.clas.abap index 55382f5c..5f6aef6a 100644 --- a/src/01/01/z2ui5_cl_demo_app_315.clas.abap +++ b/src/01/01/z2ui5_cl_demo_app_315.clas.abap @@ -59,7 +59,7 @@ CLASS z2ui5_cl_demo_app_315 IMPLEMENTATION. )->text( `{FLIGHT>City}` )->text( `{FLIGHT>CountryCode}` ). - client->view_display( val = view->stringify( ) + client->view_display( view->stringify( ) * switch_default_model_path = `` ). diff --git a/src/01/01/z2ui5_cl_demo_app_470.clas.abap b/src/01/01/z2ui5_cl_demo_app_470.clas.abap index 52d5bedb..4a7eb9c3 100644 --- a/src/01/01/z2ui5_cl_demo_app_470.clas.abap +++ b/src/01/01/z2ui5_cl_demo_app_470.clas.abap @@ -125,7 +125,7 @@ CLASS z2ui5_cl_demo_app_470 IMPLEMENTATION. contentwidth = `24rem` ). " relative bindings - resolved by the element bind below - DATA(box) = dialog->vbox( class = `sapUiSmallMarginBegin sapUiSmallMarginTop` ). + DATA(box) = dialog->vbox( `sapUiSmallMarginBegin sapUiSmallMarginTop` ). box->object_status( title = `Category` text = `{CATEGORY}` ). box->object_status( title = `Price` text = `{PRICE} EUR` ).