Samples / Learn / Navigation

Navigation

Refuses to leave an app with unsaved changes: the confirmation popup in front of nav_app_leave, and how the dirty flag gets there.

Class
z2ui5_cl_smp_app_279
Repository
abap2UI5/samples
UI5 libraries
sap.m, sap.tnt, sap.ui.core, z2ui5.cc
Lowest UI5 release
1.71
In the browser
Runs in the playground
Controls it builds
sap.m.Button, sap.m.Dialog, sap.m.FlexBox, sap.m.Input, sap.m.MessageStrip, sap.m.Page, sap.m.Shell, sap.m.Text, sap.m.VBox, sap.tnt.InfoLabel, sap.ui.core.FragmentDefinition, sap.ui.core.mvc.View, z2ui5.cc.Dirty
Documentation
cookbook/event_navigation/navigation/inner_app ↗

The class

" @keywords dirty unsaved changes leave confirmation warning set_focus popup_display popup_close
" @summary Refuses to leave an app with unsaved changes: the confirmation popup in front of nav_app_leave, and how the dirty flag gets there.
" @docs https://abap2ui5.github.io/docs/cookbook/event_navigation/navigation/inner_app
CLASS z2ui5_cl_smp_app_279 DEFINITION PUBLIC.

  PUBLIC SECTION.
    INTERFACES z2ui5_if_app.

    DATA text_input TYPE string.
    DATA dirty TYPE abap_bool.

  PROTECTED SECTION.
    DATA client TYPE REF TO z2ui5_if_client.

    METHODS view_display.
    METHODS on_event.
    METHODS popup_confirm_display.

  PRIVATE SECTION.
ENDCLASS.


CLASS z2ui5_cl_smp_app_279 IMPLEMENTATION.


  METHOD z2ui5_if_app~main.

    me->client = client.
    IF client->check_on_navigated( ).
      view_display( ).
    ELSEIF client->check_on_event( ).
      on_event( ).
    ENDIF.

  ENDMETHOD.


  METHOD view_display.

    DATA(page) = z2ui5_cl_ui5_view_builder=>factory(
        )->ele( n = `View` ns = `mvc`
            )->a( n = `displayBlock` v = `true`
            )->a( n = `height`       v = `100%`
            )->a( n = `xmlns`        v = `sap.m`
            )->a( n = `xmlns:mvc`    v = `sap.ui.core.mvc`
            )->a( n = `xmlns:tnt`    v = `sap.tnt`
            )->a( n = `xmlns:z2ui5`  v = `z2ui5.cc`
            )->ele( `Shell`
                )->ele( `Page`
                    )->a( n = `title`          v = `abap2UI5 - Navigation - Data Loss Protection on Leaving`
                    )->a( n = `showNavButton`  b = client->check_app_prev_stack( )
                    )->a( n = `navButtonPress` v = client->_event( `BACK` ) ).

    page->tag( `MessageStrip`
        )->a( n = `text` v = `Unsaved input marks the page dirty via a custom control; navigating back then opens a confirmation ` &&
                   `popup instead of leaving and losing the data.`
        )->a( n = `type`     v = `Information`
        )->a( n = `showIcon` b = abap_true
        )->a( n = `class`    v = `sapUiSmallMargin` ).

    DATA(box) = page->ele( `FlexBox`
        )->a( n = `class`      v = `sapUiTinyMargin`
        )->a( n = `alignItems` v = `Start`
        )->a( n = `direction`  v = `Row` ).

    box->tag( `Input`
        )->a( n = `id`          v = `input`
        )->a( n = `placeholder` v = `Enter data, submit and navigate back to trigger data loss protection`
        )->a( n = `value`       v = client->_bind( text_input )
        )->a( n = `submit`      v = client->_event( `SUBMIT` )
        )->a( n = `width`       v = `40rem` ).

    box->ele( n = `InfoLabel` ns = `tnt`
        )->a( n = `class`       v = `sapUiSmallMarginBegin sapUiTinyMarginTop`
        )->a( n = `text`        v = `dirty`
        )->a( n = `colorScheme` v = `8`
        )->a( n = `visible`     v = client->_bind( dirty ) ).

    box->tag( `Button`
        )->a( n = `press`   v = client->_event( `RESET` )
        )->a( n = `text`    v = `Reset`
        )->a( n = `visible` v = client->_bind( dirty )
        )->a( n = `class`   v = `sapUiSmallMarginBegin` ).

    " isDirty is what arms the control - unbound it stays false, and the
    " browser never asks before the page is closed or reloaded
    page->tag( n = `Dirty` ns = `z2ui5`
        )->a( n = `isDirty` v = client->_bind( dirty ) ).

    client->view_display( page->stringify( ) ).

    client->follow_up_action(
        val   = z2ui5_if_client=>cs_event-set_focus
        t_arg = VALUE #( ( `input` ) ) ).

  ENDMETHOD.


  METHOD on_event.

    CASE client->get_event( ).
      WHEN `BACK`.

        IF dirty = abap_true.
          popup_confirm_display( ).

        ELSE.
          client->nav_app_leave( ).
        ENDIF.
      WHEN `POPUP_LEAVE`.

        client->popup_destroy( ).
        dirty = VALUE #( ).
        client->nav_app_leave( ).

      WHEN `SUBMIT`.
        dirty = xsdbool( text_input IS NOT INITIAL ).
      WHEN `RESET`.

        dirty      = VALUE #( ).
        text_input = VALUE #( ).

    ENDCASE.

  ENDMETHOD.


  METHOD popup_confirm_display.

    DATA(popup) = z2ui5_cl_ui5_view_builder=>factory(
        )->ele( n = `FragmentDefinition` ns = `core`
            )->a( n = `xmlns`      v = `sap.m`
            )->a( n = `xmlns:core` v = `sap.ui.core` ).
    popup->ele( `Dialog`
        )->a( n = `title` v = `Warning`
        )->a( n = `icon`  v = `sap-icon://status-critical`
        )->ele( `VBox`
            )->a( n = `class` v = `sapUiSmallMargin`
            )->tag( `Text`
                )->a( n = `text`  v = `Your entries will be lost when you leave this page.`
        )->end(
        )->ele( `buttons`
            )->tag( `Button`
                )->a( n = `press` v = client->follow_up_action( client->cs_event-popup_close )
                )->a( n = `text`  v = `Cancel`
            )->tag( `Button`
                )->a( n = `press` v = client->_event( `POPUP_LEAVE` )
                )->a( n = `text`  v = `Leave Page`
                )->a( n = `type`  v = `Emphasized` ).

    client->popup_display( popup->stringify( ) ).

  ENDMETHOD.
ENDCLASS.