From 83b59872a31771dadf5c129e201c0b616f3f9cbd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 06:05:00 +0000 Subject: [PATCH] Add sample 493 - classic FilterBar wired to variant management cs_event-filter_bar_variant_init had no sample anywhere in the ecosystem, and it is the event that saves the most code: a classic sap.ui.comp.filterbar.FilterBar knows nothing about variants, so a list report normally hand-writes registerFetchData / registerApplyData / registerGetFiltersWithValues, an addPersonalizableControl( ) with a PersonalizableInfo, and a change handler per filter field. The action does all of it, so the app needs no JavaScript at all. 478 is the neighbouring case and shows why this one is separate: a SmartFilterBar knows its fields from OData metadata and registers itself, so it only needs smart_variant_init to place the anchor. Unlike the rest of the package this sample needs no service - a classic FilterBar builds from what the app names, and the three filter controls are ordinary two-way bound sap.m inputs over an ABAP table. That is also what makes the payoff visible: selecting a saved variant puts the values back into the fields AND, through the binding, into ABAP, so Go filters on the restored values without a roundtrip of its own. Registered in the package README, the overview app and the repository sample count. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01LLqG5572QgSgbhfAWm7RAp --- README.md | 2 +- src/02/README.md | 3 +- src/02/z2ui5_cl_smpe_app_493.clas.abap | 184 +++++++++++++++++++++++++ src/02/z2ui5_cl_smpe_app_493.clas.xml | 16 +++ src/z2ui5_cl_smpe_app_00.clas.abap | 6 +- 5 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 src/02/z2ui5_cl_smpe_app_493.clas.abap create mode 100644 src/02/z2ui5_cl_smpe_app_493.clas.xml diff --git a/README.md b/README.md index 341f2c9..93e6e47 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ branch dropdown and you import that package, the overview app and nothing else: | [`mime`](../../tree/mime) | [`src/08`](src/08) — MIME Play Audio | Standard only, ≥ 7.50 | | [`launchpad`](../../tree/launchpad) | [`src/09`](src/09) — Launchpad | Cloud + Standard ≥ 7.40 SP08 | -The overview app ships on every branch and keeps listing **all 30 samples**, so it +The overview app ships on every branch and keeps listing **all 31 samples**, so it stays the catalogue of what the other branches hold — the ones that are not on your branch simply show up with a disabled Open button. diff --git a/src/02/README.md b/src/02/README.md index cfbf430..4ee4f7c 100644 --- a/src/02/README.md +++ b/src/02/README.md @@ -12,7 +12,7 @@ help and smart filtering for free. ## What you need **Release:** Cloud + Standard ≥ 7.40 SP08. The metadata does the work, so the ABAP -side of these eight samples asks for nothing beyond the release the package is +side of these nine samples asks for nothing beyond the release the package is written in — what they need is the service, not the platform. **Branch:** [`smart-controls`](https://github.com/abap2UI5/samples-ext/tree/smart-controls) @@ -36,6 +36,7 @@ written in — what they need is the service, not the platform. | [`477`](z2ui5_cl_smpe_app_477.clas.abap) | SmartFilterBar driving a SmartTable | `GWSAMPLE_BASIC` | | [`478`](z2ui5_cl_smpe_app_478.clas.abap) | page variant management | `GWSAMPLE_BASIC` | | [`479`](z2ui5_cl_smpe_app_479.clas.abap) | SmartChart with NavigationPopover | an analytical service — you supply it | +| [`493`](z2ui5_cl_smpe_app_493.clas.abap) | classic FilterBar wired to variant management | none — the data is ABAP | Start any of them with `?app_start=z2ui5_cl_smpe_app_`, or from the overview app `?app_start=z2ui5_cl_smpe_app_00`, which lists every sample of this repository. diff --git a/src/02/z2ui5_cl_smpe_app_493.clas.abap b/src/02/z2ui5_cl_smpe_app_493.clas.abap new file mode 100644 index 0000000..58c6fff --- /dev/null +++ b/src/02/z2ui5_cl_smpe_app_493.clas.abap @@ -0,0 +1,184 @@ +CLASS z2ui5_cl_smpe_app_493 DEFINITION PUBLIC. + + PUBLIC SECTION. + INTERFACES z2ui5_if_app. + + PROTECTED SECTION. + + TYPES: + BEGIN OF ty_s_product, + product TYPE string, + category TYPE string, + supplier TYPE string, + price TYPE string, + END OF ty_s_product. + TYPES ty_t_product TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY. + + TYPES: + BEGIN OF ty_s_filter, + product TYPE string, + category TYPE string, + supplier TYPE string, + END OF ty_s_filter. + + DATA ms_filter TYPE ty_s_filter. + DATA mt_result TYPE ty_t_product. + + METHODS data_all + RETURNING + VALUE(result) TYPE ty_t_product. + + METHODS search. + + PRIVATE SECTION. +ENDCLASS. + + +CLASS z2ui5_cl_smpe_app_493 IMPLEMENTATION. + + METHOD z2ui5_if_app~main. + + IF client->check_on_init( ). + + mt_result = data_all( ). + + DATA(view) = z2ui5_cl_xml_view=>factory( ). + + DATA(page) = view->shell( + )->page( + title = `abap2UI5 - Smart Controls - Classic FilterBar Variants` + navbuttonpress = client->_event_nav_app_leave( ) + shownavbutton = client->check_app_prev_stack( ) ). + + page->message_strip( + text = `Enter filters, press Go, then save the selection as a variant. ` + && `Selecting it again restores the values into the fields AND into ` + && `ABAP - the two-way binding carries them back, so Go filters on ` + && `the restored values without any extra wiring.` + type = `Information` + showicon = abap_true + class = `sapUiSmallMargin` ). + + " The variant container. It owns the persistency (sap.ui.fl / LREP) and + " is the only piece a SmartFilterBar would bring along by itself - see + " sample 478 for that variant of the same screen. + page->hbox( + )->smart_variant_management( + id = `variantMgmt` + persistencykey = `Z2UI5_493_VARIANT` ). + + " A CLASSIC sap.ui.comp.filterbar.FilterBar: unlike a SmartFilterBar it + " has no OData metadata to build itself from, so its filters are named + " here and their controls are ordinary sap.m inputs, bound two-way like + " in any other abap2UI5 app. persistencykey is what the variant is + " stored under - the wiring action below hands it to the variant + " management as the PersonalizableInfo keyName. + DATA(filter) = page->filter_bar( + id = `filterBar` + persistencykey = `Z2UI5_493_FILTERBAR` + usetoolbar = `false` + search = client->_event( `SEARCH` ) + )->filter_group_items( ). + + filter->filter_group_item( + name = `PRODUCT` + label = `Product` + groupname = `__BASIC` + visibleinfilterbar = `true` + )->filter_control( + )->input( client->_bind( ms_filter-product ) ). + + filter->filter_group_item( + name = `CATEGORY` + label = `Category` + groupname = `__BASIC` + visibleinfilterbar = `true` + )->filter_control( + )->input( client->_bind( ms_filter-category ) ). + + filter->filter_group_item( + name = `SUPPLIER` + label = `Supplier` + groupname = `__BASIC` + visibleinfilterbar = `true` + )->filter_control( + )->input( client->_bind( ms_filter-supplier ) ). + + DATA(tab) = page->table( items = client->_bind( mt_result ) + headertext = `Products` ). + + tab->columns( + )->column( )->text( `Product` )->get_parent( + )->column( )->text( `Category` )->get_parent( + )->column( )->text( `Supplier` )->get_parent( + )->column( )->text( `Price` ). + + tab->items( )->column_list_item( + )->cells( + )->text( `{PRODUCT}` + )->text( `{CATEGORY}` + )->text( `{SUPPLIER}` + )->text( `{PRICE}` ). + + client->view_display( view->stringify( ) ). + + " Everything a list-report controller would hand-write for a classic + " FilterBar: registerFetchData / registerApplyData / + " registerGetFiltersWithValues, addPersonalizableControl( ) with a + " PersonalizableInfo, and a change handler per filter field that marks + " the variant as modified. All of it is boilerplate over the bar's own + " filter items, so the framework owns it and this app writes no + " JavaScript. A SmartFilterBar registers itself instead and only needs + " cs_event-smart_variant_init (sample 478). + client->follow_up_action( val = client->cs_event-filter_bar_variant_init + t_arg = VALUE #( ( `variantMgmt` ) ( `filterBar` ) ) ). + + RETURN. + ENDIF. + + CASE client->get_event( ). + WHEN `SEARCH`. + search( ). + client->message_toast_display( |{ lines( mt_result ) } products| ). + ENDCASE. + + ENDMETHOD. + + + METHOD search. + + " the restored variant values arrived through the two-way binding of the + " filter controls, so ms_filter is already current here - selecting a + " variant needs no roundtrip of its own + mt_result = VALUE #( ). + LOOP AT data_all( ) INTO DATA(ls_row). + IF ms_filter-product IS NOT INITIAL AND ls_row-product NS ms_filter-product. + CONTINUE. + ENDIF. + IF ms_filter-category IS NOT INITIAL AND ls_row-category NS ms_filter-category. + CONTINUE. + ENDIF. + IF ms_filter-supplier IS NOT INITIAL AND ls_row-supplier NS ms_filter-supplier. + CONTINUE. + ENDIF. + INSERT ls_row INTO TABLE mt_result. + ENDLOOP. + + ENDMETHOD. + + + METHOD data_all. + + result = VALUE #( + ( product = `Notebook Basic 15` category = `Notebooks` supplier = `SAP` price = `956.00` ) + ( product = `Notebook Basic 17` category = `Notebooks` supplier = `SAP` price = `1249.00` ) + ( product = `ITelO Vault` category = `Storage` supplier = `ITelO` price = `299.00` ) + ( product = `Comfort Easy` category = `Storage` supplier = `Technocom` price = `1679.00` ) + ( product = `Ergo Screen E-I` category = `Monitors` supplier = `Technocom` price = `230.00` ) + ( product = `Flat Basic` category = `Monitors` supplier = `ITelO` price = `399.00` ) + ( product = `Smart Eye Blue` category = `Monitors` supplier = `SAP` price = `499.00` ) + ( product = `Gladiator MX` category = `Graphics` supplier = `Technocom` price = `89.00` ) ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/02/z2ui5_cl_smpe_app_493.clas.xml b/src/02/z2ui5_cl_smpe_app_493.clas.xml new file mode 100644 index 0000000..7a5da45 --- /dev/null +++ b/src/02/z2ui5_cl_smpe_app_493.clas.xml @@ -0,0 +1,16 @@ + + + + + + Z2UI5_CL_SMPE_APP_493 + E + Smart Controls - classic FilterBar variants + 1 + X + X + X + + + + diff --git a/src/z2ui5_cl_smpe_app_00.clas.abap b/src/z2ui5_cl_smpe_app_00.clas.abap index 0d79a5c..52753c3 100644 --- a/src/z2ui5_cl_smpe_app_00.clas.abap +++ b/src/z2ui5_cl_smpe_app_00.clas.abap @@ -421,7 +421,11 @@ CLASS z2ui5_cl_smpe_app_00 IMPLEMENTATION. ( sample( no = `479` title = `SmartChart with NavigationPopover` detail = `an analytical service - you supply the path` - classname = `Z2UI5_CL_SMPE_APP_479` ) ) ). + classname = `Z2UI5_CL_SMPE_APP_479` ) ) + ( sample( no = `493` + title = `Classic FilterBar with variant management` + detail = `no service needed - the data is ABAP` + classname = `Z2UI5_CL_SMPE_APP_493` ) ) ). t_rap = VALUE #( ( sample( no = `01`