In this chapter, we will cover the following recipes:
Using client-side templates to generate HTML markup from JSON data
Creating a two-way binding between
View
elements and JavaScript objects using the Model View ViewModel (MVVM) patternUsing
source
andtemplate
binding withViewModel
to generate HTML contentValidating user input using the built-in Validator
The Kendo UI library is composed of various widgets that are built for both the web and mobile platform. It also provides data visualization components, which can be used to build rich and interactive charts. This chapter focuses on the Kendo UI application framework. This framework includes tools such as the client-side templating engine, data binding, and routing, and it also helps users to validate form fields.
The concept of using a templating system with some data source to generate a dynamic web content has been around web development for a long time. Java Server Pages (Java), Smarty (PHP), and Django (Python) are examples of some of the server-side templating engines. Generating content at runtime used to be a server-side-only affair. In recent years, generating the content on the client side (on the browser) has been embraced.
The dynamic applications that are being built today require the user interface to be updated frequently. This can be achieved by fetching the HTML fragment from the server and then inserting it into the document. However, this requires the server to generate such fragments as opposed to delivering complete web pages. In the client-side templating engine, the servers are responsible for sending only the dynamic data in the JSON format and then have the page assembled in the browser using a static client-side template. This template can be served from Content Delivery Network (CDN) instead of the same server that sends the dynamic data. The time taken to send the records in the form of JSON data and not generate the markup on the server side takes away more CPU cycles, thereby improving the performance of the application to a great extent. Consider a shopping cart application, which lists the products in the cart. The cart data can be sent to the client in the JSON format. Then, use templates to generate an HTML markup on the client side.
There are various types of client-side templating engines to choose from; some of them are logic-less such as Mustache and Handlebars, some are based on the HAML syntax such as Jade, and some others are based on John Resig's micro templating such as underscore.js
.
In Kendo UI, a microtemplating library is used, which is called hash templates. In these templates, hash symbols are used to mark regions in the template that will be executed when the template is used to generate dynamic content.
The Kendo UI library exports an object, kendo
, which is a namespace for various other objects and functions. The template function is one of them. The template function compiles hash-based templates into functions that can be evaluated for rendering. It is useful to render complicated bits of HTML from a JSON data source. The following are the three hash-based syntaxes:
The syntax to render literal values is
#= #
The syntax to render HTML-encoded values is
#: #
The syntax to execute arbitrary JavaScript code is
# for(…) #
Let's take a look at a very simple example of rendering firstName
and lastName
of a person using the following hash-based template:
<script> var template = kendo.template("Full Name: " +"<span> #= lastName # </span>," + "<span> #= firstName # </span>"); var data = {}; data.lastName = "Smith"; data.firstName = "Todd"; var result = template(data); $('.addressContainer').append(result); </script>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Here, the #= <literal> #
expression is used. Similarly, we can also use a hash-based expression to render HTML-encoded values:
<script> var template = kendo.template("Full Name: <span> # lastName # # </span>, <span> #: firstName # </span>"); var data = {}; data.lastName = "<b>Smith</b>"; data.firstName = "<i>Todd</i>"; var result = template(data); $('.addressContainer').append(result); </script>
Here, the #: <literal> #
expression is used. Rendering HTML-encoded values is particularly useful when you are accepting HTML strings as a part of a form input string, and they display the same in the result. The HTML characters\tags present in the data would be escaped and rendered as strings.
Now, let's understand what is happening in the preceding code examples. In the first example, the first line is as follows:
var template = kendo.template("Full Name: " + "<span> #= lastName # </span>," + "<span> #= firstName # </span>");
Here, the template function is used to compile the input string. Note that the input string contains HTML tags with hash-based expressions. This will return a function that can then be used with data to generate output. In the following four lines of the code snippet, a JavaScript data object with two variables, lastName
and firstName
, is created:
var data = {}; data.lastName = "Smith"; data.firstName = "Todd"; var result = template(data);
The last line in the preceding code snippet invokes the compiled function (assigned to the template variable), which then passes the JavaScript object as a parameter. This will replace the literal values inside the hash-based expression and generate the following output string:
Full Name: <span> Smith </span>, <span> Todd </span>
In the second example, the code is very similar, except that the #: <literal> #
hash-based expression is used. This expression will escape the HTML tags and generate the output that contains HTML tags as it is.
As seen in the previous examples, the HTML is passed as a string to the kendo.template
function. An alternative to this is to define a template in a script tag:
<script type="text/x-kendo-template" id="testTemplate"> # for (var i=0; i < functions.length; i++) { # <li> #= functions[i] # </li> # } # </script>
Note the hash-based syntax used in the preceding code as well; it contains a JavaScript for
statement that iterates over an array and generates list tags (<li>
tags). Now, to compile this template, we will refer to the script tag using the id
attribute:
<script> var templateContent = $('#testTemplate').html(); var template = kendo.template(templateContent); var functions = ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"]; var result = template(functions); $('.listContainer').append(result); </script>
Here, the template is referred using the id
attribute, #testTemplate
. The content of the template is retrieved using $('#testTemplate').html()
. The content is then used with the kendo.template
function to generate the markup. This content is then inserted into the page by appending the same inside an unordered list using $('ul.listContainer').append(result)
.
There are various architectural patterns that are used in most of the applications. The three very important architectural patterns are as follows:
Model View Controller (MVC)
Model View Presenter (MVP)
Model View ViewModel (MVVM)
These patterns are heavily used in structuring both the desktop and server-side applications. In recent years, these patterns have been applied to client-side applications as well. Frameworks such as AngularJS, BackboneJS, and EmberJS provide components that can be readily used to build applications that follow one of these patterns. All three patterns mentioned previously try to separate the development of the user interface from the development of the business logic.
The Model View ViewModel (MVVM) pattern is an architectural pattern, which is based on MVC and MVP. Here, the model layer represents the domain-specific data. An example application will include the bank account number, the holder's name, the balance amount, and so on. The model layer represents raw data that needs to be formatted to be consumed by View
. The View
layer consumes the data provided by the model and formats it as required. On the other hand, the behavior of the application or the business logic is encapsulated in a layer called ViewModel
.
There are several frameworks, such as KnockoutJS, KnockbackJS, and Kendo UI, that implement the MVVM pattern. In Kendo UI, the MVVM pattern is at the core of the application framework. The framework provides APIs using which the various components, such as model, ViewModel
, and data binding (that binds the markup to the ViewModel
object) can be accomplished.
To illustrate how the MVVM pattern is implemented in Kendo UI, let's take a look at a very simple example in which the form elements are bound to a ViewModel
object. The ViewModel
object, in this case, would define the model data and also the behavior for one of the elements:
<form id="testView"> Firstname: <input id="firstName" type="text" data-bind="value: fisrtName"> <br/> Lastname: <input id="lastName" type="text" data-bind="value: lastName"> <br/> Fullname: <input id="fullName" type="text" data-bind="value: fullName" readonly> <br/> <input type="submit"> </form>
In the previous code snippet, a form with the id
attribute, testview
, that contains three input elements (textboxes) is created. Note the data-bind
attribute in each one of these input elements. The data-bind
attribute is used to specify the binding between View
elements and the ViewModel
object.
Here, the first input element specifies the value of the data-bind
attribute as value: firstName
. This indicates that the value of the input element is bound to the firstName
model attribute. Now let's define ViewModel
, which encapsulates the model data and behavior:
var viewModel = kendo.observable({ fisrtName: "Sagar", lastName: "Ganatra", fullName: function() { return this.get("fisrtName") + ' ' + this.get("lastName"); } });
A ViewModel
object is created using the Observable
interface on the kendo
object. In this example, the ViewModel
object contains the firstName
, lastName
, and fullName
attributes. Note that while firstName
and lastName
are of the string type, the fullName
attribute is a function that returns a string by concatenating firstName
and lastName
.
Now that we have the markup and ViewModel
, they should be tied to each other. The bind
method is used to bind View
components to ViewModel
:
kendo.bind($('form#testView'),viewModel);
The first argument to the bind function is the View
component referred by using $('form#testView')
and the second argument is the ViewModel
object, viewModel
. Once View
and ViewModel
are bound, any changes made to the model will update View
, and any changes made by the user will be reflected in the model.
When you execute the previously mentioned code snippets, the form elements with the values mentioned in the model are populated, as shown in the following screenshot:

