Wednesday, 20 May 2020

Simple web forms realized by Fiori Elements Quick Create pattern

In this blog you will see how the Quick Create pattern from Fiori Elements can be used to easily create a HTML form application.

Forms


HTML form is a simple type of a one step/ one page application consisting of a list of fields for data entry and a SUBMIT button.  After the SUBMIT is hit the page data is sent to a back end system and the process is done.


There are many examples of this application type in the web for instance:

◉ Self registrations
◉ Simple orders especially in an internal organization
◉ Messages / Notifications
◉ Registration of participations

The Quick Create Pattern


SAP offers with the Quick Create pattern in Fiori elements an easy way to create such a HTML form in Fiori technology. Quick Create was originally developed for usage in SAP CoPilote but is very easy to use as standalone app as well. Quick create basically consists of one page of input fields and a Create Button.

The development steps


As an overview here are the development steps:

◉ A gateway service where you define the data structure for the form fields and an implemented the CREATE method (optionally more data structures for Value Helps including Metadata enhancements)
◉ A Fiori Elements App based on the Quick Create pattern
◉ An annotation file to define the form page
◉ An enhancement to the application HTML file to show the created object

Example: problem notification in SAP PM


The example app  creates a PM – notification (can be maintained by transaction IW22 in the backend).

The Fiori UI will look like:

SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Certification, SAP ABAP Exam Prep

When the creation was done you will see the result in the backend:

SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Certification, SAP ABAP Exam Prep

(As prerequisite the maintenance type I1 must exist in the SAP customizing and functional locations must exist to add a notification to.)

These are the minimal steps (no value helps or other enhancements) to develop this application:

1. Add the SAP Gateway definitions

Goto transaction SEGW and create a new project Z_NOTIF
Add an new entity by selecting Data Model -> right mouse -> Import -> RFC/BOR interface Choose option RFC and BAPI_ALM_NOTIF_CREATE as function module.
Name the entity notification_ih.Choose these fields from the BAPI:
NotifNumber (mark it later as key!)
NotifType
FunctLoc
ShortText
PriokxMark the entitySet notificationSet as creatable and updatable.Now you can generate the classes and services.
In our case the class names should be:
ZCL_Z_NOTIF_DPC / ZCL_Z_NOTIF_DPC_EXT
ZCL_Z_NOTIF_MPC / ZCL_Z_NOTIF_MPC_EXT

2. Activate the service Z_NOTIF_SRV in the transaction /IWFND/MAINT_SERVICE

3. Add the coding fort he object creation in the ZCL_Z_NOTIF_DPC_EXT class: Redefine the method notificationset_create_entity.

