Source Binding
The Kendo UI Source (source
) binding sets the HTML content of the target element by rendering a Kendo UI template with a View-Model value.
If the View-Model value changes, the HTML content of the target element is updated.
The template is specified by the data-template
attribute of the element. The value of that attribute should be the value of the id
of an existing script
element which defines the Kendo UI template. If a template is not specified, a default template is used depending on the element tag name.
The
source
binding does not support nesting widgets with source binding such astreeview
with source binding to the view model. The nested widgets trigger a source change, which forces the root source binging to re-render its content, leading to infinitive loops. The proper way to nest widgets with source is to use thedata-source
attribute demo.
Source Binding to Root Elements
When the View-Model value is an array, the source
binding iterates all array items and renders the template. The accumulated output of the template is set as the HTML content of the target element. The context inside the template is the current array item.
Adding or removing items from the array updates the HTML contents of the target element.
A single root element should be used in the template when binding to an array. Having two first-level DOM elements is going to result in an erratic behavior.
The following example is a correct instance of a template with a single root element.
<ul data-template="ul-template" data-bind="source: products">
</ul>
<script id="ul-template" type="text/x-kendo-template">
<li>
id: <span data-bind="text: id"></span>
</li>
</script>
<script>
var viewModel = kendo.observable({ products: [ { id: 1 }, { id: 2 }, { id: 3 } ] });
kendo.bind($("ul"), viewModel);
</script>
The following example is an unsupported instance of a template with multiple first-level DOM elements.
<ul data-template="ul-template" data-bind="source: products">
</ul>
<!-- Bindings will not work as expected -->
<script id="ul-template" type="text/x-kendo-template">
<li> id: <span data-bind="text: id"></span> </li>
<li> details: <span data-bind="text: id"></span> </li>
</script>
<script>
var viewModel = kendo.observable({ products: [ { id: 1 }, { id: 2 }, { id: 3 } ] });
kendo.bind($("ul"), viewModel);
</script>
Source Binding to Arrays of Objects
Source binding requires the result set to be either an
ObservableArray
or a list ofObservableObject
instances.
The following example will output three li
elements—one for every item in the products
array.
<ul data-template="ul-template" data-bind="source: products">
</ul>
<script id="ul-template" type="text/x-kendo-template">
<li>
id: <span data-bind="text: id"></span>
name: <span data-bind="text: name"></span>
</li>
</script>
<script>
var viewModel = kendo.observable({
products: [
{ id: 1, name: "Coffee" },
{ id: 2, name: "Tea" },
{ id: 3, name: "Juice" }
]
});
kendo.bind($("ul"), viewModel);
</script>
The following example demonstrates the final output. Note that all data
attributes are removed for clarity.
<ul>
<li>
id: <span>1</span>
name: <span>Coffee</span>
</li>
<li>
id: <span>2</span>
name: <span>Tea</span>
</li>
<li>
id: <span>3</span>
name: <span>Juice</span>
</li>
</ul>
Source Binding to Arrays of Primitive Objects
If the array contains primitive objects, such as Number
, String
, and Date
, the this
reserved word should be used inside the template declaration to refer to the current item.
<ul data-template="ul-template" data-bind="source: products">
</ul>
<script id="ul-template" type="text/x-kendo-template">
<li data-bind="text: this"></li>
</script>
<script>
var viewModel = kendo.observable({
products: [ "Coffee", "Tea", "Juice" ]
});
kendo.bind($("ul"), viewModel);
</script>
The following example demonstrates the final output. Note that all data
attributes are removed for clarity.
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Juice</li>
</ul>
Source Binding to Non-Array Values
The source
binding also supports non-array values. In this case the specified template is applied by using the value of the View-Model field and the output is set as the HTML contents of the target element. The context inside the template will be the value of the View-Model field.
<div data-template="div-template" data-bind="source: person">
<script id="div-template" type="text/x-kendo-template">
Name: <span data-bind="text: name"></span>
</script>
</div>
<script>
var viewModel = kendo.observable({
person: {
name: "John Doe"
}
});
kendo.bind($("div"), viewModel);
</script>
The following example demonstrates the expected output. All data
attributes are removed for clarity.
<div>
Name: <span>John Doe</span>
</div>
Source Binding to the DataSource
The source
binding to a Kendo UI DataSource instance can be used for Kendo UI widgets, which can normally be data-bound to a Kendo UI DataSource outside an MVVM scenario. This binding can also be used with elements, which are containers for items, such as <ul>
, <table>
, <select>
, and others. In this case an item template must be defined via data-template
. The source
binding does not work for plain HTML elements that are not meant to be bound to collections of data items, such as textboxes.
<div id="example">
<p>Kendo UI DropDownList</p>
<select data-role="dropdownlist"
data-bind="source: fruits"
data-text-field="name"
data-value-field="id"></select>
<p>Select</p>
<select data-bind="source: fruits" data-template="select-template"></select>
<script id="select-template" type="text/x-kendo-template">
<option value="#: id #">#: name #</option>
</script>
<p>Unordered list</p>
<ul data-bind="source: fruits" data-template="list-template">
<li></li>
</ul>
<script id="list-template" type="text/x-kendo-template">
<li><strong>ID</strong> #: id #, <strong>Name</strong> #: name #</li>
</script>
<p>Table</p>
<table>
<thead><th>ID</th><th>Name</th></thead>
<tbody data-bind="source: fruits" data-template="row-template">
<tr><td></td><td></td></tr>
</tbody>
</table>
<script id="row-template" type="text/x-kendo-template">
<tr><td>#: id #</td><td>#: name #</td></tr>
</script>
</div>
<script>
var viewModel = kendo.observable({
fruits: new kendo.data.DataSource({
data: [
{ id: 1, name: "Apples" },
{ id: 2, name: "Oranges" },
{ id: 3, name: "Bananas" }
],
schema: {
model: {
fields: {
id: { type: "number" },
name: { type: "string" }
}
}
}
})
});
kendo.bind("#example", viewModel);
</script>
<style>
table {
border-collapse: collapse;
}
table th,
table td {
border: 1px solid #999;
padding: .3em .6em;
text-align: left;
}
</style>
Source Binding to View-Model
If you want to use the View-Model itself, use the this
reserved word, as shown below.
<div data-template="div-template" data-bind="source: this">
<script id="div-template" type="text/x-kendo-template">
Name: <span data-bind="text: name"></span>
</script>
</div>
<script>
var viewModel = kendo.observable({
name: "John Doe"
});
kendo.bind($("div"), viewModel);
</script>
The output is exactly the same as in the previous case.
<div>
Name: <span>John Doe</span>
</div>
Selecting Source Binding to Primitive Values
When applied to a select
element, the source
binding creates option
elements. The following example demonstrates source binding of a select
element to an array of primitive objects.
<select data-bind="source: colors"></select>
<script>
var viewModel = kendo.observable({
colors: [ "Red", "Green", "Blue" ]
});
kendo.bind($("select"), viewModel);
</script>
The source
binding creates an option
element for every item in the colors
array and sets its HTML contents to the value of that item. This results in the output below.
<select>
<option>Red</option>
<option>Green</option>
<option>Blue</option>
</select>
Selecting Source Binding to Non-Primitive Values
The source
binding could also populate a select
element from an array of non-primitive objects. The data-text-field
and data-value-field
attributes are used to specify how the value and content of the option
elements are going to be bound.
The following example demonstrates source binding of a select
element to an array of non-primitive values. If the data-text-field
and data-value-field
attributes are not set and the select
is bound to an array of non-primitive objects, the content of the option
elements is set to [object Object]
.
<select data-text-field="name" data-value-field="id"
data-bind="source: products"></select>
<script>
var viewModel = kendo.observable({
products: [
{ id: 1, name: "Coffee" },
{ id: 2, name: "Tea" },
{ id: 3, name: "Juice" }
]
});
kendo.bind($("select"), viewModel);
</script>
This results in the output below.
<select>
<option value="1">Coffee</option>
<option value="2">Tea</option>
<option value="3">Juice</option>
</select>
Important Notes
The this
keyword may convey different meaning in different scenarios. To avoid this behavior, this
has to:
- Be specified in the
source
binding if and only if the entire View-Model object is used as a value. - Be used inside a template only when the
source
binding is using an array of primitive objects. -
Always be used on its own. The following example is not supported.
<div data-bind="text: this.bogus"></div> <script id="bogus-template" type="text/x-kendo-template"> <span data-bind="text: this.bogus"></span> </script>
See Also
- MVVM Overview
- Overview of the Attribute Binding
- Overview of the Checked Binding
- Overview of the Click Binding
- Overview of the CSS Binding
- Overview of the Custom Binding
- Overview of the Disabled Binding
- Overview of the Enabled Binding
- Overview of the Events Binding
- Overview of the HTML Binding
- Overview of the Invisible Binding
- Overview of the Style Binding
- Overview of the Text Binding
- Overview of the Value Binding
- Overview of the Visible Binding