Skip to content

Commit f701ef0

Browse files
oblomov-devclaude
andauthored
Add four samples for the new frontend capabilities (#697)
One sample per capability added to the framework (abap2UI5 PR "implement the five open ai-demokit framework requests"), all in Basic II (src/01/02) and marked (A) as frontend-action demos: - 471 Keyboard Shortcuts: Ctrl+S / Ctrl+D fire the backend events SAVE and DELETE via cs_event-keyboard_shortcut; a button registers and unregisters them again, a list logs what was triggered. - 472 Link with preventDefault: a sap.m.Link whose press is registered with s_ctrl-check_prevent_default, so the browser does not follow the href and the backend decides instead. A switch rebuilds the view with the flag off to compare both behaviours. - 473 Menu Item Path: a nested sap.m.Menu whose itemSelected toasts the full breadcrumb of the selected item ("Create New Site > Official Store"), resolved client-side by $controller.textPath( ) - no roundtrip. - 474 MessagePopover URL Policy: messages carrying an in-app and an external link; the popover is opened with RELATIVE_ONLY, ALLOW_ALL or DENY_ALL, the frontend installs the matching setAsyncURLHandler validator. Overview catalog regenerated (npm run launchpad). Note: these samples use framework API that is not on abap2UI5 main yet, so the abaplint gates stay red until that PR is merged (and, for ABAP_702, until the 702 branch is regenerated). Verified locally against the framework branch: ABAP_STANDARD, ABAP_CLOUD and the 702 downport all report 0 issues. Claude-Session: https://claude.ai/code/session_01Amu2PTNKeQLzUJysdJUBUa Co-authored-by: Claude <noreply@anthropic.com>
1 parent 62d2778 commit f701ef0

9 files changed

Lines changed: 539 additions & 0 deletions
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
CLASS z2ui5_cl_demo_app_471 DEFINITION PUBLIC.
2+
3+
PUBLIC SECTION.
4+
INTERFACES z2ui5_if_app.
5+
6+
TYPES:
7+
BEGIN OF ty_s_log,
8+
entry TYPE string,
9+
END OF ty_s_log.
10+
DATA t_log TYPE STANDARD TABLE OF ty_s_log WITH EMPTY KEY.
11+
DATA registered TYPE abap_bool.
12+
13+
PROTECTED SECTION.
14+
DATA client TYPE REF TO z2ui5_if_client.
15+
16+
METHODS on_init.
17+
METHODS on_event.
18+
METHODS view_display.
19+
METHODS shortcuts_set
20+
IMPORTING
21+
event_save TYPE string
22+
event_delete TYPE string.
23+
24+
PRIVATE SECTION.
25+
ENDCLASS.
26+
27+
28+
CLASS z2ui5_cl_demo_app_471 IMPLEMENTATION.
29+
30+
METHOD z2ui5_if_app~main.
31+
32+
me->client = client.
33+
IF client->check_on_init( ).
34+
on_init( ).
35+
ELSEIF client->check_on_navigated( ).
36+
view_display( ).
37+
ELSEIF client->check_on_event( ).
38+
on_event( ).
39+
ENDIF.
40+
41+
ENDMETHOD.
42+
43+
44+
METHOD on_init.
45+
46+
registered = abap_true.
47+
shortcuts_set( event_save = `SAVE`
48+
event_delete = `DELETE` ).
49+
view_display( ).
50+
51+
ENDMETHOD.
52+
53+
54+
METHOD on_event.
55+
56+
CASE client->get( )-event.
57+
58+
WHEN `SAVE`.
59+
INSERT VALUE #( entry = `Ctrl+S - save triggered` ) INTO TABLE t_log.
60+
client->message_toast_display( `Ctrl+S: save triggered` ).
61+
client->view_model_update( ).
62+
63+
WHEN `DELETE`.
64+
INSERT VALUE #( entry = `Ctrl+D - delete triggered` ) INTO TABLE t_log.
65+
client->message_toast_display( `Ctrl+D: delete triggered` ).
66+
client->view_model_update( ).
67+
68+
WHEN `TOGGLE_REGISTRATION`.
69+
registered = xsdbool( registered = abap_false ).
70+
71+
IF registered = abap_true.
72+
shortcuts_set( event_save = `SAVE`
73+
event_delete = `DELETE` ).
74+
ELSE.
75+
" an empty event name removes the binding again
76+
shortcuts_set( event_save = ``
77+
event_delete = `` ).
78+
ENDIF.
79+
view_display( ).
80+
81+
WHEN `CLEAR`.
82+
t_log = VALUE #( ).
83+
client->view_model_update( ).
84+
85+
ENDCASE.
86+
87+
ENDMETHOD.
88+
89+
90+
METHOD shortcuts_set.
91+
92+
" one registration per key combination: t_arg is positional - the
93+
" combination (spelled like in UI5: Ctrl+S, Ctrl+Shift+D, F2) and the name
94+
" of the backend event it fires. Registering the same combination again
95+
" rebinds it, an empty event name removes it. The registry lives in the
96+
" frontend, so it survives every roundtrip until the app is left.
97+
client->follow_up_action( val = z2ui5_if_client=>cs_event-keyboard_shortcut
98+
t_arg = VALUE #( ( `Ctrl+S` )
99+
( event_save ) ) ).
100+
101+
client->follow_up_action( val = z2ui5_if_client=>cs_event-keyboard_shortcut
102+
t_arg = VALUE #( ( `Ctrl+D` )
103+
( event_delete ) ) ).
104+
105+
ENDMETHOD.
106+
107+
108+
METHOD view_display.
109+
110+
DATA(view) = z2ui5_cl_xml_view=>factory( ).
111+
112+
DATA(page) = view->shell(
113+
)->page(
114+
title = `abap2UI5 - Keyboard Shortcuts`
115+
navbuttonpress = client->_event_nav_app_leave( )
116+
shownavbutton = client->check_app_prev_stack( ) ).
117+
118+
page->message_strip(
119+
text = `Ctrl+S and Ctrl+D fire the backend events SAVE and DELETE - the same events the ` &&
120+
`buttons below send, but from the keyboard and without a control. The binding is ` &&
121+
`pure data (cs_event-keyboard_shortcut with the combination and the event name), ` &&
122+
`the browser default for the combination is suppressed.`
123+
type = `Information`
124+
showicon = abap_true
125+
class = `sapUiSmallMargin` ).
126+
127+
page->hbox( class = `sapUiSmallMargin`
128+
)->button(
129+
text = COND #( WHEN registered = abap_true
130+
THEN `Unregister the shortcuts`
131+
ELSE `Register the shortcuts` )
132+
icon = `sap-icon://keyboard-and-mouse`
133+
press = client->_event( `TOGGLE_REGISTRATION` )
134+
)->button(
135+
text = `Save (Ctrl+S)`
136+
type = `Emphasized`
137+
class = `sapUiTinyMarginBegin`
138+
press = client->_event( `SAVE` )
139+
)->button(
140+
text = `Delete (Ctrl+D)`
141+
class = `sapUiTinyMarginBegin`
142+
press = client->_event( `DELETE` )
143+
)->button(
144+
text = `Clear log`
145+
class = `sapUiTinyMarginBegin`
146+
press = client->_event( `CLEAR` ) ).
147+
148+
page->list(
149+
headertext = `Triggered events`
150+
items = client->_bind_edit( t_log )
151+
)->standard_list_item( title = `{ENTRY}` ).
152+
153+
client->view_display( view->stringify( ) ).
154+
155+
ENDMETHOD.
156+
157+
ENDCLASS.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
3+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
4+
<asx:values>
5+
<VSEOCLASS>
6+
<CLSNAME>Z2UI5_CL_DEMO_APP_471</CLSNAME>
7+
<LANGU>E</LANGU>
8+
<DESCRIPT>More - Keyboard Shortcuts (A)</DESCRIPT>
9+
<STATE>1</STATE>
10+
<CLSCCINCL>X</CLSCCINCL>
11+
<FIXPT>X</FIXPT>
12+
<UNICODE>X</UNICODE>
13+
</VSEOCLASS>
14+
</asx:values>
15+
</asx:abap>
16+
</abapGit>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
CLASS z2ui5_cl_demo_app_472 DEFINITION PUBLIC.
2+
3+
PUBLIC SECTION.
4+
INTERFACES z2ui5_if_app.
5+
6+
DATA block_navigation TYPE abap_bool.
7+
DATA last_press TYPE string.
8+
9+
PROTECTED SECTION.
10+
DATA client TYPE REF TO z2ui5_if_client.
11+
12+
METHODS on_event.
13+
METHODS view_display.
14+
15+
PRIVATE SECTION.
16+
ENDCLASS.
17+
18+
19+
CLASS z2ui5_cl_demo_app_472 IMPLEMENTATION.
20+
21+
METHOD z2ui5_if_app~main.
22+
23+
me->client = client.
24+
IF client->check_on_init( ).
25+
block_navigation = abap_true.
26+
view_display( ).
27+
ELSEIF client->check_on_navigated( ).
28+
view_display( ).
29+
ELSEIF client->check_on_event( ).
30+
on_event( ).
31+
ENDIF.
32+
33+
ENDMETHOD.
34+
35+
36+
METHOD on_event.
37+
38+
CASE client->get( )-event.
39+
40+
WHEN `LINK_PRESS`.
41+
42+
IF block_navigation = abap_true.
43+
last_press = `Link pressed - the browser did NOT follow the href, the backend decides what happens.`.
44+
ELSE.
45+
last_press = `Link pressed - the href was followed by the browser as usual.`.
46+
ENDIF.
47+
client->view_model_update( ).
48+
49+
WHEN `TOGGLE`.
50+
" the flag is part of the event registration, so the view has to be
51+
" rebuilt for the change to reach the frontend
52+
view_display( ).
53+
54+
ENDCASE.
55+
56+
ENDMETHOD.
57+
58+
59+
METHOD view_display.
60+
61+
DATA(view) = z2ui5_cl_xml_view=>factory( ).
62+
63+
DATA(page) = view->shell(
64+
)->page(
65+
title = `abap2UI5 - Event with preventDefault`
66+
navbuttonpress = client->_event_nav_app_leave( )
67+
shownavbutton = client->check_app_prev_stack( ) ).
68+
69+
page->message_strip(
70+
text = `A sap.m.Link normally follows its href when pressed. Registered with ` &&
71+
`s_ctrl-check_prevent_default the event cancels that built-in default ` &&
72+
`(oEvent.preventDefault()) before the roundtrip - the event still reaches the ` &&
73+
`backend, so the app decides what happens instead. Flip the switch to compare.`
74+
type = `Information`
75+
showicon = abap_true
76+
class = `sapUiSmallMargin` ).
77+
78+
DATA(form) = page->simple_form(
79+
title = `Link with a cancelled default`
80+
editable = abap_true
81+
)->content( `form` ).
82+
83+
form->label( `Cancel the browser navigation`
84+
)->switch(
85+
state = client->_bind_edit( block_navigation )
86+
change = client->_event( `TOGGLE` )
87+
)->label( `Link`
88+
)->link(
89+
text = `Open abap2ui5.org`
90+
href = `https://abap2ui5.org`
91+
target = `_blank`
92+
press = client->_event(
93+
val = `LINK_PRESS`
94+
s_ctrl = VALUE #( check_prevent_default = block_navigation ) )
95+
)->label( `Result`
96+
)->text( client->_bind_edit( last_press ) ).
97+
98+
client->view_display( view->stringify( ) ).
99+
100+
ENDMETHOD.
101+
102+
ENDCLASS.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
3+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
4+
<asx:values>
5+
<VSEOCLASS>
6+
<CLSNAME>Z2UI5_CL_DEMO_APP_472</CLSNAME>
7+
<LANGU>E</LANGU>
8+
<DESCRIPT>More - Link with preventDefault (A)</DESCRIPT>
9+
<STATE>1</STATE>
10+
<CLSCCINCL>X</CLSCCINCL>
11+
<FIXPT>X</FIXPT>
12+
<UNICODE>X</UNICODE>
13+
</VSEOCLASS>
14+
</asx:values>
15+
</asx:abap>
16+
</abapGit>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
CLASS z2ui5_cl_demo_app_473 DEFINITION PUBLIC.
2+
3+
PUBLIC SECTION.
4+
INTERFACES z2ui5_if_app.
5+
6+
PROTECTED SECTION.
7+
DATA client TYPE REF TO z2ui5_if_client.
8+
9+
METHODS view_display.
10+
11+
PRIVATE SECTION.
12+
ENDCLASS.
13+
14+
15+
CLASS z2ui5_cl_demo_app_473 IMPLEMENTATION.
16+
17+
METHOD z2ui5_if_app~main.
18+
19+
me->client = client.
20+
IF client->check_on_init( ).
21+
view_display( ).
22+
ENDIF.
23+
24+
ENDMETHOD.
25+
26+
27+
METHOD view_display.
28+
29+
DATA(view) = z2ui5_cl_xml_view=>factory( ).
30+
31+
DATA(page) = view->shell(
32+
)->page(
33+
title = `abap2UI5 - Menu Item Path`
34+
navbuttonpress = client->_event_nav_app_leave( )
35+
shownavbutton = client->check_app_prev_stack( ) ).
36+
37+
page->message_strip(
38+
text = `The toast shows the full path of the selected menu item ` &&
39+
`("Create New Site > Official Store"), not only its own text. ` &&
40+
`$controller.textPath( ) walks the item's parent chain in the control tree ` &&
41+
`and joins the texts - a walk no binding path can express. Everything happens ` &&
42+
`on the client, the menu selection needs no roundtrip at all.`
43+
type = `Information`
44+
showicon = abap_true
45+
class = `sapUiSmallMargin` ).
46+
47+
" the item's breadcrumb is resolved on the client and substituted into the
48+
" toast template ({0}); an argument starting with $ is a client-side
49+
" expression, everything else travels as a plain string
50+
DATA(menu_selected) = client->_event_client(
51+
val = z2ui5_if_client=>cs_event-control_global
52+
t_arg = VALUE #( ( `MESSAGE_TOAST` )
53+
( `show` )
54+
( `Action triggered on item: {0}` )
55+
( `$controller.textPath(${$parameters>/item})` ) ) ).
56+
57+
DATA(menu) = page->hbox( class = `sapUiSmallMargin`
58+
)->menu_button( text = `Actions`
59+
)->menu( itemselected = menu_selected ).
60+
61+
menu->_generic(
62+
name = `MenuItem`
63+
t_prop = VALUE #( ( n = `text` v = `Create New Site` ) )
64+
)->menu_item( text = `Official Store`
65+
)->menu_item( text = `Franchise Store`
66+
)->menu_item( text = `Pop-up Store` ).
67+
68+
menu->_generic(
69+
name = `MenuItem`
70+
t_prop = VALUE #( ( n = `text` v = `Manage Users` ) )
71+
)->menu_item( text = `Add User`
72+
)->menu_item( text = `Remove User` ).
73+
74+
menu->menu_item( text = `Log Out` ).
75+
76+
client->view_display( view->stringify( ) ).
77+
78+
ENDMETHOD.
79+
80+
ENDCLASS.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
3+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
4+
<asx:values>
5+
<VSEOCLASS>
6+
<CLSNAME>Z2UI5_CL_DEMO_APP_473</CLSNAME>
7+
<LANGU>E</LANGU>
8+
<DESCRIPT>More - Menu Item Path (A)</DESCRIPT>
9+
<STATE>1</STATE>
10+
<CLSCCINCL>X</CLSCCINCL>
11+
<FIXPT>X</FIXPT>
12+
<UNICODE>X</UNICODE>
13+
</VSEOCLASS>
14+
</asx:values>
15+
</asx:abap>
16+
</abapGit>

0 commit comments

Comments
 (0)