Show TOC

Property BindingLocate this document in the navigation structure

Property binding allows properties of the control to get automatically initialized and updated from model data.

To define a property binding on a control, the following options exist:

  • As part of the control’s declaration in an XML view

  • Using JavaScript:
    • In the settings object in the constructor of a control

    • Using the bindProperty method of a control

Once you have defined the property binding, the property is updated automatically every time the bound model property value is changed and vice versa.

Let’s say we have the following JSON data:

{
		"company" : {
		"name"  : "Acme Inc."
		"street": "23 Franklin St." 
		"city"  : "Claremont"
		"state" : "New Hampshire"
		"zip"   : "03301"
		"revenue": "1833990"
	}
}

The most convenient way to define a property binding, which is sufficient in most cases, is to include the binding path within curly brackets in the control's XML view declaration, as outlined in Binding Path:

<mvc:View
	controllerName="sap.ui.sample.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Input
		value="{/company/name}"
	/>
</mvc:View>

If you declare your control directly in JavaScript, you can include the binding path within curly brackets in JavaScript as a string literal in the settings object:

var oInput = new sap.m.Input({
	value: "{/company/name}"
});

Moreover, you can use an extended syntax for property bindings. This extended syntax allows you to define additional binding information to be contained in the settings object, such as a formatter function. If you are working with XML views, make sure that you've turned on complex binding syntax in your bootstrap script, as shown here:

<script id="sap-ui-bootstrap"
	src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
	data-sap-ui-theme="sap_bluecrystal"
	data-sap-ui-xx-bindingSyntax="complex"
	data-sap-ui-libs="sap.m"
	data-sap-ui-compatVersion="edge"
	data-sap-ui-preload="async"
	data-sap-ui-resourceroots='{
		"sap.ui.sample": "./"
	}' >
</script>

You can then set the bindingMode or other additional properties like this:

<mvc:View
	controllerName="sap.ui.sample.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Input
		value="{ 
			path:'/company/name', 
			mode: 'sap.ui.model.BindingMode.OneWay' 
		}"
	/>   
</mvc:View>

In JavaScript views or controllers, you use a JS object instead of a string literal. This must contain a path property containing the binding path and can contain additional properties:

var oInput = new sap.m.Input ({
    value: {
		path: "/company/name", 
		mode: sap.ui.model.BindingMode.OneWay
	}
});

Depending on the use case, it may be useful to define the binding at a later time, using the bindProperty method:

oInput.bindProperty("value", "/company/name");

This option also allows you to use the same object-literal as in the constructor to define the binding:

oInput.bindProperty("value", {
	path: "value",
	type: new sap.ui.model.type.Integer()
});

Some controls offer convenience methods for the main properties of a control that are most likely to be bound by an application:

oTextField.bindValue("/company/name");

To remove a property binding, you can use the unbindProperty method. The property binding is removed automatically whenever a control is destroyed:

oTextField.unbindProperty("value");
Formatting Property Values

The values in the data are often represented in some kind of internal format and need to be converted to an external format for visual representation. This is especially necessary for numbers, dates and times with locale-dependent external formats. SAPUI5 provides two different options for converting data: Formatter functions allow one-way conversion only, while data types can also be used for two-way binding as they cannot only format, but also parse user input. You can choose freely between these two options for each binding, depending on your scenario.

When using an XML view, the formatter function can be defined in the views controller:

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
	"use strict";
	return Controller.extend("sap.ui.sample.App", {
		……………
		roundToMillion: function(fValue) {
			if (fValue) {
				return "> " + Math.floor(fValue/1000000) + "M";
			}
			return "0";
		}
	});
}); 

The XML view references the formatter using extended syntax (notice the dot!):

<mvc:View
	controllerName="sap.ui.sample.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Input
		value="{ path:'/company/revenue', 
		formatter: '.roundToMillion'}"
	/>
</mvc:View>

Using JavaScript, the formatter function can either be passed as a third parameter to the bindProperty method, or contained in the binding info with the key "formatter". It has a single parameter value, which is the value that needs to be formatted to an external representation, and is executed as a member of the control, meaning it can access additional control properties or model data.

oTextField.bindProperty("value", "/company/title", function(sValue) {
	return sValue && sValue.toUpperCase();
});

oControl = new sap.m.Input({
	value: {
		path:"/company/revenue",
		formatter: function(fValue) {
			if (fValue) {
				return "> " + Math.floor(fValue/1000000) + "M";
			}
			return "0";
		}
	}
})

