Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
4,426

In his blog post “Creating OData-based SAPUI5 UIs for BPM tasks – the easy way…” Frederic showed the ‘New Task’ wizard capable of generating custom task UIs with just a few clicks. In the SAP NetWeaver Developer Studio (NWDS) versions discussed, only data types with simple properties but without complex structures could be used as a starting point for the UI generation. Complex data structures had to be flattened to own XSD types before running the UI generation.

Starting with SAP NetWeaver 7.3 EHP1 SP16 (and SAP NetWeaver 7.4 SP11), the ‘New Task’ wizard provides the generation of task UIs based on complex data structures including collections. Additionally, the buttons ‘Reject’ and ‘Put Back’ are generated.

This blog post provides you with a quick overview of this extended functionality.

Triggering task UI generation with complex data types

The actual usage of the SAPUI5 generation in NWDS hasn’t changed at all. If you have read the aforementioned blog post from Frederic, you already know how to use the ‘New Task’ wizard with the ‘Generate UI Component’ option. Subsequently, our blog post uses the same example process. We have added an escalation handler at the ‘Verify Customer Data’. Why? Stay tuned – we will explain this in the context of the ‘Reject’ button a little bit later.

Becoming more complex – generation is still easy!

We have adapted the ‘Customer’ data type to be able to show how the SAPUI5 generation deals with complex data structures and collections:


<?xml version="1.0" encoding="UTF-8"?>

<schema targetNamespace="http://demo.sap.com/CustomerDataTypes" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://demo.sap.com/CustomerDataTypes">

  <complexType name="Customer">

    <sequence>

      <element name="firstName" type="string"></element>

      <element name="lastName" type="string"></element>

      <element name="address" type="tns:Address" maxOccurs="unbounded"></element>

      <element name="currency" type="string" default="EUR"></element>

    </sequence>

  </complexType>

  <complexType name="Address">

      <sequence>

      <element name="street" type="string"></element>

      <element name="city" type="string"></element>

      <element name="zip" type="int"></element>

      <element name="country" type="string"></element>

    </sequence>

  </complexType>

 

  <complexType name="Credit">

    <sequence>

      <element name="creditLimit" type="double"></element>     

    </sequence>

  </complexType>

</schema>

While previously the address fields have been manually flattened already in the XSD data type, we have now the complex type ‘Address’. Since customers can have more than one address it can be used with a cardinality higher than 1 (XSD terminology “unbounded”) for a given customer. The fields such as address_street are now child elements of the complex type “Address” and thus it is not required anymore to prefix their names with “address_”.

In our process model the data object DO_Customer is still based on the ‘Customer’ type, which now contains (as just explained) collection-style complex types. When it comes to the generation of the task UI with the ‘New Task’ wizard, we can select now both, DO_Credit and DO_Customer. This automatically selects all included wrapper and leaf elements. Also, as a child of DO_Customer, the repeatable address element is selected as well. In contrast to the previous time, we leave the preset selection as we do not deselect any wrappers manually:

After confirming the wizard with the ‘Finish’ button, the following component folder is generated:

The resulting files in the ‘view’ folder depend on the chosen data structure. For each contained complex type, an own ‘Form.fragment.xml’ file is generated. Additionally, there are two further fragments (‘FormForm.fragment.xml’ and ‘startTypeINPUTForm.fragment.xml’) representing the automatically generated wrapper types.

Without any further modifications, after deployment the resulting task UI is shown in the web browser:

As we could already see in the ‘view’ folder, in the UI for each complex type (plus generated wrappers) an own section is shown.

For an important research project, let’s move Frederic from our Walldorf headquarters to our labs in Palo Alto. Just modifying the data in the form and clicking the ‘Approve’ button will complete the given task and the modeled output mapping on the human activity will map the provided data back to the process context. Here, we also see the nested structure of the data:

Figure out our latest collection style

Having done this initial roundtrip, you might wonder:  Where is the ‘collection’ flavor of the data reflected? When starting the generation in the wizard, chosen data types containing collections are accepted. But the resulting UI represents the data only in a non-repeatable form view. For the repeatable data type ‘Address’, the file ‘addressForm.fragment.xml’ was generated as follows:



<core:FragmentDefinition xmlns="sap.ui.commons"

      xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core">

                  <f:Form minWidth="1024"

                        maxContainerCols="2" editable="true" class="editableForm">

                        <f:layout>

                             <f:ResponsiveGridLayout

                                   labelSpanL="2"

                                   labelSpanM="2"

                                   emptySpanL="6"

                                   emptySpanM="6"

                                   columnsL="1"

                                   columnsM="1"

                             />

                        </f:layout>

                        <f:formContainers>

                        <f:FormContainer expandable="false" title="{i18n>addressLabel}">

                             <f:formElements>

                                   <f:FormElement label="{i18n>address.zip}">

                                         <f:fields>

                                               <TextField value="{path:'address/results/0/zip', type:'sap.ui.model.type.Integer'}" editable="true"/>

                                         </f:fields>

                                   </f:FormElement>

                                   <f:FormElement label="{i18n>address.street}">

                                         <f:fields>

                                               <TextField value="{path:'address/results/0/street'}" editable="true"/>

                                         </f:fields>

                                   </f:FormElement>

                                   <f:FormElement label="{i18n>address.country}">

                                         <f:fields>

                                               <TextField value="{path:'address/results/0/country'}" editable="true"/>

                                         </f:fields>

                                   </f:FormElement>

                                   <f:FormElement label="{i18n>address.city}">

                                         <f:fields>

                                               <TextField value="{path:'address/results/0/city'}" editable="true"/>

                                         </f:fields>

                                   </f:FormElement>

                             </f:formElements>

                        </f:FormContainer>

                        </f:formContainers>

                  </f:Form>

</core:FragmentDefinition>


By default, paths like ‘address/results/0/street’ fetch only the content of the first element (index 0) from the OData model. As it highly depends on the use case how collection-style data should get presented, customers should modify the ‘addressForm.fragment.xml’ according to their requirements. For example, customers can use easily a table or ‘RowRepeater’ control to present collection-style data. Please refer to the UI5 documentation for details.

What are the new buttons for?

You don’t agree? Reject!

You might have noticed the new buttons, which are generated. As already demonstrated, the ‘Approve’ button completes the task, provides the data to the main flow (if a mapping is modeled) and the process continues in the regular flow.

The ‘Reject’ button, however, throws an escalation event, which can be handled at the human activity itself or at any higher level of the process hierarchy. By default, the data structure itself is the same as when approving the task. As in our BPM flow shown at the beginning of this blog post, we catch the escalation event and abort the BPM process rather than continuing the regular flow.

You cannot work on this task? Put it back!

After having opened and thus automatically claimed a task, you figure out that you cannot work on this task. So you might like to put it back to all other potential owners again. For doing this, you can press the ‘Put Back’ button. This revokes the reservation of the task and brings it back to its initial state. In addition, the task UI browser window is closed.

Conclusion

With this blog post we have demonstrated the latest capabilities of the generation of SAPUI5 task UIs. Now, supporting also complex data types with collections and providing further action buttons out of the box, the generated UIs are already suitable for initial use and can be a good starting point for further UI customizing.

4 Comments