Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Typescript

Kendo Typescript: DropDownList Control with MVVM

4.70/5 (5 votes)
23 Jan 2014CPOL6 min read 38.1K   508  
Introductory article to explain how to configure a simple kendo dropdown list, that reads from a WEB API service, using kendo MVVM and typescript

Introduction

UI demo programTypescript is a new and promising open source language from Microsoft(r). In fact Typescript[1] [2] offers the possibility to get a JavaScript code more easy to organize and more simple to be debugged. The compile in fact, returned pure JavaScript code compatible with ECMA 3 or ECMA 5 specifications.

This article gives an example of use of it with the WEB drop-down list from Telerik(r) Kendo[3]. The example made use of typescript to programming the Kendo drop-down list[4], and it uses kendo MVVM[5] to operate the control and a WEB API to get the information from a remote source.

Prerequisites

To use the code, you need the following:

  • Visual Studio 2012 or 2013 (it was tested in VS 2012)
  • Typescript Microsoft plug-in for Visual Studio (version 0.9.5)
  • Recommended Microsoft Web Essential for Visual studio 2012.

You can find the plug-in at Official Typescript Web Download.

And the Web Essential 2012 at Download Web Essential.

Note: Be careful with Web Essential, the actual version creates a spurious log in the output windows of VS, when you compile the application. The logs lines are inoffensive, but look like something as bad. Maybe in the next version, this issue will be repaired.

Now you can download the solution, unzip and open in Visual Studio.

The application runs in IIS Express, then you need to open the code (Common.ts file) and edit the port used by IIS Express to run the service. To avoid problems with cross domain issues, the web API and the combo-box program demonstration were put in the same project. The following code shows the line to modify:

JavaScript
module Common {
    export function GetProgramVersionDataSource(kendo) {
        var url = "http://localhost:57031/api/Values"; //< -- Change this to your specific port.
        var programVersionDataSource = new kendo.data.DataSource({
            transport: {
                read: {
                    url: url
                },
                dataType: "json",
                type: "GET",
            }
        }
            );

        return programVersionDataSource;
    }
} 

Using the Code

The example uses the community Kendo web from Telerik(r) (An abbreviate version to save file space). A complete library can be found on [6].

The code shows a drop-down list that reads information from a web API and shows it in the combo. It also shows a small label with the position of the month in the year. This example shows how to drive a Kendo drop down list with MVVC and connected to a web API service.

The Web API

Here is not so much, the project is a normal WEB API project with all by default. The only modification was at the value controller to get fixed data as is shown in the following code:

JavaScript
namespace KendoTypeScript.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public ComboBoxItemOutput[] Get()
        {
            var output = new ComboBoxItemOutput[12];

            var o1 = new ComboBoxItemOutput { Description = "January", Id = 1 };
            output[0] = o1;
            var o2 = new ComboBoxItemOutput { Description = "February", Id = 2 };
            output[1] = o2;
            var o3 = new ComboBoxItemOutput { Description = "March", Id = 3 };
            output[2] = o3;
            var o4 = new ComboBoxItemOutput { Description = "April", Id = 4 };
            output[3] = o4;
            var o5 = new ComboBoxItemOutput { Description = "May", Id = 5 };
            output[4] = o5;
            var o6 = new ComboBoxItemOutput { Description = "June", Id = 6 };
            output[5] = o6;
            var o7 = new ComboBoxItemOutput { Description = "July", Id = 7 };
            output[6] = o7;
            var o8 = new ComboBoxItemOutput { Description = "August", Id = 8 };
            output[7] = o8;
            var o9 = new ComboBoxItemOutput { Description = "September", Id = 9 };
            output[8] = o9;
            var o10 = new ComboBoxItemOutput { Description = "October", Id = 10 };
            output[9] = o10;
            var o11 = new ComboBoxItemOutput { Description = "November", Id = 11 };
            output[10] = o11;
            var o12 = new ComboBoxItemOutput { Description = "December", Id = 12 };
            output[11] = o12;
            return output;
        }

The HTML Test Page

JavaScript
<div id="example" class="k-content" >
      <div class="k-block" style="text-align: center;
      height: 200px; width:400px; margin:0 auto">
          <div class="k-header k-shadow">
              <b>ALL MONTHS DEMO</b>
          </div>

          <input id="months" style="width: 250px"
              data-role="dropdownlist"
              data-value-primitive="true"
              data-bind="value: SelectedValue, source:dropdownItems" />

          <p></p>
          <div style="text-align: center">
              The selected Month, is the
          <span data-bind="text: SelectedValue"></span>
              month in the calendar
          </div>
      </div>
  </div>

To bind the control with Kendo MVVM they are used attributes, in this case the following attributes were used to link the information:

data-role="dropdownlist" Report that the data are used in a drop-down

data-bind="value: SelectedValue, source: dropdownItems"

This describes what variables are used in the binding. The source indicates the data source for the item list in Drop Down and value bind with the selected value in the drop-down list.

data-value-primitive="true"

This attribute instructs Kendo, to gets only the value selected. If you put here false, value return the item selected, that is the object bound to the item.