As it can contain any JavaScript, the formatter function, cannot only be used for formatting a value, but can also do type conversion or calculate results from a given value, for example to show a special traffic light image depending on a boolean value:

oImage.bindProperty("src", "/company/trusted", function(bValue) {
	return bValue ? "green.png" : "red.png";
}); 
Using Data Types

The type system enables data to be formatted and parsed, as well as validating if the data entered lies within any defined constraints. SAPUI5 comes with several predefined and ready-to-use types, referred to as simple types, see Simple Types.

Here’s how you can use these types in an XML view:

<mvc:View
	controllerName="sap.ui.sample.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Input
		value="{ path:'/company/revenue', 
		type: 'sap.ui.model.type.Integer'}"/>
</mvc:View>

You can also provide parameter values for some of the simple types in your XML view. These are declared as formatOptions, as you can see in the Float type sample below. Permitted formatOptions are properties of the corresponding data type. Please refer to the API documentation in the Demo Kit for more details.

<mvc:View
   controllerName="sap.ui.sample.App"
   xmlns="sap.m"
   xmlns:mvc="sap.ui.core.mvc">
   <Input
      value="{ path:'/company/revenue', 
           type: 'sap.ui.model.type.Float',
           formatOptions: {
                   minFractionDigits: 2,
                   maxFractionDigits: 2
           }
      }"/>
</mvc:View>

Using JavaScript, you can define a type to be used for a property binding by passing it as a third parameter in bindProperty or by adding it to the binding information by using the key type, as shown here:

oTextField.bindProperty("value", "/company/name", new sap.ui.model.type.String());

oControl = new sap.m.Input({
    value: {
        path:"/company/revenue",
        type: new sap.ui.model.type.Float({
            minFractionDigits: 2,
            maxFractionDigits: 2
        })
    }
})
Predefined data types also offer visual feedback for erroneous user input. To turn this feedback on, add the following line to your controller's init function:
sap.ui.getCore().getMessageManager().registerObject(this.getView(), true);

You can define custom types by inheriting from sap.ui.model.SimpleType and implementing the three methods formatValue, parseValue and validateValue. formatValue will be called whenever the value in the model is changed to convert it to the type of the control property it is bound to, and may throw a FormatException. parseValue is called whenever the user has modified a value in the UI and the change is transported back into the model. It may throw a ParseException if the value cannot be converted. If parsing is successful, validateValue is called to check additional constraints, like minimum or maximum value, and throws a ValidateException if any constraints are violated.

sap.ui.model.SimpleType.extend("sap.ui.sample.Zipcode", {
    formatValue: function(oValue) {
        return oValue;
    },
    parseValue: function(oValue) {
        return oValue;
    },
    validateValue: function(oValue) {
       if (!/^(\d{5})?$/.test(oValue)) {
            throw new sap.ui.model.ValidateException("Zip code must have 5 digits!");
       }
    }
});

You can use your custom types in XML views or JavaScript in the same way as you would apply predefined types:

<mvc:View
   controllerName="sap.ui.sample.App"
   xmlns="sap.m"
   xmlns:mvc="sap.ui.core.mvc">
   
   <Input
      value="{ path:'/company/zip', 
      type: 'sap.ui.sample.Zipcode'
     }"/>

</mvc:View>

For more information, see Using the Data Binding Type System.

Binding Mode

By default, all bindings of a model instance have the default binding mode of the model, but you can change this behavior if needed. When creating a PropertyBinding, you can specify a different binding mode, which is then used exclusively for this specific binding. Of course, a binding can only have a binding mode that is supported by the model in question.

	var oModel = new sap.ui.model.json.JSONModel();
	// default binding mode is Two Way
	oModel.setData(myData);
	sap.ui.getCore().setModel(oModel);
	var oInputFirstName = new sap.m.Input ();
	
	// bind value property one way only 
	// propertyname, formatter function, binding mode
	oInputFirstName.bindValue("/firstName", null, sap.ui.model.BindingMode.OneWay);
	oInputFirstName.placeAt("target1");

	oInputLastName = new sap.m.Input();
	// bind value property two way which is the default
	oInputLastName.bindValue("/lastName");
	oInputLastName.placeAt("target2");
}

In the example above, two Input fields are created and their value property is bound to the same property in the model. The first Input binding has a one-way binding mode, whereas the second Input has the default binding mode of the model instance, which is two-way. For this reason, when text is entered in the first Input, the value will not be changed in the model. This only happens if text is entered in the second Input. Then, of course, the value of the first Input will be updated as it has a one-way binding, which means from model to view.