Notice that in the markup, the last input element for FullName is read only. It is bound to a fullName
model attribute, which is a function that returns the string concatenated by firstName
and lastName
. When you change the value of either firstName
or lastName
, the fullName
model also gets updated and the same is reflected in the View
class.

In the preceding screenshot, when the value of the Firstname input element is changed, the value of the Fullname attribute also gets updated. Note that the model attributes are updated on a blur event on the View
component.
In the previous screenshot, we saw how data binding can be used to set the values of input elements in the form. In addition to setting the value for some of the elements in the page, data binding can also be used to set attribute values (attr
), to set HTML content (html
), hide or show the elements in the page (visible
and invisible
), and so on.
Let's take a look at each one of these scenarios. The attr
binding is used to bind tag
attributes with model attributes in the following code snippet:
<a data-bind="attr: {href: websiteLink}" target="_blank"> Click Here </a>
In the preceding code snippet, the data-bind
attribute has the attr: {href: websiteLink}
value. Here, attr
indicates that the tag attributes are bound to ViewModel
. In this example, the href
attribute of the anchor element is bound to a model attribute, websiteLink
. The ViewModel
object for the same would be as shown in the following code snippet:
<script> var viewModel = kendo.observable({ websiteLink: 'http://www.packtpub.com', }); kendo.bind($('a'),viewModel); </script>
In the code snippet, the ViewModel
object contains only one attribute, websiteLink
. The value for this model attribute is an external link, which is http://www.packtpub.com. When the View
component is bound to the ViewModel
object, the anchor element is updated, which then has an attribute, href
, that refers to the external link mentioned in ViewModel
.
Similarly, the components in View
can be hidden or shown on the page by using the binding attribute, visible
:
<div id="view"> <span id="container" data-bind="visible: isVisible"> Some content here.... </span> <br/> <button id="toggleVisible" data-bind="click: updateVisible"> Toggle Visible </button> </div>
In the previous code snippet, the span element has the data-bind
attribute set to visible: isVisible
. Here, the value of the isVisible
model attribute should be of the Boolean type. If the same is false, then the style attribute of the span element is set to display: none
. Also, the button has the data-bind
attribute set to click: updateVisible
. Here, the button's click
event is bound to the model attribute, updateVisible
. The ViewModel
object for the previous markup is shown in the following code snippet:
var viewModel = kendo.observable({ isVisible: true, updateVisible: function() { this.set('isVisible', !this.get('isVisible')); } }); kendo.bind($('div#view'),viewModel);
The initial value for isVisible
in ViewModel
is set to true and hence the text, Some Content here…
, (inside the span) would be visible. When you click on the toggleVisible button, it toggles the isVisible
model attribute. This will either show or hide the span element.
In the previous recipe, data binding between View
components and ViewModel
attributes was explored. Binding can be performed not only on the value of the form elements, but also on the attributes, and also to hide or show the elements on the page. In this recipe, we will look at the source and the HTML binding in combination.
Consider a dropdown (to select an element) that you want to populate it with data (option tags). The data for these could be provided from a ViewModel
object; use a template to generate these option tags.
Let's first construct a ViewModel
object:
var viewModel = kendo.observable({ optionsData: [ {optionValue:1, optionName: "Test1"}, {optionValue:2, optionName: "Test2"}, {optionValue:3, optionName: "Test3"} ] });
The ViewModel
object here contains an optionsData
attribute, which is a collection (array) of objects. Each object in optionsData
contains two attributes, namely optionValue
and optionName
. The optionValue
attribute will be used for the value
attribute of the option
tag, and optionName
will be used for the HTML content to be shown in the dropdown. The template that contains the option tag binding is shown in the following code snippet:
<script id="select-template" type="text/x-kendo-template"> <option data-bind= "attr: {value: optionValue}, html: optionName"> </option> </script>
Here, the template with the id
attribute set to select-template
contains one option tag. The option tag contains the data-bind
attribute whose value is attr: {value: optionValue}, html: optionName
. We already saw the attribute binding in action in the previous recipe. The other binding specified here is html
. This binding is used to generate the HTML content for the tag. These option tags should be bound to the ViewModel
object and be encapsulated inside a select tag.
The select tag can refer to the template (mentioned previously) and bind to the ViewModel
object using the source
attribute:
<select data-template="select-template" data-bind="source: optionsData"> </select>
Here, the select tag specifies the two attributes, namely data-template
and data-bind
. The value of the data-template
attribute is the id
attribute of the template (the script tag) that we defined earlier, that is, select-template
. This instructs kendo
to bind the template to the select
tag, and the generated content would become the HTML content for this select
tag.
The data-bind
attribute specifies a binding source that refers to the optionData
model attribute in ViewModel
. Now, the only step pending is to bind View
elements to ViewModel
, which is attained by executing the following line of code:
kendo.bind($('select'),viewModel);
The select
tag specifies the source binding that refers to the optionsData
model attribute. This will make the collection of objects available to all the tags inside it.
The data-template
attribute that refers to the template in the page is provided with the collection of objects (optionsData
) and the template is iterated for the number of entries in the array. In this example, the optionsData
collection contains three objects and hence, the template is generated three times and inserted as the HTML content for the select
tag. The generated content would look like the following code snippet:
<select data-template="select-template" data-bind="source: optionsData"> <option data-bind= "attr: {value: optionValue}, html: optionName" value="1"> Test1 </option> <option data-bind= "attr: {value: optionValue}, html: optionName" value="2"> Test2 </option> <option data-bind= "attr: {value: optionValue}, html: optionName" value="3"> Test3 </option> </select>
The data-
attributes would remain as they are, and the generated content now has the value
attribute and the HTML content. Note that the preceding code could have been accomplished by using a for
statement in a hash-based template and then appending the generated output to the select
tag. However, using a data-template
attribute and source binding allows you to do this seamlessly and write more intuitive code.
This pattern can be applied in various situations. Another example includes generating list tags (li
elements) and inserting them into an unordered or ordered list.
Validating user-input data is one of the common tasks in any project. A client-side validation includes checking the form-input data for the type or for the missing data. This is not to say that the server-side validation is not important. However, a client-side validation takes care of performing basic validations and shows error or validation messages before submitting the form data to a server for processing. Therefore, it provides instant feedback to the user and improves the overall user experience.
With the advent of HTML5, the input fields in a form can have types defined for it. For example, an input field that should accept only an e-mail address can be specified as type=email
. Similarly, the input fields can have types such as URL
, NUMBER
, RANGE
, DATE
, SEARCH
, and COLOR
. When the user specifies incorrect data for any of these fields, the browser will show an appropriate validation message. In addition to the types, the form elements can also be marked as required by adding an additional attribute, required
, to the input elements. However, some of the old browsers don't support HTML5 features, including the previously mentioned form validation. The Kendo UI library comes with a built-in validator that can be used to perform client-side validations.
The Kendo UI validator encourages users to use HTML5-like syntax and provides out-of-the-box support to make the form validation work on older browsers.
Let's take a look at an example where in one input, the text field is marked as required, and the other input field of the email
type is also marked as required. Please note that this is very much an HTML5 syntax and the user doesn't have to alter the markup to mark the fields as required or of a different type:
<form id="testView"> <label for="firstName">First Name</label> <input id="firstName" name="First Name" type="text" required validationMessage="Please specify First Name"> <br> <label for="emailId">Email Address</label> <input id="emailId" name="Email Address" type="email" required data-required-msg="Please specify Email Address" data-email-msg="Email format is not correct"> <br> <input type="submit"> </form>
In the preceding markup, the input fields are marked as required
and validation messages are defined in data-
attributes. After specifying the validation messages in the markup, the last step is to attach the kendo
validator to the form. This is attained by executing the following code snippet:
$("form#testView").kendoValidator();
In the previous code snippet, the form
element is marked for validation by calling the kendoValidator
function on the same.
In the previous markup, the firstName
field is of the text
type and is marked as required
by adding the required
attribute. Also, a validationMessage
attribute that specifies the validation message to show when the user doesn't provide any input data is mentioned. The next input element, emailId
, is of the email
type and is marked as required
as well. In this case, there are two rules that are applicable; firstly, the field is required, and secondly, the user should enter a valid e-mail address. Therefore, we need to specify two validation messages for the input field. Here, the data-required-msg
and data-email-msg
attributes are specified. When the user doesn't specify any value, the validation message specified in data-required-msg
is displayed. Also, when the user specifies an invalid e-mail address, the validation message specified in data-email-msg
is displayed.
Now, let's see this in action; when the user doesn't specify values for both the fields, then the required validation message would be shown as follows:

