diff --git a/docs/cookbook/device_capabilities/info.md b/docs/cookbook/device_capabilities/info.md
index 95ea51af..12fd6a7f 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/z2ui5_cl_smp_app_122.clas.abap) |
+| Frontend Info: UI5 Version, Theme, OS, Browser | [`Z2UI5_CL_SMP_APP_122`](https://github.com/abap2UI5/samples/blob/main/src/01/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/life_cycle.md b/docs/cookbook/event_navigation/life_cycle.md
index a73fb06d..024764d5 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/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/01/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 b2c60c9a..36f362d6 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/z2ui5_cl_smp_app_498.clas.abap) |
+| App State, Bookmark and Share | [`Z2UI5_CL_SMP_APP_498`](https://github.com/abap2UI5/samples/blob/main/src/01/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 c5842d0a..b55226cf 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/z2ui5_cl_smp_app_468.clas.abap) |
+| Routing mode fresh | [`Z2UI5_CL_SMP_APP_468`](https://github.com/abap2UI5/samples/blob/main/src/01/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/z2ui5_cl_smp_app_499.clas.abap) |
+| App-Owned Routing (#/detail) | [`Z2UI5_CL_SMP_APP_499`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_499.clas.abap) |
diff --git a/docs/cookbook/expert_more/snippets.md b/docs/cookbook/expert_more/snippets.md
index 7ab53097..d34f6dd1 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/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/01/z2ui5_cl_smp_app_004.clas.abap) |
diff --git a/docs/cookbook/model/tables.md b/docs/cookbook/model/tables.md
index f3d94bdf..d32c3e0b 100644
--- a/docs/cookbook/model/tables.md
+++ b/docs/cookbook/model/tables.md
@@ -234,7 +234,7 @@ unless its row names another of the three sample repositories — pull that repo
| Large Table with Growing and ScrollContainer | [`Z2UI5_CL_SMP_APP_006`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_006.clas.abap) |
| Filter Rows in the Backend | [`Z2UI5_CL_SMP_APP_045`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_045.clas.abap) |
| Search in the Backend (SearchField) | [`Z2UI5_CL_SMP_APP_053`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_053.clas.abap) |
-| Live Search with Parallel Requests | [`Z2UI5_CL_SMP_APP_059`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_059.clas.abap) |
+| Live Search over a Large Table | [`Z2UI5_CL_SMP_APP_059`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_059.clas.abap) |
| Full Example with sap.ui.table | [`Z2UI5_CL_SMP_APP_070`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_070.clas.abap) |
| Events on Cell Level | [`Z2UI5_CL_SMP_APP_160`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_160.clas.abap) |
| Keep Column Filters on Refresh (C) | [`Z2UI5_CL_SMP_APP_143`](https://github.com/abap2UI5/samples/blob/main/src/01/z2ui5_cl_smp_app_143.clas.abap) |
diff --git a/docs/cookbook/popup_popover/popover.md b/docs/cookbook/popup_popover/popover.md
index 10b64a30..c76bdda0 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/z2ui5_cl_smp_app_052.clas.abap) |
+| Open from a Table Row (A) | [`Z2UI5_CL_SMP_APP_052`](https://github.com/abap2UI5/samples/blob/main/src/01/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 9e8b4f7b..0cf6afa7 100644
--- a/docs/cookbook/translation_messages/message.md
+++ b/docs/cookbook/translation_messages/message.md
@@ -234,7 +234,7 @@ unless its row names another of the three sample repositories — pull that repo
| Sample | Class |
|---|---|
-| 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) |
+| MessageToast via the Global Object | [`Z2UI5_CL_SMP_APP_381`](https://github.com/abap2UI5/samples/blob/main/src/01/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) |
diff --git a/docs/public/api/client-api.json b/docs/public/api/client-api.json
index f8a46752..0c420894 100644
--- a/docs/public/api/client-api.json
+++ b/docs/public/api/client-api.json
@@ -551,6 +551,7 @@
"**cs_event-keyboard_shortcut** - bind a key combination to a named backend event, the declarative equivalent of a sap.ui.core.CommandExecution shortcut, t_arg = combination, event name: ``client->follow_up_action( val = client->cs_event-keyboard_shortcut t_arg = VALUE #( ( `Ctrl+S` ) ( `SAVE` ) ) )``. The combination is spelled like the UI5 one (`Ctrl+S`, `Ctrl+Shift+D`, `F2`; ctrl/shift/alt/meta in any order, cmd/command/option/control accepted as aliases). Pressing it fires the event exactly like a button press and suppresses the browser's own default for the combination. Registering the same combination again rebinds it; an empty event name removes it. The registrations belong to the running app and are dropped when another app takes over. An optional THIRD t_arg SCOPES the shortcut: the scoped registration wins while its scope is OPEN and the unscoped one applies otherwise, which is how a UI5 CommandExecution in a Popover's dependents shadows the page-level one for the same command. A scope is either a view slot (cs_view-popover/popup/nested/nested2/main) or the ID OF A CONTROL that can be open or closed - a Popover/Dialog declared in the view and opened with control_by_id openBy, which never enters a framework slot. A control scope beats a slot scope (it is the more specific statement), then the innermost open slot wins. An empty event name removes the registration of THAT scope only.",
"**cs_event-hash_attach_changed** - APP-OWNED hash routing (HashChanger#attachHashChanged), the 1:1 counterpart of a UI5 router's own hash (`#/Page2`) for an app that does NOT use hash_routing, t_arg = a backend event name: ``client->follow_up_action( val = client->cs_event-hash_attach_changed t_arg = VALUE #( ( `HASH_CHANGED` ) ) )``. From then on hash_set( `/Page2` ) writes that value as the whole app hash (a pushed history entry), hash_replace( ) the same without a new entry, and a hash change the app did not write itself - browser Back/Forward, a manual URL edit - fires the registered event; the hash the browser now stands on arrives with that request (and with every other one, a fresh deep-link start included) in get( )-s_config-hash, so the app decides what to show. While registered, the framework leaves the hash entirely alone. Calling it without t_arg unregisters. The registration dies with an app switch - register it in view_display( ), so every render (a draft restore included) re-asserts it. Mutually exclusive with hash_routing (a routed app's hash belongs to the router) and with app_state_set_active (both claim the whole hash).",
"**cs_event-hash_back** - the UI5 onNavBack pattern: without t_arg one real step back in the browser history (`window.history.go(-1)` - the step is CONSUMED, and the resulting hash change fires the registered event). With t_arg = a fallback hash it guards the cold deep link the way UI5's recommended onNavBack does: when this page load never pushed an app hash, there is no in-app step to take, so the fallback is written as a REPLACE instead of falling out of the app - and the change fires the registered event, which shows the fallback route: ``client->follow_up_action( val = client->cs_event-hash_back t_arg = VALUE #( ( `/` ) ) )``.",
+ "**cs_event-store_data** - write a structure into the browser's local or session storage, the write half of the invisible z2ui5:Storage control that reads it back. t_arg = the structure holding TYPE (`local`/`session`), PREFIX, KEY and VALUE - handed over as the BINDING of that structure, so the frontend takes the current value: ``client->follow_up_action( val = client->cs_event-store_data t_arg = VALUE #( ( client->_bind( ms_storage ) ) ) )``. It works from a view wire and from a handler alike: on a wire UI5 resolves the binding when the view is built, and a follow-up action queued in a handler carries the model PATH, which the frontend resolves when it runs. An empty VALUE removes the key.",
"**cs_event-binding_call** - apply a declarative filter or sorter to an aggregation binding, the client-side equivalent of the UI5 controller pattern getBinding('items').filter(...); the model data stays untouched. t_arg = id, aggregation, method, params. Method `filter`: params = path, operator, value1, value2 (empty values clear the filter); method `sort`: params = path, descending, group (abap_bool as `X`/``): ``client->follow_up_action( val = client->cs_event-binding_call t_arg = VALUE #( ( `tab` ) ( `items` ) ( `filter` ) ( `NAME` ) ( `Contains` ) ( `ab` ) ) )``."
],
"parameters": [
diff --git a/docs/resources/api.md b/docs/resources/api.md
index dcd575f3..9b3fa760 100644
--- a/docs/resources/api.md
+++ b/docs/resources/api.md
@@ -207,6 +207,8 @@ Every one of them also works roundtrip-free when WIRED IN THE VIEW: write the sa
**cs_event-hash_back** - the UI5 onNavBack pattern: without t_arg one real step back in the browser history (`window.history.go(-1)` - the step is CONSUMED, and the resulting hash change fires the registered event). With t_arg = a fallback hash it guards the cold deep link the way UI5's recommended onNavBack does: when this page load never pushed an app hash, there is no in-app step to take, so the fallback is written as a REPLACE instead of falling out of the app - and the change fires the registered event, which shows the fallback route: ``client->follow_up_action( val = client->cs_event-hash_back t_arg = VALUE #( ( `/` ) ) )``.
+**cs_event-store_data** - write a structure into the browser's local or session storage, the write half of the invisible z2ui5:Storage control that reads it back. t_arg = the structure holding TYPE (`local`/`session`), PREFIX, KEY and VALUE - handed over as the BINDING of that structure, so the frontend takes the current value: ``client->follow_up_action( val = client->cs_event-store_data t_arg = VALUE #( ( client->_bind( ms_storage ) ) ) )``. It works from a view wire and from a handler alike: on a wire UI5 resolves the binding when the view is built, and a follow-up action queued in a handler carries the model PATH, which the frontend resolves when it runs. An empty VALUE removes the key.
+
**cs_event-binding_call** - apply a declarative filter or sorter to an aggregation binding, the client-side equivalent of the UI5 controller pattern getBinding('items').filter(...); the model data stays untouched. t_arg = id, aggregation, method, params. Method `filter`: params = path, operator, value1, value2 (empty values clear the filter); method `sort`: params = path, descending, group (abap_bool as `X`/``): ``client->follow_up_action( val = client->cs_event-binding_call t_arg = VALUE #( ( `tab` ) ( `items` ) ( `filter` ) ( `NAME` ) ( `Contains` ) ( `ab` ) ) )``.
| Parameter | Type | Default | Description |
diff --git a/docs/resources/deprecations.md b/docs/resources/deprecations.md
index 381fdd45..e347de52 100644
--- a/docs/resources/deprecations.md
+++ b/docs/resources/deprecations.md
@@ -70,6 +70,7 @@ tell you what is coming if you do not.
| `cs_event-set_nav_routing` | `cs_event-hash_routing` | **removed**, *next release* |
| `cs_event-clipboard_app_state` | `app_state_get_href( )` + `cs_event-clipboard_copy` | **removed**, *next release* |
| `_event( s_ctrl-check_allow_multi_req )` | `s_ctrl-check_queue_last` | **removed**, *next release* |
+| the UI5 options of `message_toast_display( )` / `message_box_display( )` | set them on the control, through `cs_event-control_global` | **removed**, *next release* |
## Obsolete: still compiles
@@ -168,8 +169,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/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) |
+| 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/01/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/01/z2ui5_cl_smp_app_509.clas.abap) |
| Anything else | Shape the value in ABAP before you bind it | — |
```abap
@@ -218,50 +219,6 @@ compiles against.
Both parameters are still evaluated and keep working — existing code does not
break.
-### The `view` parameter of `_bind( )` / `_bind_edit( )`
-
-**Removed.** It dates from the time each view slot had a model of its own; today
-one model serves every open slot, so there was nothing left for it to select —
-the parameter was inert, never passed on internally, for as long as it carried
-the obsolete mark. Deleting it is the whole migration, and a call that still
-names it does not compile.
-
-```abap
-" old
-client->_bind( val = ms_data view = client->cs_view-popup )
-
-" new
-client->_bind( ms_data )
-```
-
-The binding string that comes back is the one that came back before. `cs_view`
-itself stays — it is the view slot of `follow_up_action( )`, where it does
-select one.
-
-### `cs_event-wizard_set_next_step`
-
-**Removed.** The event bundled the two calls a UI5 controller makes on a Wizard
-(`discardProgress( oStep )` + `oStep.setNextStep( oNext )`) into one fixed pair.
-Both methods are on the frontend's `CONTROL_METHODS` whitelist, so the same flow
-is two ordinary `control_by_id` calls — which additionally reach `goToStep`, a
-step the bundled event could not express.
-
-```abap
-" old
-client->follow_up_action( val = client->cs_event-wizard_set_next_step
- t_arg = VALUE #( ( `wizard` ) ( `step2` ) ) ).
-
-" new
-client->follow_up_action( val = client->cs_event-control_by_id
- t_arg = VALUE #( ( `wizard` ) ( `discardProgress` ) ( `step1` ) ) ).
-client->follow_up_action( val = client->cs_event-control_by_id
- t_arg = VALUE #( ( `step1` ) ( `setNextStep` ) ( `step2` ) ) ).
-```
-
-The constant is gone from `cs_event` and the `WIZARD_SET_NEXT_STEP` handler is
-gone from the frontend, so a call that still names either does not compile and
-a raw string does nothing.
-
### The `nav_container_to` event family
`cs_event-nav_container_to` and its `nest_` / `nest2_` / `popup_` / `popover_`
@@ -400,7 +357,6 @@ ABAP with no control in the view at all:
| `Title` | `cs_event-set_title` — [Title](/cookbook/browser_interaction/title) |
| `LPTitle` | `cs_event-set_title_launchpad` — [Title](/cookbook/browser_interaction/title) |
| `Favicon` | `cs_event-set_favicon` |
-| `SoftKeyboard` | `cs_event-keyboard_set_mode` — [Soft Keyboard](/cookbook/browser_interaction/soft_keyboard) |
| `Info` | `client->get( )-s_device` / `-s_ui5` / `-s_focus` / `-s_scroll` — [Device Info](/cookbook/device_capabilities/info) |
| `History` | `client->hash_set( )` — [URL Handling](/cookbook/browser_interaction/url_handling) |
@@ -508,6 +464,75 @@ and runs exactly as before, and every moved type is identical field for field,
so a variable declared the old way still fits the new signatures. There is no
deadline; change it when you next touch the class.
+### `z2ui5.Util` → `z2ui5.Formatter`
+
+`z2ui5.Util` (module `z2ui5/Util`) is a backward-compatible alias that
+re-exports the date helpers from `z2ui5.Formatter` (module
+`z2ui5/model/formatter`). It will not gain new helpers.
+
+```abap
+" old
+|\{ path: `{ client->_bind( val = mv_date path = abap_true ) }`,
+ formatter: 'z2ui5.Util.DateCreateObject' \}|
+
+" new
+|\{ path: `{ client->_bind( val = mv_date path = abap_true ) }`,
+ formatter: 'Formatter.DateCreateObject' \}|
+```
+
+See [Formatter](/cookbook/model/formatter).
+
+## Removed: does not compile any more
+
+Every name below is **gone from the framework**, not merely marked. A call
+that still writes one fails at activation, so these are the entries to work
+through before you pull a release that carries them — the table above says
+which one that is.
+
+### The `view` parameter of `_bind( )` / `_bind_edit( )`
+
+**Removed.** It dates from the time each view slot had a model of its own; today
+one model serves every open slot, so there was nothing left for it to select —
+the parameter was inert, never passed on internally, for as long as it carried
+the obsolete mark. Deleting it is the whole migration, and a call that still
+names it does not compile.
+
+```abap
+" old
+client->_bind( val = ms_data view = client->cs_view-popup )
+
+" new
+client->_bind( ms_data )
+```
+
+The binding string that comes back is the one that came back before. `cs_view`
+itself stays — it is the view slot of `follow_up_action( )`, where it does
+select one.
+
+### `cs_event-wizard_set_next_step`
+
+**Removed.** The event bundled the two calls a UI5 controller makes on a Wizard
+(`discardProgress( oStep )` + `oStep.setNextStep( oNext )`) into one fixed pair.
+Both methods are on the frontend's `CONTROL_METHODS` whitelist, so the same flow
+is two ordinary `control_by_id` calls — which additionally reach `goToStep`, a
+step the bundled event could not express.
+
+```abap
+" old
+client->follow_up_action( val = client->cs_event-wizard_set_next_step
+ t_arg = VALUE #( ( `wizard` ) ( `step2` ) ) ).
+
+" new
+client->follow_up_action( val = client->cs_event-control_by_id
+ t_arg = VALUE #( ( `wizard` ) ( `discardProgress` ) ( `step1` ) ) ).
+client->follow_up_action( val = client->cs_event-control_by_id
+ t_arg = VALUE #( ( `step1` ) ( `setNextStep` ) ( `step2` ) ) ).
+```
+
+The constant is gone from `cs_event` and the `WIZARD_SET_NEXT_STEP` handler is
+gone from the frontend, so a call that still names either does not compile and
+a raw string does nothing.
+
### The URL API is `hash_*` and `app_state_*` now
@@ -567,24 +592,6 @@ What is genuinely new rather than renamed — `hash_replace( )`,
app the URL semantics of a UI5 router — is on
[Hash](/cookbook/event_navigation/navigation/hash).
-### `z2ui5.Util` → `z2ui5.Formatter`
-
-`z2ui5.Util` (module `z2ui5/Util`) is a backward-compatible alias that
-re-exports the date helpers from `z2ui5.Formatter` (module
-`z2ui5/model/formatter`). It will not gain new helpers.
-
-```abap
-" old
-|\{ path: `{ client->_bind( val = mv_date path = abap_true ) }`,
- formatter: 'z2ui5.Util.DateCreateObject' \}|
-
-" new
-|\{ path: `{ client->_bind( val = mv_date path = abap_true ) }`,
- formatter: 'Formatter.DateCreateObject' \}|
-```
-
-See [Formatter](/cookbook/model/formatter).
-
### `check_allow_multi_req` → `check_queue_last`
`s_ctrl-check_allow_multi_req` sent the event while another round-trip was
@@ -614,3 +621,49 @@ The component is gone from `ty_s_event_control`, so an app that names it does
not activate — the rename above is the whole migration. Without either flag the
busy guard drops every event fired during a flight, which is right for a click
and wrong for a keystroke.
+
+### The UI5 options of `message_toast_display( )` / `message_box_display( )`
+
+**Removed.** Both methods had grown to fourteen parameters each, and most of
+each list was a plain `sap.m` option abap2UI5 did nothing with but pass on. What
+the ABAP method carries is what an ABAP app decides — the data in whatever shape
+it has, the kind of box, the buttons, the backend event its closing raises.
+Where a toast docks and how wide a box is are not ABAP decisions, and they are
+set on the control now.
+
+| Method | Parameters gone |
+|---|---|
+| `message_toast_display( )` | `width`, `my`, `at`, `of`, `offset`, `collision`, `autoclose`, `animationtimingfunction`, `animationduration`, `closeonbrowsernavigation`, `class` |
+| `message_box_display( )` | `textdirection`, `icon`, `closeonnavigation`, `dependenton`, `contentwidth` |
+
+This is the one entry on this page that shortens a **signature** rather than
+retiring a name, so a call that still passes one of them fails on the parameter,
+not on the method. What stays is `text`, `type`, `title`, `styleclass`,
+`actions`, `emphasizedaction`, `initialfocus`, `details` and `onclose` on the
+box, and `text`, `duration` and `onclose` on the toast.
+
+The replacement is the whitelisted global call, whose last argument is the
+option object of `sap.m.MessageToast.show( )` / `sap.m.MessageBox.( )`
+1:1 — an argument that starts with a brace travels as real JSON:
+
+```abap
+" old
+client->message_box_display( text = `Not saved.`
+ type = `error`
+ contentwidth = `30rem`
+ icon = `WARNING` ).
+
+" new - 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"}` ) ) ).
+```
+
+Both paths end in the same frontend code, so the options behave identically:
+`onClose` stays a backend event name on either, the details are still expanded,
+`dependentOn` is still resolved to a control. The raw path can do one thing
+more — wired into a view it needs no round-trip at all. See
+[Message](/cookbook/translation_messages/message).
diff --git a/docs/tutorials/walkthrough/step-3.md b/docs/tutorials/walkthrough/step-3.md
index 62ff3015..11f3ce7a 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/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/01/z2ui5_cl_smp_app_004.clas.abap) |