Show TOC

Property BindingLocate this document in the navigation structure

With property binding, you can initialize properties of a control automatically and update them based on the data of the model.

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

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

  • Using JavaScript, in the settings object in the constructor of a control, or in special cases, using the bindProperty method of a control

Once you have defined the property binding, the property is updated automatically every time the property value of the bound model 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"
	}
}
To define property binding in the control declaration in the XML view, just include the binding path within curly brackets (see also Binding Path):
<mvc:View
	controllerName="sap.ui.sample.App"
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc">
	<Input
		value="{/company/name}"
	/>
</mvc:View>
In JavaScript, you can include the binding path within curly brackets as a string literal in the settings object:
var oInput = new sap.m.Input({
	value: "{/company/name}"
});

You can also use an complex syntax for property bindings. This complex 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-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 that you used in the constructor to define the binding:

oInput.bindProperty("value", {
	path: "value",
	type: new sap.ui.model.type.Integer()
});
Note
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
Values in data are often represented in an internal format and need to be converted to an external format for visual representation, especially numbers, dates, and times with locale-dependent external formats. SAPUI5 provides two different options for converting data. You can use both options for each binding, you don't have to use one option consistently throughout your app:
  • Formatter functions for one-way conversion

  • Data types in two-way binding

    Data types can be used to parse user input in addition to formatting values.

Using a Formatter Function

If you define the property binding in the XML view, you need to define a formatter function (roundToMillion) in the view 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 this context of a formatter function is generally set to the control (or managed object) that owns the binding. However, in XML views, the reference to the formatter is done in the view controller by putting a dot (.) in front of the name of the formatter function ({ formatter: '.myformatter' }). In this case, the formatter's this context is bound to the controller.

<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>

If you use JavaScript, you can pass the formatter function as a third parameter to the bindProperty method, or you can add the binding info with the formatter key. The formatter has a single parameter value, which is the value that is to be formatted, 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";
		}
	}
})
Because it can contain any JavaScript, the formatter function can be used for formatting a value and also for performing type conversions or calculating results, 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";
}); 
Caution

The framework only updates a binding when one of the properties included in the binding changes. If the formatter uses another property value that is not part of the binding definition, the framework won't know that the result depends on that additional property and could miss necessary updates. Therefore, make sure that you declare a composite binding referencing all necessary properties (maybe even from different models).

Using Data Types

The data type system enables you to format and parse data, as well as to validate whether the entered data lies within any defined constraints. SAPUI5 comes with several predefined and ready-to-use types, referred to as simple types. For more information, 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. For more information, see the API Reference in the Demo Kit.
<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 feature 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 is 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, such as 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.

Changing the 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 (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, that is, from model to view.