When the user clicks on the Submit button, the validator runs, inspects the input data, and shows the validation message if there is no data specified. Now, when the user keys in an invalid value in the e-mail field, the validation message specified in data-email-msg
would be shown as follows:

Here, both the fields have some data in place and hence, the required
field validation has passed. However, the e-mail address is not valid and, hence, you see the corresponding validation message being shown.
In the previous example, we saw that the validation message was specified in the markup. It is also possible to configure the validator so that the same message is applicable to all fields with a specific validation rule. For example, all required fields can have the same validation message, such as This field is required.
The messages
configuration option can be used to set the various validation messages that can be applied across all the input elements, as shown in the following code snippet:
$("form#testView").kendoValidator({ messages: { // {0} would be replaced with the input element's name required: '{0} is required' email: 'Enter a valid email address' } });
Here, the validation messages are removed from the markup and the same is specified in the
kendoValidator
method. Note the use of {0}
in the validation message for the required fields. Here {0}
is replaced with the input element's name. For example, if the first name is not specified, the message would be First Name is required.
Similarly, in the case of fields of the email
type, the Enter a valid email address validation message is shown if the user doesn't provide a valid e-mail address.
In a case where the validation message is specified in the markup as well as in the kendoValidator
method as options, the message specified in the markup would take precedence.
It is also possible to define custom validation rules in addition to the standard set of validation rules mentioned previously. This is done by passing the rules
option to the kendoValidator
method. Let's consider the same example form that contains two input fields, namely firstName
and emailId
.
Now, let's add a custom rule that doesn't allow numbers to be entered in these fields:
$("form#testView").kendoValidator({ rules: { customRule1: function(input) { var re = /^[A-Za-z]+$/; return re.test(input.val()); } }, messages: { customRule1: 'Numbers are not allowed' } });
In the preceding code snippet, a custom rule, customRule1
, is defined. When the form is being validated, all input fields are checked against this custom rule. Here, a regular expression is used to test whether the value of the input element contains a numeric value. If this returns false
, then the validation message (defined under the messages object) Numbers are not allowed is displayed.

As highlighted in the preceding screenshot, the validation message is shown as the user has entered alphanumeric characters.