From fa59fb78367cfbd55c6271326ae704e4482c6232 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 13 Sep 2026 11:49:05 +0000 Subject: [PATCH] Message: say which half of the API a call belongs to abap2UI5 takes the plain sap.m options off client->message_toast_display( ) and client->message_box_display( ): the client method carries what an ABAP app decides - the data in any shape, the kind of box, the buttons as a table, the backend event its closing raises - and a pure UI5 option is set on the control, as the option object of a follow_up_action( cs_event-control_global ) call, which is the sap.m API 1:1. The Message page gets that as a section of its own, with the table of which option moved where and the wired, round-trip-free form; Frontend Actions says next to control_global that a t_arg starting with a brace travels as real JSON, which is what carries those options. Z2UI5_CL_SMP_APP_512 joins the page's sample list as the control-side counterpart of 502. Also repaired: two deprecation-page links into src/00/97, a package that no longer exists in abap2UI5/samples, and the sample-link blocks the generator refreshes with them. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01CigShdooBBhKDDztTLpsZq --- docs/cookbook/device_capabilities/info.md | 2 +- docs/cookbook/event_navigation/frontend.md | 16 +++++ docs/cookbook/event_navigation/life_cycle.md | 2 +- .../event_navigation/navigation/app_state.md | 2 +- .../event_navigation/navigation/hash.md | 4 +- docs/cookbook/expert_more/snippets.md | 2 +- docs/cookbook/popup_popover/popover.md | 2 +- docs/cookbook/translation_messages/message.md | 68 ++++++++++++++++++- docs/resources/deprecations.md | 4 +- docs/tutorials/walkthrough/step-3.md | 2 +- 10 files changed, 93 insertions(+), 11 deletions(-) diff --git a/docs/cookbook/device_capabilities/info.md b/docs/cookbook/device_capabilities/info.md index 8f64483a..95ea51af 100644 --- a/docs/cookbook/device_capabilities/info.md +++ b/docs/cookbook/device_capabilities/info.md @@ -143,7 +143,7 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| -| Device — Frontend Info: UI5 Version, Theme, OS, Browser | [`Z2UI5_CL_SMP_APP_122`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_122.clas.abap) | +| Device — Frontend Info: UI5 Version, Theme, OS, Browser | [`Z2UI5_CL_SMP_APP_122`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_122.clas.abap) | | Device Model: Phone, Tablet, Desktop (A) | [`Z2UI5_CL_SMP_APP_445`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_445.clas.abap) | diff --git a/docs/cookbook/event_navigation/frontend.md b/docs/cookbook/event_navigation/frontend.md index 4e46defa..e66b4e94 100644 --- a/docs/cookbook/event_navigation/frontend.md +++ b/docs/cookbook/event_navigation/frontend.md @@ -160,6 +160,22 @@ press = client->follow_up_action( t_arg = VALUE #( ( `msgPopover` ) ( `toggleBy` ) ( `${$source>/id}` ) ) ) ``` +A `t_arg` argument that starts with a brace travels as **real JSON** rather than +as a string. That is how `MESSAGE_TOAST` and `MESSAGE_BOX` take their UI5 +options — the object is the last argument of the call and is the option object +of `sap.m.MessageToast.show( )` / `sap.m.MessageBox.( )` 1:1, with the box +type as the method: + +```abap +client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) ( `error` ) ( `Not saved.` ) + ( `{"contentWidth":"30rem","icon":"WARNING"}` ) ) ). +``` + +Which options belong here and which stay on `client->message_box_display( )` is +the subject of [Message](/cookbook/translation_messages/message). + The same events also work as a **statement** in your `main` method, with the identical `t_arg` — then the browser runs them after the response arrives, once your backend work is done: ```abap diff --git a/docs/cookbook/event_navigation/life_cycle.md b/docs/cookbook/event_navigation/life_cycle.md index fa2e0c3d..a73fb06d 100644 --- a/docs/cookbook/event_navigation/life_cycle.md +++ b/docs/cookbook/event_navigation/life_cycle.md @@ -149,6 +149,6 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| | Basics III — Lifecycle: Init, Event, Navigated | [`Z2UI5_CL_SMP_APP_495`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_495.clas.abap) | -| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_004.clas.abap) | +| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_004.clas.abap) | diff --git a/docs/cookbook/event_navigation/navigation/app_state.md b/docs/cookbook/event_navigation/navigation/app_state.md index b58b01eb..b2c60c9a 100644 --- a/docs/cookbook/event_navigation/navigation/app_state.md +++ b/docs/cookbook/event_navigation/navigation/app_state.md @@ -218,6 +218,6 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| -| Hash — App State, Bookmark and Share | [`Z2UI5_CL_SMP_APP_498`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_498.clas.abap) | +| Hash — App State, Bookmark and Share | [`Z2UI5_CL_SMP_APP_498`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_498.clas.abap) | diff --git a/docs/cookbook/event_navigation/navigation/hash.md b/docs/cookbook/event_navigation/navigation/hash.md index 24c8b73f..c5842d0a 100644 --- a/docs/cookbook/event_navigation/navigation/hash.md +++ b/docs/cookbook/event_navigation/navigation/hash.md @@ -207,8 +207,8 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| -| Hash — Routing mode fresh | [`Z2UI5_CL_SMP_APP_468`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_468.clas.abap) | +| Hash — Routing mode fresh | [`Z2UI5_CL_SMP_APP_468`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_468.clas.abap) | | Routing mode keep | [`Z2UI5_CL_SMP_APP_480`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_480.clas.abap) | -| Hash — App-Owned Routing (#/detail) | [`Z2UI5_CL_SMP_APP_499`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_499.clas.abap) | +| Hash — App-Owned Routing (#/detail) | [`Z2UI5_CL_SMP_APP_499`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_499.clas.abap) | diff --git a/docs/cookbook/expert_more/snippets.md b/docs/cookbook/expert_more/snippets.md index 36452c35..7ab53097 100644 --- a/docs/cookbook/expert_more/snippets.md +++ b/docs/cookbook/expert_more/snippets.md @@ -371,6 +371,6 @@ unless its row names another of the three sample repositories — pull that repo |---|---| | Basics I — Hello World, the Smallest App | [`Z2UI5_CL_SMP_APP_493`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_493.clas.abap) | | Basics III — Lifecycle: Init, Event, Navigated | [`Z2UI5_CL_SMP_APP_495`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_495.clas.abap) | -| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_004.clas.abap) | +| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_004.clas.abap) | diff --git a/docs/cookbook/popup_popover/popover.md b/docs/cookbook/popup_popover/popover.md index a6c439dd..10b64a30 100644 --- a/docs/cookbook/popup_popover/popover.md +++ b/docs/cookbook/popup_popover/popover.md @@ -87,7 +87,7 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| | Basic Example with Placement | [`Z2UI5_CL_SMP_APP_026`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_026.clas.abap) | -| Popover — Open from a Table Row (A) | [`Z2UI5_CL_SMP_APP_052`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_052.clas.abap) | +| Popover — Open from a Table Row (A) | [`Z2UI5_CL_SMP_APP_052`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_052.clas.abap) | | Select from a List | [`Z2UI5_CL_SMP_APP_081`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_081.clas.abap) | | QuickView Contact Card | [`Z2UI5_CL_SMP_APP_109`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_109.clas.abap) | | Toggle by ID (toggleBy) (A) | [`Z2UI5_CL_SMP_APP_465`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_465.clas.abap) | diff --git a/docs/cookbook/translation_messages/message.md b/docs/cookbook/translation_messages/message.md index cc065455..9e8b4f7b 100644 --- a/docs/cookbook/translation_messages/message.md +++ b/docs/cookbook/translation_messages/message.md @@ -8,6 +8,7 @@ samples: - z2ui5_cl_smp_app_467 - z2ui5_cl_smp_app_474 - z2ui5_cl_smp_app_502 + - z2ui5_cl_smp_app_512 --- # Message @@ -83,6 +84,70 @@ ENDMETHOD. ``` The framework accepts other inputs too — pass your message structure and the message box shows it. +## Client Method or Global Object? + +Both of the calls above have a second form, and the two answer different +questions. + +`client->message_toast_display( )` and `client->message_box_display( )` are the +**ABAP side**. Hand them what the app already holds — a text, a BAPIRET2 table, +a log, an exception, a structure, a whole table — and they work out the +severity, the title and the rendering themselves, as the section above shows. +What they take as parameters is what an ABAP app decides: the data, the kind of +box, the buttons as a `string_table`, and the backend event raised when the box +closes. + +A plain **UI5 option** — where a toast docks, how wide the box is, which icon it +carries — is not an ABAP decision, and it is set on the control instead. The +whitelisted global call reaches `sap.m.MessageToast` and `sap.m.MessageBox` +directly, and its last argument is the option object of that API 1:1: + +```abap +METHOD z2ui5_if_app~main. + + " the display method IS the box type + client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_BOX` ) + ( `error` ) + ( `Not saved.` ) + ( `{"contentWidth":"30rem","icon":"WARNING"}` ) ) ). + +ENDMETHOD. +``` + +An argument that starts with a brace travels as **real JSON**, so the options +arrive as an object rather than as a string that looks like one. Both ways end +in the same frontend code: `onClose` stays a backend event name on either path, +and the details of a box are expanded on either path. + +These options left the two client methods in September 2026 and are set through +the global object now: + +| Control | Options on the control | +|---|---| +| `MESSAGE_TOAST` | `width`, `my`, `at`, `of`, `offset`, `collision`, `autoClose`, `animationTimingFunction`, `animationDuration`, `closeOnBrowserNavigation`, and the abap2UI5-own `class` | +| `MESSAGE_BOX` | `icon`, `textDirection`, `closeOnNavigation`, `dependentOn`, `contentWidth` | + +The global call has one more property the client method cannot have: it can be +**wired into the view**, where it runs without a round-trip at all. Extra +arguments fill the `{0}`, `{1}` placeholders of the text, so a button can say +what was pressed without asking the backend: + +```abap +)->tag( `Button` + )->a( n = `text` v = `Save` + )->a( n = `press` v = client->follow_up_action( + val = client->cs_event-control_global + t_arg = VALUE #( ( `MESSAGE_TOAST` ) + ( `show` ) + ( `{0} was pressed` ) + ( `${$source>/text}` ) ) ) ) +``` + +See [Frontend Actions](/cookbook/event_navigation/frontend) for the other global +objects this call reaches. + ## All of Them in One App The fragments above are each one call. Press **Run** to see the whole family in @@ -169,12 +234,13 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| -| Message — MessageToast, Position, onClose and Class | [`Z2UI5_CL_SMP_APP_381`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_381.clas.abap) | +| Message — MessageToast via the Global Object | [`Z2UI5_CL_SMP_APP_381`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_381.clas.abap) | | MessageBox, Types and Custom Actions | [`Z2UI5_CL_SMP_APP_382`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_382.clas.abap) | | MessageBox from SY, BAPIRET2 or Exception | [`Z2UI5_CL_SMP_APP_008`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_008.clas.abap) | | MessageView and MessagePopover (A) | [`Z2UI5_CL_SMP_APP_452`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_452.clas.abap) | | Message Model and MessageManager (C) | [`Z2UI5_CL_SMP_APP_467`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_467.clas.abap) | | MessagePopover URL Policy (A) | [`Z2UI5_CL_SMP_APP_474`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_474.clas.abap) | | MessageBox for Any Data | [`Z2UI5_CL_SMP_APP_502`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_502.clas.abap) | +| MessageBox via the Global Object | [`Z2UI5_CL_SMP_APP_512`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_512.clas.abap) | diff --git a/docs/resources/deprecations.md b/docs/resources/deprecations.md index 3e1f7fc9..e551e715 100644 --- a/docs/resources/deprecations.md +++ b/docs/resources/deprecations.md @@ -167,8 +167,8 @@ replacement has a sample that proves it: | What you used AJSON for | What to write instead | Sample | |---|---|---| -| Drop initial fields so the UI5 default applies (`create_empty_filter`) | `omit_initial`, or `omit_initial_paths` for single columns | [`Z2UI5_CL_SMP_APP_507`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_507.clas.abap) | -| Get a model **node** instead of a quoted string — under keys no ABAP component could be named after | `json = abap_true` | [`Z2UI5_CL_SMP_APP_509`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_509.clas.abap) | +| Drop initial fields so the UI5 default applies (`create_empty_filter`) | `omit_initial`, or `omit_initial_paths` for single columns | [`Z2UI5_CL_SMP_APP_507`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_507.clas.abap) | +| Get a model **node** instead of a quoted string — under keys no ABAP component could be named after | `json = abap_true` | [`Z2UI5_CL_SMP_APP_509`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_509.clas.abap) | | Anything else | Shape the value in ABAP before you bind it | — | ```abap diff --git a/docs/tutorials/walkthrough/step-3.md b/docs/tutorials/walkthrough/step-3.md index 63240cb4..62ff3015 100644 --- a/docs/tutorials/walkthrough/step-3.md +++ b/docs/tutorials/walkthrough/step-3.md @@ -94,6 +94,6 @@ unless its row names another of the three sample repositories — pull that repo | Sample | Class | |---|---| | Basics III — Lifecycle: Init, Event, Navigated | [`Z2UI5_CL_SMP_APP_495`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_495.clas.abap) | -| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/97/z2ui5_cl_smp_app_004.clas.abap) | +| Basics IV — Events, Views and Roundtrips | [`Z2UI5_CL_SMP_APP_004`](https://github.com/abap2UI5/samples/blob/main/src/00/z2ui5_cl_smp_app_004.clas.abap) |