METHOD notificationset_create_entity.

    DATA: lv_NOTIF_TYPE         TYPE bapi2080-notif_type,
          lv_NOTIFHEADER        TYPE bapi2080_nothdri,
          ls_created_ntf_header TYPE bapi2080_nothdre,
          lt_longtext           TYPE TABLE OF bapi2080_notfulltxti,
          ls_notif              TYPE zcl_z_notif_mpc=>ts_notification_ih,
          lt_bapiret2           TYPE TABLE OF bapiret2,
          ls_t100_message       TYPE scx_t100key.

    lv_NOTIF_TYPE = 'I1'. "simple real estate message

    io_data_provider->read_entry_data(    IMPORTING    es_data = ls_notif ).

    lv_notifheader-funct_loc = ls_notif-funct_loc.
    lv_notifheader-priority = ls_notif-priokx(1). "first character = key in text

    SPLIT ls_notif-short_text AT cl_abap_char_utilities=>newline INTO
          TABLE DATA(lt_lines) .
    LOOP AT lt_lines ASSIGNING FIELD-SYMBOL(<f_line>).
      APPEND INITIAL LINE TO lt_longtext ASSIGNING FIELD-SYMBOL(<f_longtext>).
      <f_longtext>-objtype = 'QMEL' .
      <f_longtext>-objkey = '00000000' .
      <f_longtext>-FOrmat_col = 'AS' .
      <f_longtext>-text_line = <f_line>.
    ENDLOOP.

    lv_notifheader-short_text = lt_lines[ 1 ] .

    CALL FUNCTION 'BAPI_ALM_NOTIF_CREATE'
      EXPORTING
        notif_type         = lv_notif_type
        notifheader        = lv_notifheader
      IMPORTING
        notifheader_export = ls_created_ntf_header
      TABLES
        longtexts          = lt_longtext
        return             = lt_bapiret2
      .
    LOOP AT lt_bapiret2 INTO DATA(lv_bapiret2) WHERE type CA 'EA'.
      EXIT.
    ENDLOOP.
    IF sy-subrc EQ 0.
      ls_t100_message-msgid = lv_bapiret2-id .
      ls_t100_message-msgno  = lv_bapiret2-number .
      ls_t100_message-attr1 = lv_bapiret2-message_v1 .
      ls_t100_message-attr2 = lv_bapiret2-message_v2.
      ls_t100_message-attr3 = lv_bapiret2-message_v3.
      ls_t100_message-attr4 = lv_bapiret2-message_v4.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
        EXPORTING
          textid = ls_t100_message.

    ENDIF.
    CALL FUNCTION 'BAPI_ALM_NOTIF_SAVE'
      EXPORTING
        number      = ls_created_ntf_header-notif_no
      IMPORTING
        notifheader = ls_created_ntf_header
      TABLES
        return      = lt_bapiret2.
    LOOP AT lt_bapiret2 INTO lv_bapiret2 WHERE type CA 'EA'.
      EXIT.
    ENDLOOP.
    IF sy-subrc EQ 0.
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception .
    ENDIF.
    er_entity = ls_notif.
    er_entity-qmnum = ls_created_ntf_header-notif_no .
  ENDMETHOD.
4. Import and generate the UI in the SAP WEB IDE using the Quick Create pattern

SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Certification, SAP ABAP Exam Prep

Choose your service as datasource and create the project.

5. Add an annotation file to establish the frontend fields for the Fiori App via right mouse -> New -> Annotation File and copy the following content:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="/sap/opu/odata/sap/Z_NOTIF_SRV/$metadata">
<edmx:Include Alias="Metadata" Namespace="Z_NOTIF_SRV"/>
</edmx:Reference>
<edmx:Reference Uri="https://wiki.scn.sap.com/wiki/download/attachments/448470968/UI.xml?api=v2">
<edmx:Include Alias="UI" Namespace="com.sap.vocabularies.UI.v1"/>
</edmx:Reference>
<edmx:Reference Uri="https://wiki.scn.sap.com/wiki/download/attachments/448470974/Common.xml?api=v2">
<edmx:Include Alias="Common" Namespace="com.sap.vocabularies.Common.v1"/>
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Notification.annotation0.Z_NOTIF_SRV">
<Annotations Target="Metadata.notification_ih">
<Annotation Term="UI.QuickCreateFacets">
<Collection>
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Target" AnnotationPath="@UI.FieldGroup#QuickCreate"/>
</Record>
</Collection>
</Annotation>
<Annotation Term="UI.FieldGroup" Qualifier="QuickCreate">
<Record Type="UI.FieldGroupType">
<PropertyValue Property="Data">
<Collection>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="Priokx"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="FunctLoc"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="ShortText">
<Annotation Term="UI.MultiLineText" Bool="true"/>
</PropertyValue>
</Record>
</Collection>
</PropertyValue>
<PropertyValue Property="Label" String="{@i18n&gt;appDescription}"/>
</Record>
</Annotation>
<Annotation Term="Common.SemanticKey">
<Collection>
<PropertyPath>NotifNumber</PropertyPath>
</Collection>
</Annotation>
</Annotations>
<Annotations Target="Metadata.notification_ih/ShortText">
<Annotation Term="UI.MultiLineText" Bool="true"/>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
6. Add coding to inform the user about the created message number from the backend.
Open the flpSandbox.html file from the SAP Web IDE. Locate the event objectCreated: function in the coding an replace the coding
objectCreated: function() {
console.warn(“Method objectCreated() unimplemented in mock”);
},
by:

