Skip to content

Latest commit

 

History

History
159 lines (116 loc) · 7.25 KB

Step_22_Custom_Formatters_0f8626e.md

File metadata and controls

159 lines (116 loc) · 7.25 KB
loio
0f8626ed7b7542ffaa44601828db20de

Step 22: Custom Formatters

If we want to do a more complex logic for formatting properties of our data model, we can also write a custom formatting function. We will now add a localized status with a custom formatter, because the status in our data model is in a rather technical format.


Preview

A status is now displayed with a custom formatter

A list of invoices is displayed below the panel


You can view and download all files at Walkthrough - Step 22.


sap.ui.define([], () => {
	"use strict";

	return {
		statusText(sStatus) {
			const oResourceBundle = this.getOwnerComponent().getModel("i18n").getResourceBundle();
			switch (sStatus) {
				case "A":
					return oResourceBundle.getText("invoiceStatusA");
				case "B":
					return oResourceBundle.getText("invoiceStatusB");
				case "C":
					return oResourceBundle.getText("invoiceStatusC");
				default:
					return sStatus;
			}
		}
	};
});

We create a new folder model in our app project. The new formatter file is placed in the model folder of the app, because formatters are working on data properties and format them for display on the UI. So far we did not have any model-related artifacts, except for the Invoices.json file, we will now add the folder webapp/model to our app. This time we do not extend from any base object but just return a JavaScript object with our formatter functions inside the sap.ui.define call.

The statusText function gets the technical status from the data model as input parameter and returns the correct human-readable text from the resourceBundle file.

Note:

In the above example, this refers to the controller instance as soon as the formatter gets called. We access the data model via the component using this.getOwnerComponent().getModel() instead of using this.getView().getModel(). The latter call might return undefined, because the view might not have been attached to the component yet, and thus the view can't inherit a model from the component.

Additional Information:


webapp/view/InvoiceList.view.xml

<mvc:View
    controllerName="ui5.walkthrough.controller.InvoiceList"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc">
    <List
        headerText="{i18n>invoiceListTitle}"
        class="sapUiResponsiveMargin"
        width="auto"
        items="{invoice>/Invoices}">
        <items>
            <ObjectListItem
                title="{invoice>Quantity} x {invoice>ProductName}"
                number="{
                    parts: [
                        'invoice>ExtendedPrice',
                        'view>/currency'
                    ],
                    type: 'sap.ui.model.type.Currency',
                    formatOptions: {
                        showMeasure: false
                    }
                }"
                numberUnit="{view>/currency}"
                numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }">
                <firstStatus>
                    <ObjectStatus
                        core:require="{
                            Formatter: 'ui5/walkthrough/model/formatter'
                        }"
                        text="{
                            path: 'invoice>Status',
                            formatter: 'Formatter.statusText.bind($controller)'
                        }"/>
                </firstStatus>
            </ObjectListItem>
        </items>
    </List>
</mvc:View>

To load our formatter functions, we use the require attribute with the sap.ui.core namespace URI, for which the core prefix is already defined in our XML view. This allows us to write the attribute as core:require. We then add our custom formatter module to the list of required modules and assign it the Formatter alias, making it available for use within the view.

We add a status using the firstStatus aggregation to our ObjectListItem that will display the status of our invoice. The custom formatter function is specified with the reserved formatter property of the binding syntax. There, we use our Formatter alias that holds our formatter functions in order to access the desired function via Formatter.statusText. When called, we want the this context to be set to the current view controller's context. To achieve this, we use .bind($controller).


webapp/i18n/i18n.properties

# App Descriptor
appTitle=Hello World
appDescription=A simple walkthrough app that explains the most important concepts of OpenUI5

# Hello Panel
showHelloButtonText=Say Hello
helloMsg=Hello {0}
homePageTitle=Walkthrough
helloPanelTitle=Hello World
openDialogButtonText=Say Hello With Dialog
dialogCloseButtonText=Ok

# Invoice List
invoiceListTitle=Invoices
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done

We add three new entries to the resource bundle that reflect our translated status texts. These texts are now displayed below the number attribute of the ObjectListItem dependent on the status of the invoice.

Parent topic:Walkthrough Tutorial (JavaScript)

Next:Step 21: Expression Binding

Previous:Step 23: Filtering

Related Information

Formatting, Parsing, and Validating Data