Show TOC

Step 14: Expression BindingLocate this document in the navigation structure

Expression binding allows you to display a value on the screen that has been calculated from values found in some model object. This way simple formatting or calculations can be inserted directly into the data binding string. In this example, we will change the color of the price depending on whether it is above or below some arbitrary threshold. The threshold value is also stored in the JSON model.

Preview
Figure 1: Values formatted
Coding

You can view and download all files in the Explored app in the Demo Kit under Data Binding - Step 14.

webapp/view/App.view.xml
...
    </content>
  </Panel>
  <Panel headerText="{i18n>panel3HeaderText}" class="sapUiResponsiveMargin" width="auto">
    <content>
      <List headerText="{i18n>invoiceListTitle}" class="sapUiResponsiveMargin" width="auto"
            items="{/invoices}">
        <items>
          <ObjectListItem
              title="{Quantity} x {ProductName}"
              number="{ parts: [{path: 'ExtendedPrice'},
                                {path: '/currencyCode'}],
                        type: 'sap.ui.model.type.Currency',
                        formatOptions: { showMeasure: false }
                      }"
              numberUnit="{/currencyCode}"
              numberState="{= ${products>UnitPrice}  > ${/priceThreshold} ? 'Error' : 'Success' }">
            <attributes>
              <ObjectAttribute text="{ path: 'Status',
                                       formatter: '.formatStatusText' }"/>
            </attributes>
          </ObjectListItem>
        </items>
      </List>
    </content>
  </Panel>
</mvc:View>

In the XML view, we add a new numberState property to the ObjectListItem element within the List. The value of this property is an expression that will be evaluated for each item.

webapp/index.html
...
  "salesToDate" : 12345.6789,
  "priceThreshold" : 20,
  "currencyCode" : "EUR"
...

We add a new property called priceThreshold against which each invoice value will be checked.

As a result of binding an expression to the numberState property, the error status (color) of the price field will change depending on the invoice value.

Look at the following two expressions:
  • numberState="{= ${products>UnitPrice} > ${/priceThreshold} ? 'Error' : 'Success' }">

  • numberState="{= ${products>UnitPrice} <= ${/priceThreshold} ? 'Success' : 'Error' }">

Can you see why one of these expressions will work, and the other will not?

Logically, both expressions are identical; yet the first one works, and the second does not: it produces only an empty screen and an "Invalid XML" message in the browser's console… Hmmm, what's going on here?

In order to understand why this situation occurs, you must understand how XML files are parsed.

When an XML file is parsed, certain characters have a special (that is, high priority) meaning to the XML parser. When such characters are encountered, they are always interpreted to be part of the XML definition itself and not part of any other content that might exist within the XML document.

As soon as the XML parser encounters one of these high-priority characters (in this case, a less-than (<) character), it will always be interpreted as the start of a new XML tag – irrespective of any other meaning that character might have within the context of the expression. This is known as a syntax collision.

In this case, the collision occurs between the syntax of XML and the syntax of the JavaScript-like expression language used by SAPUI5.

Therefore, this statement fails because the less-than character is interpreted as the start of an XML tag: numberState="{= ${products>UnitPrice} <= ${/priceThreshold} ? 'Success' : 'Error' }">

This particular problem can be avoided in one of two ways:
  • Reverse the logic of the condition (use "greater than or equal to" instead of "less than")

  • Use the escaped value for the less-than character: numberState="{= ${products>UnitPrice} &lt;= ${/priceThreshold} ? 'Success' : 'Error' }">

Since the use of an escaped character is not so easy to read, the preferred approach is to reverse the logic of the condition and use a greater-than character instead.

The ampersand (&) character also has a high priority meaning to the XML parser. This character will always be interpreted to mean "The start of an escaped character". So if you wish to use the Boolean AND operator (&&) in a condition, you must escape both ampersand characters (&amp;&amp;).