diff --git a/AGENTS.md b/AGENTS.md
index c3cc5727..f5aaf658 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -54,6 +54,7 @@ src/
├── 05/ only with javascript and css and html needs native JS / CSS / HTML
├── 06/ only testing test / scaffolding apps, not demos
├── 07/ experimental, TODO work-in-progress / not finished
+ ├── 08/ framework - new (beta) needs framework features not yet in a stable release
└── 99/ obsolete superseded, or built on a deprecated UI5 control
```
@@ -120,7 +121,8 @@ The split is driven directly by the CI builds:
5. Needs native JavaScript / CSS / HTML → `00/05`
6. Test / scaffolding app → `00/06`
7. Experimental / work-in-progress → `00/07`
- 8. Deprecated control/property, or superseded → `00/99`
+ 8. Needs framework features not yet in a stable release (beta) → `00/08`
+ 9. Deprecated control/property, or superseded → `00/99`
A sample qualifies for `src/01` **only if none** of the above restrictions
apply: OpenUI5-compatible, ABAP-Cloud-ready, standalone, every control **and**
diff --git a/src/00/08/package.devc.xml b/src/00/08/package.devc.xml
new file mode 100644
index 00000000..dcda5754
--- /dev/null
+++ b/src/00/08/package.devc.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ framework - new (beta)
+ X
+
+
+
+
diff --git a/src/00/08/z2ui5_cl_demo_app_448.clas.abap b/src/00/08/z2ui5_cl_demo_app_448.clas.abap
new file mode 100644
index 00000000..b4fd7b21
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_448.clas.abap
@@ -0,0 +1,82 @@
+CLASS z2ui5_cl_demo_app_448 DEFINITION PUBLIC.
+
+ PUBLIC SECTION.
+ INTERFACES z2ui5_if_app.
+
+ PROTECTED SECTION.
+ DATA client TYPE REF TO z2ui5_if_client.
+ " not bound - mirrors the panel state so the toggle can invert it
+ DATA expanded TYPE abap_bool.
+
+ METHODS view_display.
+ METHODS on_event.
+
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+CLASS z2ui5_cl_demo_app_448 IMPLEMENTATION.
+
+ METHOD z2ui5_if_app~main.
+
+ me->client = client.
+ IF client->check_on_init( ).
+ view_display( ).
+ ELSE.
+ on_event( ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD on_event.
+
+ CASE client->get( )-event.
+
+ WHEN `TOGGLE`.
+ " invert the mirrored state and call the whitelisted setExpanded on
+ " the panel - client-side, after the response renders, no rebuild
+ expanded = xsdbool( expanded = abap_false ).
+ client->control_call_by_id( id = `demoPanel`
+ method = `setExpanded`
+ params = VALUE #( ( CONV string( expanded ) ) ) ).
+
+ ENDCASE.
+
+ ENDMETHOD.
+
+
+ METHOD view_display.
+
+ DATA(view) = z2ui5_cl_xml_view=>factory( ).
+
+ DATA(page) = view->shell(
+ )->page(
+ title = `abap2UI5 - Action - control_call_by_id setExpanded`
+ navbuttonpress = client->_event_nav_app_leave( )
+ shownavbutton = client->check_app_prev_stack( ) ).
+
+ page->message_strip(
+ text = `The button toggles the panel via the whitelisted setExpanded method ` &&
+ `(control_call_by_id), client-side after render - no view rebuild.`
+ type = `Information`
+ showicon = abap_true
+ class = `sapUiSmallMargin` ).
+
+ page->vbox( `sapUiSmallMargin`
+ )->button( text = `Toggle panel`
+ icon = `sap-icon://expand-group`
+ press = client->_event( `TOGGLE` ) ).
+
+ page->panel( id = `demoPanel`
+ headertext = `Collapsible panel`
+ expandable = abap_true
+ width = `auto`
+ class = `sapUiSmallMargin`
+ )->text( `Content of the panel - collapsed and expanded from the backend without a roundtrip payload.` ).
+
+ client->view_display( view->stringify( ) ).
+
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/src/00/08/z2ui5_cl_demo_app_448.clas.xml b/src/00/08/z2ui5_cl_demo_app_448.clas.xml
new file mode 100644
index 00000000..e930d7a8
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_448.clas.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Z2UI5_CL_DEMO_APP_448
+ E
+ Control Call - Panel setExpanded
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/00/08/z2ui5_cl_demo_app_449.clas.abap b/src/00/08/z2ui5_cl_demo_app_449.clas.abap
new file mode 100644
index 00000000..1d16a638
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_449.clas.abap
@@ -0,0 +1,80 @@
+CLASS z2ui5_cl_demo_app_449 DEFINITION PUBLIC.
+
+ PUBLIC SECTION.
+ INTERFACES z2ui5_if_app.
+
+ PROTECTED SECTION.
+ DATA client TYPE REF TO z2ui5_if_client.
+
+ METHODS view_display.
+ METHODS on_event.
+
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+CLASS z2ui5_cl_demo_app_449 IMPLEMENTATION.
+
+ METHOD z2ui5_if_app~main.
+
+ me->client = client.
+ IF client->check_on_init( ).
+ view_display( ).
+ ELSE.
+ on_event( ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD on_event.
+
+ CASE client->get( )-event.
+
+ WHEN `OPEN`.
+ " open the popup-mode PDFViewer via the whitelisted open method -
+ " the viewer brings its own dialog and close button
+ client->control_call_by_id( id = `demoPdf`
+ method = `open` ).
+
+ ENDCASE.
+
+ ENDMETHOD.
+
+
+ METHOD view_display.
+
+ DATA(view) = z2ui5_cl_xml_view=>factory( ).
+
+ DATA(page) = view->shell(
+ )->page(
+ title = `abap2UI5 - Action - control_call_by_id open`
+ navbuttonpress = client->_event_nav_app_leave( )
+ shownavbutton = client->check_app_prev_stack( ) ).
+
+ " a popup-mode PDFViewer kept as a dependent of the page; opened
+ " imperatively from the backend, like a controller calling oViewer.open()
+ page->dependents(
+ )->_generic( name = `PDFViewer`
+ t_prop = VALUE #( ( n = `id` v = `demoPdf` )
+ ( n = `title` v = `Sample PDF` )
+ ( n = `source` v = `https://sapui5.hana.ondemand.com/test-resources/sap/m/demokit/sample/PDFViewerPopup/sample1.pdf` )
+ ( n = `height` v = `100%` ) ) ).
+
+ page->message_strip(
+ text = `The button opens the popup-mode PDFViewer via the whitelisted open method ` &&
+ `(control_call_by_id), client-side after render.`
+ type = `Information`
+ showicon = abap_true
+ class = `sapUiSmallMargin` ).
+
+ page->vbox( `sapUiSmallMargin`
+ )->button( text = `Open PDF`
+ icon = `sap-icon://pdf-attachment`
+ press = client->_event( `OPEN` ) ).
+
+ client->view_display( view->stringify( ) ).
+
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/src/00/08/z2ui5_cl_demo_app_449.clas.xml b/src/00/08/z2ui5_cl_demo_app_449.clas.xml
new file mode 100644
index 00000000..638c9160
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_449.clas.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Z2UI5_CL_DEMO_APP_449
+ E
+ Control Call - PDFViewer open
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/00/08/z2ui5_cl_demo_app_450.clas.abap b/src/00/08/z2ui5_cl_demo_app_450.clas.abap
new file mode 100644
index 00000000..cabdad96
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_450.clas.abap
@@ -0,0 +1,83 @@
+CLASS z2ui5_cl_demo_app_450 DEFINITION PUBLIC.
+
+ PUBLIC SECTION.
+ INTERFACES z2ui5_if_app.
+
+ TYPES:
+ BEGIN OF ty_s_product,
+ name TYPE string,
+ measure TYPE string,
+ unit TYPE string,
+ END OF ty_s_product.
+ DATA t_products TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY.
+
+ PROTECTED SECTION.
+ DATA client TYPE REF TO z2ui5_if_client.
+
+ METHODS view_display.
+
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+CLASS z2ui5_cl_demo_app_450 IMPLEMENTATION.
+
+ METHOD z2ui5_if_app~main.
+
+ me->client = client.
+ IF client->check_on_init( ).
+ t_products = VALUE #(
+ ( name = `Comfort Easy` measure = `0.2` unit = `KG` )
+ ( name = `Notebook Basic 15` measure = `4.2` unit = `KG` )
+ ( name = `Ergo Screen E-I` measure = `21` unit = `KG` ) ).
+ view_display( ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD view_display.
+
+ DATA(view) = z2ui5_cl_xml_view=>factory( ).
+
+ " require the framework's curated formatter module into the view, like an
+ " original UI5 app requires its model/formatter - the weightState function
+ " (weight -> ValueState) then works as a plain formatter in the binding.
+ " z2ui5.Util is deprecated; z2ui5/model/formatter is the module to use.
+ view->_generic_property( VALUE #( n = `core:require`
+ v = `{Formatter: 'z2ui5/model/formatter'}` ) ).
+
+ DATA(page) = view->shell(
+ )->page(
+ title = `abap2UI5 - Formatter - weightState via core:require`
+ navbuttonpress = client->_event_nav_app_leave( )
+ shownavbutton = client->check_app_prev_stack( ) ).
+
+ page->message_strip(
+ text = `The Weight column's state is formatted client-side by ` &&
+ `Formatter.weightState from z2ui5/model/formatter, wired via core:require.`
+ type = `Information`
+ showicon = abap_true
+ class = `sapUiSmallMargin` ).
+
+ DATA(tab) = page->table( id = `productTable`
+ items = client->_bind( t_products ) ).
+
+ tab->columns(
+ )->column( )->text( `Product` )->get_parent(
+ )->column( )->text( `Weight` )->get_parent( ).
+
+ tab->items(
+ )->column_list_item(
+ )->cells(
+ )->text( `{NAME}`
+ )->object_number(
+ number = `{MEASURE}`
+ unit = `{UNIT}`
+ state = |\{ parts: [\{path: 'MEASURE'\}, \{path: 'UNIT'\}], formatter: 'Formatter.weightState' \}| ).
+
+ client->view_display( view->stringify( ) ).
+
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/src/00/08/z2ui5_cl_demo_app_450.clas.xml b/src/00/08/z2ui5_cl_demo_app_450.clas.xml
new file mode 100644
index 00000000..be77585c
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_450.clas.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Z2UI5_CL_DEMO_APP_450
+ E
+ Formatter - weightState via core require
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/00/08/z2ui5_cl_demo_app_451.clas.abap b/src/00/08/z2ui5_cl_demo_app_451.clas.abap
new file mode 100644
index 00000000..04373e47
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_451.clas.abap
@@ -0,0 +1,80 @@
+CLASS z2ui5_cl_demo_app_451 DEFINITION PUBLIC.
+
+ PUBLIC SECTION.
+ INTERFACES z2ui5_if_app.
+
+ TYPES:
+ BEGIN OF ty_s_token,
+ key TYPE string,
+ text TYPE string,
+ END OF ty_s_token.
+ DATA t_tokens TYPE STANDARD TABLE OF ty_s_token WITH EMPTY KEY.
+ DATA t_tokens_added TYPE STANDARD TABLE OF ty_s_token WITH EMPTY KEY.
+ DATA t_tokens_removed TYPE STANDARD TABLE OF ty_s_token WITH EMPTY KEY.
+
+ PROTECTED SECTION.
+ DATA client TYPE REF TO z2ui5_if_client.
+
+ METHODS view_display.
+
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+CLASS z2ui5_cl_demo_app_451 IMPLEMENTATION.
+
+ METHOD z2ui5_if_app~main.
+
+ me->client = client.
+ IF client->check_on_init( ).
+ t_tokens = VALUE #( ( key = `0001` text = `Token 1` )
+ ( key = `0002` text = `Token 2` ) ).
+ view_display( ).
+ ELSEIF client->check_on_event( `UPDATE_BACKEND` ).
+ " added/removed tokens arrive in the bound tables via the companion's change event
+ client->view_model_update( ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD view_display.
+
+ DATA(view) = z2ui5_cl_xml_view=>factory( ).
+
+ DATA(page) = view->shell(
+ )->page(
+ title = `abap2UI5 - Custom Control - MultiInput Validator`
+ navbuttonpress = client->_event_nav_app_leave( )
+ shownavbutton = client->check_app_prev_stack( ) ).
+
+ page->message_strip(
+ text = `The invisible companion control z2ui5.cc.MultiInputExt installs the ` &&
+ `free-text validator: type any text and press Enter to create a token.`
+ type = `Information`
+ showicon = abap_true
+ class = `sapUiSmallMargin` ).
+
+ " the companion references the MultiInput by id and adds the validator
+ " (free text + Enter -> new Token), mirroring token changes to the backend
+ page->_z2ui5( )->multiinput_ext(
+ multiinputid = `myInput`
+ addedtokens = client->_bind_edit( t_tokens_added )
+ removedtokens = client->_bind_edit( t_tokens_removed )
+ change = client->_event( `UPDATE_BACKEND` ) ).
+
+ page->multi_input(
+ id = `myInput`
+ width = `20em`
+ showvaluehelp = abap_false
+ class = `sapUiSmallMargin`
+ tokens = client->_bind_edit( t_tokens )
+ )->tokens(
+ )->token( key = `{KEY}`
+ text = `{TEXT}` ).
+
+ client->view_display( view->stringify( ) ).
+
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/src/00/08/z2ui5_cl_demo_app_451.clas.xml b/src/00/08/z2ui5_cl_demo_app_451.clas.xml
new file mode 100644
index 00000000..43c3aa92
--- /dev/null
+++ b/src/00/08/z2ui5_cl_demo_app_451.clas.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Z2UI5_CL_DEMO_APP_451
+ E
+ Custom Control - MultiInput Validator
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/00/z2ui5_cl_sample_app_000.clas.abap b/src/00/z2ui5_cl_sample_app_000.clas.abap
index 8a653158..287bb99b 100644
--- a/src/00/z2ui5_cl_sample_app_000.clas.abap
+++ b/src/00/z2ui5_cl_sample_app_000.clas.abap
@@ -302,6 +302,10 @@ CLASS z2ui5_cl_sample_app_000 IMPLEMENTATION.
( group = `experimental, TODO` header = `Tree Table II` sub = `` app = `z2ui5_cl_demo_app_069` )
( group = `experimental, TODO` header = `Tree Table III` sub = `Checkbox Binding per Node` app = `z2ui5_cl_demo_app_364` )
( group = `experimental, TODO` header = `ViewSettingsDialog` sub = `` app = `z2ui5_cl_demo_app_099` )
+ ( group = `framework - new (beta)` header = `Control Call` sub = `Panel setExpanded` app = `z2ui5_cl_demo_app_448` )
+ ( group = `framework - new (beta)` header = `Control Call` sub = `PDFViewer open` app = `z2ui5_cl_demo_app_449` )
+ ( group = `framework - new (beta)` header = `Custom Control` sub = `MultiInput Validator` app = `z2ui5_cl_demo_app_451` )
+ ( group = `framework - new (beta)` header = `Formatter` sub = `weightState via core require` app = `z2ui5_cl_demo_app_450` )
( group = `obsolete` header = `follow_up_action with JS` sub = `` app = `z2ui5_cl_demo_app_309_0` )
( 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` )
diff --git a/src/01/01/z2ui5_cl_demo_app_452.clas.abap b/src/01/01/z2ui5_cl_demo_app_452.clas.abap
new file mode 100644
index 00000000..9b9d0e81
--- /dev/null
+++ b/src/01/01/z2ui5_cl_demo_app_452.clas.abap
@@ -0,0 +1,234 @@
+CLASS z2ui5_cl_demo_app_452 DEFINITION PUBLIC.
+
+ PUBLIC SECTION.
+ INTERFACES z2ui5_if_app.
+
+ TYPES:
+ BEGIN OF ty_s_msg,
+ type TYPE string,
+ title TYPE string,
+ subtitle TYPE string,
+ description TYPE string,
+ group TYPE string,
+ END OF ty_s_msg.
+ DATA t_msg TYPE STANDARD TABLE OF ty_s_msg WITH EMPTY KEY.
+
+ PROTECTED SECTION.
+ DATA client TYPE REF TO z2ui5_if_client.
+
+ METHODS on_init.
+ METHODS on_event.
+ METHODS view_display.
+ METHODS popup_display.
+ METHODS popover_display
+ IMPORTING
+ id TYPE string.
+
+ PRIVATE SECTION.
+ENDCLASS.
+
+
+CLASS z2ui5_cl_demo_app_452 IMPLEMENTATION.
+
+ METHOD z2ui5_if_app~main.
+
+ me->client = client.
+ IF client->check_on_init( ).
+ on_init( ).
+ ELSEIF client->check_on_event( ).
+ on_event( ).
+ ENDIF.
+
+ ENDMETHOD.
+
+
+ METHOD on_init.
+
+ " the original controller reuses the same long description text for every message
+ DATA(description) = `First Error message description. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ` &&
+ `Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ` &&
+ `Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ` &&
+ `Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`.
+
+ t_msg = VALUE #(
+ ( type = `Error`
+ title = `Account 801 requires an assignment`
+ subtitle = `Role is invalid`
+ description = description
+ group = `Purchase Order 450001` )
+ ( type = `Warning`
+ title = `Account 821 requires a check`
+ subtitle = `Undefined task`
+ description = description
+ group = `Purchase Order 450001` )
+ ( type = `Warning`
+ title = `Enter a text with maximum 6 characters length`
+ description = description
+ group = `Purchase Order 450002` )
+ ( type = `Warning`
+ title = `Enter a text with maximum 8 characters length`
+ description = description
+ group = `Purchase Order 450002` )
+ ( type = `Error`
+ title = `Account 802 requires an assignment`
+ subtitle = `Role is invalid`
+ description = description
+ group = `Purchase Order 450002` )
+ ( type = `Information`
+ title = `Account 804 requires an assignment`
+ subtitle = `Information type subtitle`
+ description = description
+ group = `Purchase Order 450002` )
+ ( type = `Error`
+ title = `Technical message without object relation`
+ description = description
+ group = `General` )
+ ( type = `Warning`
+ title = `Global System will be down on Sunday`
+ description = description
+ group = `General` )
+ ( type = `Error`
+ title = `Global System will be down on Sunday`
+ description = description
+ group = `General` )
+ ( type = `Error`
+ title = `An Error`
+ subtitle = `Ungrouped message`
+ description = description )
+ ( type = `Warning`
+ title = `A Warning`
+ subtitle = `Ungrouped message`
+ description = description ) ).
+
+ view_display( ).
+
+ ENDMETHOD.
+
+
+ METHOD on_event.
+
+ CASE client->get( )-event.
+ WHEN `POPUP`.
+ popup_display( ).
+ WHEN `POPOVER`.
+ popover_display( `messagePopoverBtn` ).
+ WHEN `POPOVER_CLOSE`.
+ client->popover_destroy( ).
+ ENDCASE.
+
+ ENDMETHOD.
+
+
+ METHOD view_display.
+
+ " the original derives the footer button icon and text from the highest message severity via formatters - here Error
+ DATA(error_count) = 0.
+ LOOP AT t_msg TRANSPORTING NO FIELDS WHERE type = `Error`.
+ error_count = error_count + 1.
+ ENDLOOP.
+
+ DATA(view) = z2ui5_cl_xml_view=>factory( ).
+ DATA(page) = view->shell(
+ )->page(
+ title = `abap2UI5 - Sample: Message View with Grouping`
+ navbuttonpress = client->_event_nav_app_leave( )
+ shownavbutton = client->check_app_prev_stack( ) ).
+
+ page->header_content(
+ )->link(
+ text = `UI5 Demo Kit`
+ target = `_blank`
+ href = `https://sapui5.hana.ondemand.com/sdk/#/entity/sap.m.MessageView/sample/sap.m.sample.MessageViewWithGrouping` ).
+
+ page->message_view(
+ items = client->_bind( t_msg )
+ groupitems = abap_true
+ )->message_item(
+ type = `{TYPE}`
+ title = `{TITLE}`
+ subtitle = `{SUBTITLE}`
+ description = `{DESCRIPTION}`
+ groupname = `{GROUP}`
+ )->link(
+ text = `Show more information`
+ href = `http://sap.com`
+ target = `_blank` ).
+
+ " the original renders the footer button with type 'Negative' - the type is only available since UI5 1.73, therefore omitted
+ page->footer( )->overflow_toolbar(
+ )->button(
+ icon = `sap-icon://message-error`
+ text = |{ error_count }|
+ press = client->_event( `POPUP` )
+ )->toolbar_spacer(
+ )->button(
+ id = `messagePopoverBtn`
+ text = `Message Popover`
+ press = client->_event( `POPOVER` ) ).
+
+ client->view_display( view->stringify( ) ).
+
+ ENDMETHOD.
+
+
+ METHOD popup_display.
+
+ DATA(popup) = z2ui5_cl_xml_view=>factory_popup( ).
+
+ " the original hosts a back button for the message details in a custom header - here the dialog keeps the plain title
+ DATA(dialog) = popup->dialog(
+ title = `Publish order`
+ contentheight = `50%`
+ contentwidth = `50%`
+ verticalscrolling = abap_false
+ afterclose = client->_event_client( client->cs_event-popup_close ) ).
+
+ dialog->message_view(
+ items = client->_bind( t_msg )
+ groupitems = abap_true
+ )->message_item(
+ type = `{TYPE}`
+ title = `{TITLE}`
+ subtitle = `{SUBTITLE}`
+ description = `{DESCRIPTION}`
+ groupname = `{GROUP}`
+ )->link(
+ text = `Show more information`
+ href = `http://sap.com`
+ target = `_blank` ).
+
+ dialog->end_button( )->button(
+ text = `Close`
+ press = client->_event_client( client->cs_event-popup_close ) ).
+
+ client->popup_display( popup->stringify( ) ).
+
+ ENDMETHOD.
+
+
+ METHOD popover_display.
+
+ DATA(popup) = z2ui5_cl_xml_view=>factory_popup( ).
+
+ popup->message_popover(
+ items = client->_bind( t_msg )
+ groupitems = abap_true
+ placement = `Top`
+ beforeclose = client->_event( `POPOVER_CLOSE` )
+ )->message_item(
+ type = `{TYPE}`
+ title = `{TITLE}`
+ subtitle = `{SUBTITLE}`
+ description = `{DESCRIPTION}`
+ groupname = `{GROUP}`
+ )->link(
+ text = `Show more information`
+ href = `http://sap.com`
+ target = `_blank` ).
+
+ client->popover_display( xml = popup->stringify( )
+ by_id = id ).
+
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/src/01/01/z2ui5_cl_demo_app_452.clas.xml b/src/01/01/z2ui5_cl_demo_app_452.clas.xml
new file mode 100644
index 00000000..c8d28b16
--- /dev/null
+++ b/src/01/01/z2ui5_cl_demo_app_452.clas.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Z2UI5_CL_DEMO_APP_452
+ E
+ Message - MessageView
+ 1
+ X
+ X
+ X
+
+
+
+
diff --git a/src/01/z2ui5_cl_sample_app_001.clas.abap b/src/01/z2ui5_cl_sample_app_001.clas.abap
index 5c8198be..af137001 100644
--- a/src/01/z2ui5_cl_sample_app_001.clas.abap
+++ b/src/01/z2ui5_cl_sample_app_001.clas.abap
@@ -221,6 +221,7 @@ CLASS z2ui5_cl_sample_app_001 IMPLEMENTATION.
( group = `framework - basics` header = `Message` sub = `Backend` app = `z2ui5_cl_demo_app_008` )
( group = `framework - basics` header = `Message` sub = `MessageBox` app = `z2ui5_cl_demo_app_382` )
( group = `framework - basics` header = `Message` sub = `MessageToast` app = `z2ui5_cl_demo_app_381` )
+ ( group = `framework - basics` header = `Message` sub = `MessageView` app = `z2ui5_cl_demo_app_452` )
( group = `framework - basics` header = `More` sub = `Call and leave to apps` app = `z2ui5_cl_demo_app_024` )
( group = `framework - basics` header = `More` sub = `Generic Data Reference` app = `z2ui5_cl_demo_app_061` )
( group = `framework - basics` header = `More` sub = `Model Size Limit` app = `z2ui5_cl_demo_app_071` )