(in this example valuePrimitive = false returned {ID: value, Description: description}

The span tag also is bound to SelectedValue, if the MVVM model works, each time that changes the drop-down list, change the text value in the span tag. We also need to define, what fields of the returned service, go with value and text in the drop-down box. You can define them as attributes and also, when you define the drop-down as Kendo in JavaScript.

For demonstrative purposes, we create three ts files, in order to explain each part in detail. The first ts module creates a class that represents our drop-down list:

The DropDownDemo Class

JavaScript
///<reference  path="kendo.web.d.ts" />
///<reference path="jquery.d.ts"    />

module MyModule {

    export class DropDownDemo {

        public viewmodel: DropDownViewModel.viewModel; 

        constructor() {

            this.viewmodel = new DropDownViewModel.viewModel();
            var monthComboBox = $("#months").kendoDropDownList({
              dataTextField: "Description",
                dataValueField: "Id",
            });

            this.viewmodel.SelectedValue = 12;
            kendo.bind($("#example"), this.viewmodel);
       }
    }
}

If you see the typescript syntax resemble a normal C# program structure. module works as namespace, and we can create classes inside then. For these classes to be accessible outside the module, you must declare them as export.

As a normal class, you should create a constructor to initialize it. If you see the constructor, it creates a view model class first (it is in other ts file), then declare the input tag #months as kendoDropDownList, and assign to the dataTextField to Description and as dataValueField to Id. These values will be read from the web API.

Important: Remember that JavaScript as C# is case sensitive. dataTextField is not the same as datatextfield. If you put other case, then you don't get the result that you want.

After initialization of DropDownList, we assigned a predefined value to the view-model SelectedValue, because we want to open the drop-down list with the December Text.

And the last line makes the magic thing to bind the Drop-down and the span tag with our view model.

Observe that the bind is realized over the <div id="example"> tag, that contains the two tags that we want to bind with the view model.

The View Model

JavaScript
///<reference  path="kendo.web.d.ts" />
///<reference path="jquery.d.ts"    />

module DropDownViewModel {

    export class viewModel extends kendo.Observable {

        public dropdownItems: kendo.data.DataSource;
        public SelectedValue: number;

        constructor() {
            super();
            this.dropdownItems = Common.GetProgramVersionDataSource(kendo);
            this.SelectedValue = null;
        }
    }
}

This module defines a class as our view model. The class inherited from kendo.Observable (Typescript use extends reserved work to do this). In the class, we define drop-down list as kendo.data.DataSource and SelectedValue as number.

The constructor simply initializes the two values. (Observe that you need to call in constructor the inherited constructor, that is realized by the super() line).

Because we want to get the data from a Web API service, we need to configure the data-source to do so. For clarity, we put this data-source in other module.

The Data Source File

JavaScript
///<reference  path="kendo.web.d.ts" />
///<reference path="jquery.d.ts"    />

module Common {

    export function GetProgramVersionDataSource(kendo) {

        // Change this to your specific port.
        var url = "http://localhost:57031/api/Values"; 
        var programVersionDataSource = new kendo.data.DataSource({

            transport: {
                read: {
                    url: url
                },
                dataType: "json",
                type: "GET",
            }
        }
            );

        return programVersionDataSource;
    }
}

The call to a json service is as you see, very simple. Here we define the URL and the type of data, and the verb to use.

You can put this in the same file as your view-model.

Observe that here we declare a module, but not a class. The function is exported not associated with any class. You don't need to initialize it. The behavior is similar to a static class in C#.

The last line:

All this looks well, but does not work if you don't create a instance of DropDownTest. You can do this in any of the files or directly in the HTML page. In our example, we put this in our DropDownTest class:

JavaScript
$(document).ready(function () {
    var vm = new MyModule.DropDownDemo();
});

You should of course put a reference to the generated js file in your code.

In our example, we configure the typescript project to generate only one js file, also we configure it to copy the generate file to the demo.html project. To do this, we need to do the following procedure:

  • Upload the tyepscript project
  • Edit the csproj file
  • Enter the following tag in debug and release configuration of the csproj file:

<TypeScriptOutFile>Your output.js</TypeScriptOutFile>
See the following code for more details:

  • Save and close the .csproj
  • Reload the typescript project
  • Now typescript creates a single file for your project:
XML
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
   <TypeScriptTarget>ES5</TypeScriptTarget>
   <TypeScriptGeneratesDeclarations>true</TypeScriptGeneratesDeclarations>
   <TypeScriptRemoveComments>false</TypeScriptRemoveComments>
   <TypeScriptSourceMap>true</TypeScriptSourceMap>
   <TypeScriptModuleKind>AMD</TypeScriptModuleKind>
   <TypeScriptOutFile>KendoWeb.js</TypeScriptOutFile>
 </PropertyGroup>

 <PropertyGroup Condition="'$(Configuration)' == 'Release'">
   <TypeScriptTarget>ES5</TypeScriptTarget>
   <TypeScriptRemoveComments>true</TypeScriptRemoveComments>
   <TypeScriptSourceMap>false</TypeScriptSourceMap>
   <TypeScriptModuleKind>AMD</TypeScriptModuleKind>
   <TypeScriptOutFile>KendoWeb.js</TypeScriptOutFile>
 </PropertyGroup>
 <ItemGroup>

To create an automatic copy of the js file to your project, go to project -> properties and open Build Event Tag. In post - build event, copy the following code:

xcopy "$(ProjectDir)KendoWeb.js"  "$(SolutionDir)KendoTypeScript\Scripts\"    /y

Substitute the name of the js file and the target address according your project.

NOTE: This form of work, presents the problem that you cannot debug directly the code in typescript, you must debug using the outputted JavaScript file. If you are comfortable with JavaScript, that is not a problem. If you want to debug directly in typescript, you should copy the ts files in your project as well as the map files generated. To see the generate files for typescript, explore the project using Show All Files option in Visual Studio.

Points of Interest

This is a simple example to join the emerging typescript with the classic JavaScript and with two modern frameworks often used in web client development: Kendo web and wep.API.

History

  • First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)