objectCreated: function(context) {
document.getElementById("__button0").innerHTML = "<h2> Message was created with number" + context.sPath.substring(18, 26) + "</h2>" ;
},​

Now after the create button was pressed the user gets the result:

SAP ABAP Tutorial and Material, SAP ABAP Learning, SAP ABAP Certification, SAP ABAP Exam Prep

Enhancements for value helps


To make the frontend easier to use  let’s see as an example how to add a value help to the functional location and the priority fields.

You need to start in the gateway to add data structures which define the fields of the value help. Then an implementation for the get_entityset must be added in case it cannot be derived from a search help. Finally the metadata of the service needs to be enhanced to connect the data fields from the service to the value help entity sets.

1. To add the two new structures in the SAP Gateway definition go to transaction SEGW

2. Import the searchhelp IFLMT (name of the entity is Iflmt and of the entity set IflmtSet). Choose the fields:

Tplnr
Pltxt
Spras 
and mark Tplnr as key.

There is no need to implement the get_entityset method since it is automatically done by the generator.

3. Import the structure T356_T (name of the entity is T356_T and of the entity set T356_TSet). Choose the field Priokx and mark it as key.

4. Regenerate the Gateway project

5. Redefine the method t356_tset_get_entityset from ZCL_Z_NOTIF_DPC_EXT and put this coding:
  METHOD t356_tset_get_entityset.
    SELECT FROM t356_t
      FIELDS
      priok,
      priokx
      WHERE spras EQ @sy-langu AND
      artpr = '$1'
      ORDER BY priok
        INTO CORRESPONDING FIELDS OF TABLE @et_entityset
      .
  ENDMETHOD.​

6. Redefine the DEFINE method from ZCL_Z_NOTIF_MPC_EXT to connect the 2 new entitysets as a search help in the Fiori UI by putting this coding:

 METHOD define.

    DATA : lv_namespace   TYPE string,
           lr_annotation  TYPE REF TO cl_fis_shlp_annotation,
           lr_annotation2 TYPE REF TO cl_fis_shlp_annotation.

    super->define( ) .

    model->set_soft_state_enabled( iv_soft_state_enabled = abap_true ).
    model->get_schema_namespace( IMPORTING ev_namespace = lv_namespace ).

    "Priority Search Help Annotation
    lr_annotation = cl_fis_shlp_annotation=>create(
        io_odata_model               = model
        io_vocan_model               = vocab_anno_model
        iv_namespace                 = lv_namespace
        iv_entitytype                = 'notification_ih'
        iv_property                  = 'Priokx'
        iv_valuelist_entityset       = 'T356_TSet'
        iv_valuelist_property        = 'Priokx' ) . 

    " lr_annotation->add_display_parameter( iv_valuelist_property  = 'Name' ) .
    " lr_annotation->add_display_parameter( iv_valuelist_property  = 'Description' ) .
    " lr_annotation->add_display_parameter( iv_valuelist_property  = 'PostCode' ) .
    " lr_annotation->add_display_parameter( iv_valuelist_property  = 'City' ) .
    DATA(lo_txt_property2) = model->get_entity_type( 'notification_ih' )->get_property( 'Priokx' ).
    lo_txt_property2->set_value_list( /iwbep/if_mgw_odata_property=>gcs_value_list_type_property-fixed_values ).

    "Functional Location Search Help Annotation
    lr_annotation2 = cl_fis_shlp_annotation=>create(
        io_odata_model               = model
        io_vocan_model               = vocab_anno_model
        iv_namespace                 = lv_namespace
        iv_entitytype                = 'notification_ih'
        iv_property                  = 'FunctLoc'
        iv_search_help               = 'IFLMT'
        iv_search_help_field         = 'TPLNR'
        iv_valuelist_entityset       = 'IflmtSet'
        iv_valuelist_property        = 'Tplnr' ).

  lr_annotation2->add_display_parameter( iv_valuelist_property  = 'Pltxt' ) .
  lr_annotation2->add_display_parameter( iv_valuelist_property  = 'Spras' ) .

ENDMETHOD.

Now you have search helps as well, the one for the priority field is a dropdown list the value list for the functional location comes with a selection dialog.

No comments:

Post a Comment