Kendo UI: Creating an Dynamic Input Form from an External JSON ViewModel

By in , ,
No comments

One of my favorite features of Kendo UI is its support for MVVM through the kendo.observable object. Creating an observable ViewModel allows you to declaratively and intuitively bind data using the “data-bind” attribute, with virtually no code. Using this method, you can even generate a form on the fly, specifying not only different field types, but even different attributes such as “required” and setting a CSS class to highlight specific fields. This is what we’ll look at today. Sample JSON For this example, I’ve created a simple JSON array of items that will represent the input fields on the page. Note I’ve included several important properties such as “type” and “css” while I’ll later use to bind to the form.

{ "fields" : [ { "css" : "cssClass1",

        "label" : "Field 1",

        "name" : "Field1",

        "required" : false,

        "type" : "text"

      },

      { "css" : "cssClass2",

        "label" : "Field 2",

        "name" : "Field2",

        "required" : true,

        "type" : "text"

      },

      { "css" : "cssClass2",

        "label" : "Checkbox Field",

        "name" : "CheckField",

        "required" : false,

        "type" : "checkbox"

      },

      { "css" : "cssClass2",

        "label" : "Email Address",

        "name" : "Email",

        "required" : true,

        "type" : "email"

      },

      { "css" : "cssClass2",

        "label" : "Password",

        "name" : "Password",

        "required" : true,

        "type" : "password"

      }

    ] }

Obviously, the idea is to have this come from some kind of service, but hopefully this gives you an idea of how this might work. Kendo Template and Container Next we’ll create a simple container with a UL element, which we’ll bind to the “fields” property of the JSON object above.  

<!-- Container element for validator -->

<div id="example">

<!-- container UL to host input fields -->

<ul data-template="fieldsTemplate" data-bind="source: fields"></ul>

<!-- button to save changes -->

<button id="save" type="button">Save</button>

</div>

<!-- Kendo Template binds properties from model to input fields -->

<script id="fieldsTemplate" type="text/x-kendo-template">

<li>

<label data-bind="attr: { for: name}, text: label"></label>

<input data-bind="attr: { type: type, name: name, class: css}" # if (get("required")) {# required #} # />

</li>

</script>

The Kendo Template is where all the magic happens. By using the “data-bind” attribute, we can map the various properties from the object, as well as use inline JavaScript to check for the “required” parameter, which we’ll use for validation. Extending the kendo.observable Object If we declaring our observable object directly (as is done in all of the Kendo UI Documentation examples) we would basically be done. However, because the object properties will not be known until runtime, we need an extra step. So we’ll simulate the call to our AJAX service to get the JSON, and upon successful response, create an observable object using the returned JSON object, and use that to bind to the template. The following code accomplishes this:

// retrieve the model from an API call

$.ajax({

url: "json.txt",

type: "GET",

dataType: "json",

success: function (model) {

// convert the JSON to observable object

var viewModel = kendo.observable(model);

// bind the model to the container

kendo.bind($("#example"), viewModel);

}

});

    Putting it All Together All that’s left is to attach the kendo validator, and hook into the “click” event of the save button to run it and we are good to go! Because of the attributes, attempting to submit an invalid form will alert the user, including support for input types like “email”.  Once the form is valid you can do what you need to with the form, including submitting or posting the values to another endpoint.  Here is the complete html file:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>Kendo UI Sample: Creating a Form Using a Template and External JSON</title>

    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>

    <script type="text/javascript" src="http://cdn.kendostatic.com/2013.2.716/js/kendo.all.min.js"></script>

    <style type="text/css">

     label { width: 125px; display: block; float: left;}

     li { padding: 5px;}

    </style>

</head>

<body>

    <h1>Kendo UI Sample: Creating a Form Using a Template and External JSON</h1>

    <!-- Container element for validator -->

    <div id="example">

        <!-- container UL to host input fields -->

        <ul data-template="fieldsTemplate" data-bind="source: fields"></ul>

        <!-- button to save changes -->

        <button id="save" type="button">Save</button>

    </div>

    <!-- Kendo Template binds properties from model to input fields -->

    <script id="fieldsTemplate" type="text/x-kendo-template">

        <li>

            <label data-bind="attr: { for: name}, text: label"></label>

            <input data-bind="attr: { type: type, name: name, class: css}" # if (get("required")) {# required #} # />

        </li>

    </script>

    <script type="text/javascript">

        // retrieve the model from an API call

        $.ajax({

            url: "json.txt",

            type: "GET",

            dataType: "json",

            success: function (model) {

                // convert the JSON to observable object

                var viewModel = kendo.observable(model);

                // bind the model to the container

                kendo.bind($("#example"), viewModel);

            }

        });

        // prepare the validator

        var validator = $("#example").kendoValidator().data("kendoValidator");

        // Validate the input when the Save button is clicked

        $("#save").on("click", function () {

            // If the form is valid, the Validator will return true

            if (validator.validate()) {

                // iterate through the values

                var values = "";

                $("#example input").each(function () {

                    values += $(this).attr("name") + ": " + $(this).val() + "\n";

                });

                alert(values);

            }

        });

    </script>

</body>

</html>

I hope you find this helpful! If this inspires any ideas, sound off in the comments!  

The following two tabs change content below.

selaromdotnet

Senior Developer at iD Tech
Josh loves all things Microsoft and Windows, and develops solutions for Web, Desktop and Mobile using the .NET Framework, Azure, UWP and everything else in the Microsoft Stack. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom. His other passion is music, and in his spare time Josh spins and produces electronic music under the name DJ SelArom.