Kendo UI Core and DropDownListFor

Kendo UI Core supports data attribute initialization of its widgets. This initialization approach is largely created for it’s MVVM capabilities, but also can be used for server-side approaches too, which in turn can be used with ASP.NET MVC HTML helpers. The setup may be a little different than you are used to.

Please note: Although Telerik has MVC wrappers already created and ready for you to develop with, these come with the licensed version of the product and are not available through the Kendo UI Core license.

To begin, let’s look at how we’d setup the dropdownlist as an HTML widget without and use of the server.

<select id="reasonID" data-role="dropdownlist" data-option-label="-Select Reason-" data-value="">
  <option selected="selected" value="">-Select Reason-
  <option value="1">Entered in Error
  <option value="2">Removed
</select>

In our example, a select element with a pre-defined list of options is wrapped with the kendo dropdownlist widget. It’s initialized via the data-role attribute, indicating it’s a dropdownlist widget. Next, it defines options that the widget supports. Most of the attributes on the widget that you would configure through the JavaScript API can be defined here, but the syntax differs sometimes (for instance, the optionLabel property you would use in JS initialization is data-option-label in data attribute initialization). If you run into an issue, I was able to find what I needed online so far.

Telerik has some documentation on data attribute initialization here.

The dropdownlist widget can use a textbox as the source, and can also wire data up using JSON via local JavaScript API of via AJAX if you like. I’ve stuck with a select because I’m using the MVC DropDownListFor widget, and to get this widget to render the correct content that I needed, I had to use the following configuration:

@Html.DropDownListFor(
      i => i.ReasonTypeID,      
      Model.ReasonTypes, 
      new
      {
           data_role="dropdownlist", 
           data_option_label="-Select Reason-", 
           data_value=(Model.Receiving.ShrinkTransactionTypeID.HasValue ? Model.Receiving.ShrinkTransactionTypeID.Value.ToString() : ""), 
           style="width:100%;" })

Most of this is standard. The third parameter of DropDownListFor provides HTML attributes to the rendered select option. Here we define the role data attribute used for initialization. The next attribute defines the option label, and the data_value attribute defines the selected value, which is interesting. We already define what’s selected via the lambda expression pointing to our model. However, that’s used to render the selected attribute. What I found is that to cover all selection scenarios (including the default “Select Something” item) is to add the value attribute too, which the widget uses to perform the selection. The code above manually checks for null and converts to an empty string if no value present.

In case you didn’t notice, note how the HTML attribute use data_role, particularly the underscore. The convention that MVC uses is underscore (supported by the language), which is converted to a dash during the rendering process.

Single Page Binding with Kendo UI ListView

If you’ve looked at the demos on the Kendo UI site, you’ll notice the ListView and DataSource combination are a pretty capable combination. The ListView gives you full control over the user interface, while supporting common functionality like paging, sorting, and more. The DataSource provides read and update functionality to a local or remote data source, even giving you full control over these processes (for instance, you can use JQuery directly for AJAX communication). The pager natively pages through the contents of the listview automatically for you. The three widgets offer great functionality for the developer.

While the combination works well, I personally ran into a snag using the Kendo UI core version (open source). With the pager component natively paging the content, the data source required a complete dataset downloaded from the server. If your ListView will be presenting 30 records, all 30 must be retrieved from the server; if 3,000, all 3,000 must be retrieved from the server. Now natively the data source control supports server paging, most examples illustrated using the Telerik MVC wrappers for handling the server-side processing, and as such, I wasn’t sure whether it was supported. If it works, I would recommend using the kendo pager as it offers the smoothest navigation; but if not, this workaround worked just as well, with some added effort. In order to get around this, I ended up using the Bootstrap Paginator plugin.

The bootstrap paginator allows you control over the number of pages to show, and provide delegation on user interaction, with the example below.

$('#pager').bootstrapPaginator({
            currentPage: 1,
            totalPages: 10,
            onPageClicked: function(e, evt, type, page){
                //Reload the listview - listview uses custom AJAX option
                #("#listview").data("kendoListView").dataSource.read();
            }
        });

The currentPage option sets the current page in the list, within the range of total pages. It’s possible to preload these from an MVC model, especially when you factor in postbacks (the pager needs reinitialized on postbacks), as in the following:

{
   currentPage: @Model.CurrentPage,
   totalPages: @Model.TotalPages
}

When the user clicks on a page, it fires the onPageClicked callback handler, which subsequently triggers an AJAX action back to the server. We’ll need the new page index from the event handler; we can get it directly from the plugin, or store the current index in a hidden variable. Either way, this piece of information needs passed back to the server.
If you looked in the example online, it has a custom AJAX action as shown below.

$("#listview").kendoListView({
    dataSource: {
       transport: {
           read: function(o) {
              var index = // Get index from hidden variable or wherever

              $.ajax({
                  type: "post",
                  url: "@Url.Action("Action", "Controller"),
                  data: { index: index, otherParams: "OTHER PARAMS" },
                  success: function(d) { o.success(d); },
                  error: function(d) { o.error(d); }
              }); 
              
           }
       }
    }
});

Here we trigger the postback to the server, and pass in the list of form data values, as well as the currently selected page index. Since the items per page is hard-coded in this scenario (at say 10, for example), we can quickly calculate the starting index and ending index of the current page.

There are many ways to implement this solution; this is one quick, simple way to introduce paging with large lists of data, where each page is dynamically loaded at paging time.

Kendo MaskedTextBox Custom Rules

The Kendo UI MaskedTextBox plugin is great for limiting the input entered into a textbox. For instance, to validate a phone number, you could do the following:

$("#tb").kendoMaskedTextBox({
    mask: "(000) 000-0000"
});

The value zero ensures only numbers are entered. The masked text box also has these placeholders as well:

9 – 0 to 9 plus space
# – 0 to 9, space, plus, minus
L – a-z, A-Z
? – a-z, A-Z, space
& – any character
C – any character, space
A – letters, digits
a – letters, digits, space
. – Decimal
, – Thousands placeholder
$ – Currency

Outside of these rules, it’s possible to add your own, such as the following:

$("#tb").kendoMaskedTextBox({
    mask: "~A-00-000",
    rules: {
       "~": /[3-9]/,
       "*": /[ASDF]/
    }
});

The “~” and the “*” are the mask placeholder, whereas the /[3-9]/ and /[ASDF]/ define the range of acceptable values. This way, you can create a range to be whatever you desire.

PhoneGap, Kendo, and MVVM by Example

I’ve been looking into developing PhoneGap applications. PhoneGap is an excellent tool for getting an application into the app store for iOS, Android, Windows 8/Phone 8, and many other platforms. Since it’s HTML 5 and JavaScript-Based, running on the web browser of the target platform, PhoneGap requires only a single codebase (however, there can be some quirks with the various features, as described in the PhoneGap documentation). Since it’s HTML; you can virtually have whatever design you would like.

However, to go with a minimalist design would not be very user friendly. It’s often best to use a framework like JQuery Mobile, Sensa Touch, or others to handle the look and feel for you. These frameworks provide you with a header and footer similar to apps you would see in the application store, and provide enhanced UI input and layout elements. This is why I chose a framework to lay out the markup for me, and this is also why I chose to use Kendo UI, from Telerik. Kendo UI provides a mobile application framework that supplies a templated UI to the user that completely resembles a mobile application. It also provides a series of input widgets perfect for capturing user input that’s much more appealing ot the user than the standard HTML controlset. It also provides an MVVM framework, and a Single Page Application framework for managing your application’s interaction between the view and model. Note that Kendo comes in three different frameworks: kendo UI web for web controls, Kendo UI Mobile for mobile web applications and PhoneGap, and Kendo UI DataViz, or data visualization components (charting, etc.).

The sample application is the shell we are going to plant into a phonegap application (discussed in a later post). To start, we are going to build is an application containing two views, using data that’s bound to the view via the MVVM framework. In all of my searching on the internet, I had trouble finding a simple example incorporating these exact features, so I hope the following example is a benefit to you. I’ll also describe the Kendo UI framework as I go. To begin, we need to create an HTML page and add some core script definitions to it.

<link href="../../css/kendo.common.min.css" rel="stylesheet" />
<link href="../../css/kendo.bootstrap.min.css" rel="stylesheet" />
<link href="../../css/kendo.mobile.all.min.css" rel="stylesheet" />

<script src="../../js/jquery.js"></script>
<script src="../../js/jquery.migrate.min.js"></script>
<script src="../../js/kendo.all.min.js"></script>

I’ve included the Common, Bootstrap (as in bootstrap theme, not Twitter Bootstrap), and the mobile CSS files. All of these provided allows you to use the Kendo UI web and mobile controls. Additionally, I’ve included JQuery (a requirement of Kendo), which is the latest. The migrate JS file is an add-on that ensures backward compatibility between older versions of JQuery (as of the time of writing, this example used JQuery 1.9.1, but Kendo requires 1.8.2). Additionally, the kendo all JS file contains all of the scripts for the web, mobile, and dataviz frameworks.

Now that we have our references setup, let’s flesh out the UI. To begin, let’s setup the views and the layout, as the following:

<div id="newview" data-role="view" data-title="New Contact" 
  data-layout="viewlayout" data-model="newViewModel">
	.
	.
</div>

<div id="existingview" data-role="view" data-title="Existing Contacts" 
  data-layout="viewlayout" data-model="existingViewModel">
	.
	.
</div>

<div data-role="layout" data-id="viewlayout">
	<header data-role="header">
		<div data-role="navbar">
			<a class="nav-button" data-align="left" data-role="backbutton">Back</a>
			<span data-role="view-title"></span>
		</div>
	</header>

	<footer data-role="footer">

		<div id="footertabs" data-role="tabstrip">
			<a href="#newview" data-icon="add">New</a>
			<a href="#existingview" data-icon="contacts">Contacts</a>
		</div>

	</footer>
</div>

To begin, we have two views, a new view and an existing view. A view is the container for what the user sees, defined by a data-role value of “view”; the user only sees one view at a time, starting with the new view. A view has a header and footer. The header contains the header title bar, plus any buttons used for navigation. The footer bar contains additional footer options, which is a set of tabs to navigate between the two views. Notice that the header and footer are defined an element with a data-role attribute value of “layout”. Layouts are a convenient way to reuse the header and footer across all views. This layout above is used for the new and existing view. Now we have the views defined, and the navigation between views using the tabstrip component. But if you viewed this page in the browser, it wouldn’t be very useful. For instance, the tabscript would not work as it currently stands. We need to enable a JavaScript widget that Kendo uses to provide the tabbing feature. Kendo uses a JQuery UI widget-like capability for enabling these behaviors. For instance, to enable the tabstrip programmatically, one would do:

$("#footertabs").kendoMobileTabStrip({ /* options */ });

However, Kendo made this even easier through it’s application class; by adding the following line, the entire view is wired up to it’s related JavaScript widget, all linked together through the data-role attribute, and related “data-” configurations.

var kendoApp = new kendo.mobile.Application(document.body, {
	loading: "Loading..."
});

Now that our views are wired up and our components are linked to their JavaScript counterpart, the next task needing performed is to define the MVVM data models. Before we fully get into that, let’s look again at the complete view.

<div id="newview" data-role="view" data-title="New Contact" data-layout="viewlayout" data-model="newViewModel">
	<form action="" method="post">
		<ul id="newformlist" data-role="listview">
			<li>
				<label>Name:</label>
				<input type="text" id="Name" data-bind="value:newName" />
			</li>
			<li>
				<label>Suffix:</label>
				<input type="text" id="Suffix" name="Suffix" data-bind="value:newSuffix" />
			</li>
			<li>
				<label>Email:</label>
				<input type="email" id="Email" name="Email" data-bind="value:newEmail" />
			</li>
			<li>
				<label>Phone:</label>
				<input type="tel" id="Phone" name="Phone" data-bind="value:newPhone" />
			</li>
		</ul>
	</form>
</div>

<div id="existingview" data-role="view" data-title="Existing Contacts" data-layout="viewlayout" data-model="existingViewModel">
	<ul id="existinglist" data-role="listview" data-bind="source:contacts" data-template="contacttemplate">
	</ul>
</div>

Here we ahve our two views. The first container a form, and the last contains a list. Both use the listview component, a mobile-specific component that binds data similar to a grid, or can be used as shown above for representing a form. Both views define certain attributes; they define a title that will appear in the layout’s title bar. The views also define the layout to use (as we saw above) and the data model to bind to. Within eaach view is an HTML element that defines what to bind to. For instance, in our form, each textbox is bound, using the data-bind attribute, to some specified value (newName, newEmail, etc). The “value:” prefix specifies the type of bindings to use. There are quite a few bindings available; for know, now that the value binding links the value from the view model to the “value” attribute of the element. In future posts, I’ll talk about some of the other attributes available. These bindings link the model (newViewModel) to an attribute of that model. This makes it very easy to bind the data in a two-way fashion from some backend model to the user interface, and vice versa.

Our listview that displays a list of contacts defines a source, or the array of data to bind to, and specifies a template to use. Templates are script element defining the UI to define for the item of the list. The following is the attached template the listview uses to show the name, phone, and email for each contact. Note that templates use a #= # or #: # convention for binding, and can even accept javascript statements like the “if” statement below.

<script type="text/x-kendo-template" id="contacttemplate">
	<h3>
		#= Name#
		# if (Suffix != null && Suffix.length > 0) { #
			#= Suffix #
		# } #
	</h3>
	<div>
		#= Phone #
	</div>
	<div>
		#= Email #
	</div>
</script>

To wire up these views, we need some data. This is where the view models come into play. Kendo defines a view model using the observable method; note that this approach is different than what other MVVM frameworks use (like Knockout JS for one). Kendo transforms the basic model definition into an object with observable properties to provide the two-way binding.

var newViewModel = kendo.observable({
	newName: "ABC",
	
	newSuffix: "",
	
	newPhone: "",
	
	newEmail: ""
});

var existingViewModel = kendo.observable({
	contactsLoaded: true,
	
	contacts: [
		{ Name: "Ted Person", Suffix: "", Email: "ted.person@fake.com", Phone: "555-555-5555" },
		{ Name: "Amu Person", Suffix: null, Email: "amy.person@fake.com", Phone: "555-555-5555" },
		{ Name: "Bob Person", Suffix: "Jr", Email: "bob.person@fake.com", Phone: "555-555-5555" }
	]
});

And voila, this is all that you need to define multiple views, binding them to an MVVM model. I’ve created a JS fiddle with the scripts; it’s not fully working correctly, which is something I have to contact Telerik about. But you can get the contents and scripts here (which work great locally), or the full example here.

Working with CheckBoxList

I know the content of this post is outdated for most users, as most users have moved on to something other than ASP.NET Web Forms. But for those of you still using web forms, and even for those using MVC, I have some code I’m about to remove (as the requirements changed), and as such, want to post it in case it helps someone else.

There are times when a series of options are presented in a CheckBoxList, such as a list of rows. For this, typically what’s used is the CheckBoxList control, which renders a table. In each cell of the table is a checkbox defined as <input type=”checkbox” />. Each of these checkboxes represented a role; however, to add to the speciality of the situation, the first item displays an “All” item. This “All” item represents all of the items in the list, but does not check the other items. Instead, it’s a manually inserted item with no entry from the database, nothing from the underlying Roles table. To start, here is the CheckBoxList control:

<asp:CheckBoxList ID="RolesList" runat="server" 
   DataTextField="RoleName" DataValueField="RoleKey"
   RepeatLayout="Table" RepeatColumns="3" 
   RepeatDirection="Horizontal" />

To show the all item in the list, the following code was used. Noticed the CSS class used.

Dim item As New ListItem("All", "")
item.Attributes("class") = "AllItem"

In script, we grab all of the inner checkboxes, and do it in a way we don’t have to understand the underlying markup (as server controls hide the underlying client markup in this case). The :checkbox pseudo selector grabs all of the checkboxes generically as shown below:

var roles = $("#RolesList").find(":checkbox");

With this list, we can attach to the clicking of all the items. The first item of the list is the “All” item (note that the trick I used to identify this special item was to add an AllItem class definition). If the “All” item was checked, the handler removed checkboxes from all of the other checkboxes. Otherwise, when checking another item that’s not the “All” item, the handler removes the check from the first item. How it was done is shown below:

roles.click(function () {
	var allItem = $(this).parent().hasClass("AllItem");

	if (allItem) {
		if (this.checked == true) {
			roles.not(":first").attr("checked", false);
		}
	}
	else {
		roles.eq(0).attr("checked", false);
	}
});

To begin, we check if the current checkbox has the AllItem; the CheckBoxList control attaches the AllItem class to the parent SPAN element above the INPUT element, which is why the parent() method is used. To set the checked on the first item, I used the .eq(0) method, or finding the first item in the list of roles, as checked (which happens to be our “All” item). Otherwise, the not() method is used to remove all but the All checkbox and clear those check marks.

And voila, we have list with a special “All” item as the first designated item.

Using JQuery FullCalendar with ASP.NET MVC and Entity Framework

I had a need to use a calendar component in my application. Calendars are hard to come by, that also act as a scheduling component. In comes JQuery FullCalendar, a plugin that renders a calendar with event components.

To set this up

1. Create an Entity Framework model with all of the AdventureWorks entities.  Choose whatever template you like. Leave the context name as the default “AdventureWorksEntities”.

2. Create a new MVC project. Add a new controller named OrderHistoryController. The OrderHistoryController that I used is defined as the following:

public class OrderHistoryController : Controller
{
//
// GET: /OrderHistory/
public ActionResult Index()
{
return View();
}

[HttpPost]
public ActionResult List(long start, long end)
{
var epoch = new DateTime(1970, 1, 1);
var startDate = epoch.AddMilliseconds(start);
var endDate = epoch.AddMilliseconds(end);

var ctx = new AdventureWorksEntities();
var data = ctx.SalesOrderHeaders
.Where(i => startDate <= i.OrderDate && i.OrderDate <= endDate)
.GroupBy(i => i.OrderDate)
.Select(i => new { OrderDate = i.Key, Sales = i.FirstOrDefault()}).Take(20).ToList();

return Json(data.Select(i => new
{
title = (i.Sales.Customer != null) ? i.Sales.Customer.AccountNumber : “Untitled”,
start = i.OrderDate.ToShortDateString(),
allDay = true
}));
}

}

The Index action serves up the view.  Once the view is loaded, an AJAX request is made back to the server, looking for any orders.  Using LINQ, we load up some of those records.  I used a GroupBy statement so that I could get one record back per date for a given month, as a way to test with a single record per day.

JSON is the preferred mechanism to return to the client.  We’ll need to massage the data a little bit in order to work with the full calendar.   For instance, we’ll have to convert the date appropriately.  For simplicity, I used ToShortDateString to get the date and parse it in JavaScript.  However, it would have been more appropriate to convert the date to Epoch time (time since 1/1/197o).

3.  Download JQuery FullCalendar from the following URL: http://arshaw.com/fullcalendar/download/.  Copy the JS and CSS files to your project, in the Content and Scripts folder (or whatever folder structure you are using).  The files includes are:

  • fullcalendar.css – the core CSS file
  • fullcalendar.print.css – the CSS stylesheet for printing a calendar
  • fullcalendar.js – the core JS file
  • fullcalendar.min.js – the minified JS file
  • gcal.js – Google calendar integration

4.  Add scripts to your page

Rather than adding all the scripts to every page, I added the scripts to the OrderHistory view.  To do this, I started by creating a bundle.  Open up Bundle.config and add the following:

bundles.Add(new ScriptBundle(“~/bundles/calendar”).Include(

#if DEBUG

“~/Scripts/fullcalendar.js”

#else

“~/Scripts/fullcalendar.min.js”

#endif

));bundles.Add(new StyleBundle(“~/Content/calendar”).Include(

“~/Content/fullcalendar.css”,

“~/Content/fullcalendar.print.css”

));

We use these bundles within the view. To setup the calendar, all that we need to do is add a DIV to a page with an ID, like <div id=”container”></div>. The FullCalendar plugin simply attaches to

$(“#calendar”).fullCalendar({
    header: {
        left: ‘prev,next today’,
        center: ‘title’,
        right: ‘month,agendaWeek,agendaDay’
    },
    editable: true,
    eventClick: function(i, evt, view) {
               
    },
    events: function (start, end, callback) {
        $.ajax({
            type: “post”,
            url: ‘@Url.Action(“List”, “OrderHistory”)?start=’ + start.getTime().toString() + “&end=” + end.getTime().toString(),
            success: function (d) {
                var list = [];
                for (var i = 0, len = d.length; i < len; i++) {
                    var item = d[i];
                    item.start = new Date(item.start);

                    list.push(item);
                }

                callback(list);
            },
            error: function (e) {
                debugger;
            }
        });
    }

});

The plugin supports a variety of members defined in the documentation that can be specified at initialization time. The key is the events property, which defines the source of the events. The source can be a static list, a pointer to a page or web service, or even a function callback. The latter option gives you the most flexibility, and I’ve demonstrated it’s usage in this example. The callback gets a start and end parameter. These parameters are dates, converted to epoch time (in milliseconds) as they are sent to the server. JQuery is used to make the call to the server, and as the results come back, the process does some massaging first. For instance, a date is coming back to the client in string form, and converts the date back to a date form.

Once our final list is complete, and to load them into the calendar, they are passed to the callback. The plugin handles all of the loading of data into the calendar. Remember from the MVC controller, it returned a title, start (date), and an allDay indicator. Using this data is what the FullCalendar plugin uses as the data source. More parameters

Building JQuery Widgets Part 2

In this article, we’re going to look at some of the finer aspects of the plugin we last build a little bit ago.  Let’s start by looking again at the _init method.  As I mentioned previously, this method runs when the plugin is initialized, after the _create method runs (if there is one).  On init, we have this definition.

_init: function() {

this.options = $.extend({

title: “Interactive Help”,

buttonText: “OK”,

alertIfHidden: true,

beforeShowCallback: null,

afterShowCallback: null,

nextCallback: null,

startingCallback: null,

finishCallback: null

}, this.options);    this._elements = [];

this._currentIndex = 0;

this._total = 0;

this._buildUI();

},

Notice the use of the $.extend method; this method is very handy for establishing default values.  The method takes the values passed into the first parameter, and passes it to the second object, only if a value doesn’t already exist.  This is a great way to ensure a field exists, and helps you from having to write a lot of code that checks for a property’s existence.  What I mean by that is if you didn’t use the extend method, if your plugin tries to use this.options.startingCallback, when startingCallback was never supplied in the options, then an startingCallback is undefined an an exception is the result.  Our implementation of extend above ensures a title, buttonText, etc. field exists on the options object, so we don’t have to do that type check.

Notice that we have some options with a “callback” extension; these are the equivalent to an event in .NET or some other object-oriented language.  An event in an object-oriented language is defined explicitly, allowing the consumer of that event to attach to it and receive notification when the event occurs.  Widgets have the same functionality, in a different way.  We can attach to the event handler by supplying a JavaScript function, and then invoke that function at the appropriate time At various points in the plugin, we’ll invoke the callback by doing the following:

if (!!this.options.nextCallback)

this.options.nextCallback(this, { index: this._currentIndex, total: this._total });

We invoke the method, if it exists, and pass in any additional parameters.  Another important point to note is that you as a developer can interact with the consumer through these callbacks.  For instance, take a look at the code below.

var args = $.extend({
oldElement: el,
oldLeft: (!!pos && !!pos.left) ? pos.left : null,
oldTop: (!!pos && !!pos.top) ? pos.top : null,
element: null,
selectorFunction: null,
left: null,
top: null
}, def);if (!!this.options.beforeShowCallback)
this.options.beforeShowCallback(this, args);

if (!!args.element)
{
el = args.element;

if (!el && typeof(args.selectorFunction) !== “undefined”)
el = args.selectorFunction({ element: this.element });
if (!!el) {
pos = this._getElementPosition(el);
}
}

In this example, we construct an event argument that has specific parameters.  These parameters are passed to the beforeShow event, through the beforeShowCallback (notice the use of extend to ensure certain parameters exist).  After it’s called, the widget interrogates the argument object for any changes the user may have made.  For instance, the user may have supplied an element, or even a function for selecting the element.  In this way, users can provide the widget input at the time the event has executed, something we also have the ability to do in object-oriented languages.

When creating widgets that others on your development team, or possibly the world if  you release your widget to the public, the difficulty comes with how to let them know how to use your plugin, what parameters are available for each callback, and other aspects requiring documentation.  Without good documentation, that supply the parameters being passed in at initialization time or supplied by a callback, the consumer of the widget will have difficulty using it.  While we don’t always like documentation, providing it is key to your widget’s success.  Sure, the above average developer will read the source, but the rest of your audience will be left in the dark without good direction.

Building JQuery Widgets Part 1

JQuery provides an extensive reusability system in the form of plugins and widgets.  Plugins are native to JQuery and reside as a function that can be defined either statically, or per a range of elements.  We’ll touch on JQuery plugins in a later post.  JQuery widgets, on the other hand, are  a part of the JQuery UI framework.  At a minimum, from the JQuery UI download page (http://jqueryui.com/download/), all you need to download is the core feature, the widget feature, and the mouse feature (for mouse-oriented widgets).

This now allows us to create a widget as so:

 $.widget(‘ui.HelpBox’, { /* Definition of Widget */ });

JQuery begins a widget by using the $.widget  method (added on by JQuery UI).  This is the point the widget gets defined; the definition of the widget comes in the form of a class definition, as we’ll see soon.  It may be beneficial to see how you would create a widget, to add some perspective.  Below is how we would instantiate our HelpBox widget.

$(“#SomeElement”).HelpBox({ /* options */ });

Here you can see a widget is applied to an element. A widget is linked to an element within the DOM. It is at this point we are actually instantiating our HelpBox widget, and providing the initial settings for the widget (or options).

Jumping back to our widget definition, when its created, the _create and _init methods are invoked.  In most scenarios, the _init method is sufficient.  Below is the body of the widget defined in the “Definition of Widget” section in the comment above, in addition to some other methods.

{

_init: function() { . . },   _buildUI: function() { . .},

add: function(elementSelector, descriptionHTML, name) { . . },

_finish: function() { . . },

getSize: function() { . . },

next: function() { . . },

run: function() { . . },

_show: function(def) { . . },

stop: function() { . . }

}

We are essentially building the API of the widget, much like building an object’s API using the prototype definition. Usually a JavaScript class has additional variables used to track pieces of information pertinent to the class. During the init method, this is where we will do that, as shown  below.

_init: function() {

this.options = $.extend({

title: “Interactive Help”,

buttonText: “OK”,

beforeShowCallback: null,

afterShowCallback: null,

startingCallback: null,

doneCallback: null

}, this.options);

this._elements = [];

this._currentIndex = 0;

this._total = 0;

this._buildUI();

},

During init, we add instance variables to the widget using “this.variable”, which appends a variable to the widget instance. The “this” pointer points to an instance of the widget, which also allows us to call additional method. Notice the use of the extend method? This JQuery method is pretty handy; what it does is compare the first object against the second, and anywhere a member doesn’t exist in the second object, the default value provided in the first object is added to it, and returned from the method. So you can see the first object that’s statically defined is ensuring certain options have been defined by the user. This way, they won’t cause undefined errors later on.

Let’s turn to constructing the user interface:

_buildUI: function() {

var self = this;   self._outerElement = $(“<div/>”).addClass(“HelpBoxWrapper”).css(“display”, “none”);

self._titleElement = $(“<div/>”).addClass(“HelpBoxTitle”).html(“<h3>” + this.options.title + “</h3>”);

self._bodyElement = $(“<div/>”).addClass(“HelpBoxDescription”);

self._buttonRowElement = $(“<div/>”).addClass(“HelpBoxButtons”).append(

$(“<a />”).attr(“href”, “#”).html(this.options.buttonText)

.click(function() {

self.next();

})

);

self._outerElement.append([self._titleElement.get(0), self._bodyElement.get(0), self._buttonRowElement.get(0)]);

$(“body”).append(self._outerElement);
},

At the core of each widget is an element.  This element is referred to by “this.element”, a reference to the JQuery object containing that element.  Here we are creating some DIVs and other elements, applying CSS to the elements, which will be the user interface of the widget.  The user interface has a button, which listens to the click event.  On click of the button, it invokes a next method, a method that performs an action on the widget.  We’ll look at that in the next post.  Notice how we store a reference to each element of the widget as a variable reference (self is a pointer to this, this widget).

Usages of Widgets

Using widgets is a little awkward.  What looks like the same syntax is actually not the same.  Let’s look at how we may initialize the widget again:

$("#SomeElement").HelpBox({ buttonText: "Okay", title: "Help" });

This is the point of initialization. This calls _create and _init. We provided some options, which override the defaults that we specified in the _init method (“Okay” overrides “OK” as the default button text). Now, to call a method (like the run method) using the JQuery widget, the following is the syntax.

$("#SomeElement").HelpBox("run");

We don’t actually call a method on the object; we use the widget instance to invoke the method. It’s a little awkward at first, but eventually you get used to it. To call our add method, with parameters, you simply pass in the parameters like so:

$("#SomeElement").HelpBox("add", "#MyTargetElement", "My target description");

You can see that all interaction with the widget goes through the widget, rather than the widget’s API. You can also override the options by first specifying the “options” collection, then the name of the option, and lastly provide the new value.

I hope this was an informative look at using JQuery Widgets in your applications.

Knockout with MVC Sample

I have an application where there exists the ability to request invitation to a group, similar to the process of joining a private linked in group.  One of my MVC views displays all such requests, and allows the user to process them.  The way this page works is the following: the view loads with no data.  The view begins to build the view model and bind it without any request data.  A JQuery AJAX request fetches the request data from the server, and loads the requests after-the-fact, once the AJAX request completes.  The process used an action method to stream JSON to the client, and returns the following content:

public ActionResult Invitations(string username)

{
.
.
//load data from server

return Json(new
{
Invitations = from i in requests
select new
{
i.Key,
i.GroupName,
i.UserName,
i.Note
}
});
}

On the client, we have a view defined as the following.  there is a lot of markup, but the process isn’t overly complex.  At the top, we have the template user interface defined.  Later on, we construct the view model, load it with empty data.  An AJAX request retrieves JSON data and loads the invitations into the view.  Each invitation displays the core information, along with a button that permits and acceptance or rejection of the invitation.

<div class=“P”>

<div databind=“if:hasInvitations”>
<div id=“InvitationsList” databind=“template: { name: ‘InvitationsTemplate’, data: invitationsList }”></div>
</div>

<div databind=“if:hasNoInvitations”>
Loading
</div>

<div databind=“if:emptyInvitations”>
No invitations have been submitted yet.
</div>

</div><script type=“text/html” id=“InvitationsTemplate”>

<section databind=“foreach:Invitations”>
<h3 databind=“html:UserName”></h3>

<div class=“P”>
For Group <span databind=“text:GroupName” />
</div>

<div class=“P”>
The user attached the following note:
<div databind=“html:Note”></div>
</div>

<div class=“P”>

<div>
Please approve or reject the user using the buttons below.
</div>

<div>
<form class=“InlineForm” action=‘@Url.Action(“Approve”, “Groups”)’ method=“post”>
<input type=“submit” value=“Approve” />
</form>

<form class=“InlineForm” action=‘@Url.Action(“Reject”, “Groups”)’ method=“post”>
<input type=“submit” value=“Reject” />
</form>
</div>

</div>

</section>

</script>

<script type=“text/javascript”>

function viewModel() {
var self = this;

self.invitationsList = ko.observable(null);

self.emptyInvitations = ko.computed(function () {
var i = self.invitationsList();

   return (i != null && i.Invitations.length == 0);

});

self.hasInvitations = ko.computed(function () {
var i = self.invitationsList();

    return (i != null && i.Invitations.length > 0);

});

self.hasNoInvitations = ko.computed(function () {
    return self.invitationsList() == null;
});

}

var model = new viewModel();
ko.applyBindings(model);

$.ajax({

type: “post”,
url: ‘@Url.Action(“Invitations”, “Groups”)’,
data: { UserName: ‘@ViewBag.UserName’ },
context: model,
success: function (d) {
this.invitationsList(d);
}

});

</script>

Notice the computed properties; at first, the list of invitations is null, meaning we haven’t gotten any invitations at all.  If I would have bound a null observable to the view, Knockout JS throws an exception in relation to this.  We can’t bind a null observable that isn’t prevented first with some if logic.  If we do have data, one of two view appears.  Either the view renders the invitations posted, or if an empty list, we see an empty message to inform the user the system has no invitations.

This is a piece of functionality I actually have in operation, and I hope this may be of benefit to you to see how an entire view may be implemented in Knockout.

Knockout and Binding Lists

I have been using Knockout in an MVC project where I have been binding list-oriented data in the user interface.  I’ve been trying to use a more efficient approach to loading the UI by pushing the view with no data bound from the server, then following up with a subsequent request to serve up JSON, which populates the list.  This is the technique I’m focusing on in this article.  This means that the page builds an empty document model, then populates the model on document ready.  In my page, I build an empty view model:

function viewModel() {
var self = this;

self.listData = ko.observableArray([]);
}

Initially we start with an empty list.  At this point, on initial load, it’s beneficial to show something to the user that we have no data.  In order to do this, I found adding some computed properties for determining status was helpful.  These properties also existed in the model:

self.hasLoadedListData = ko.observable(false);
self.emptyListData = ko.computed(function() { return self.listData.length > 0; });

Here we have two properties, one for determining if we bound any data to the UI at all, and the second for determining whether the list is empty.  The difference between the two is that we may not want to show the list if there isn’t any data to bind; however, once we bound, we may want to instead show a “no records found” message, which the emptyListData property is used for.  Additionally, if we have no data to bind, and the observable points to a null value, we can get an exception too.  However, I’m going to shortly circumvent that by using the “if” binding.  In the user interface, we can setup the view to use these properties as so:

<div data-bind=”if:hasLoadedListData”>
<div data-bind=”if:emptyListData”>
No records found.
</div>
<div data-bind=”ifnot:emptyListData”>
<!– data template –>
</div>
</div>

Now it’s time to load the data.  Once data is passed to the model, it loads the view with the data at the time it’s populated.  I’m not going to get into the aspects of where the data comes from. Assuming we can get JSON from some data store, the JSON we would use, requested from JQuery, can then be passed to the view model, as in the following:

$.ajax({
type: “post”,
url: “…”,
data: { .. },
success: function(d) {
viewModel.itemData(d.Data); //array data in Data property
}
});

Here we get the data in JSON form, grab the array data from the Data property (as it’s recommended to return an object as the root object, not an array, for security purposes), and push it to the model.  There is an interesting point here; when we push the data in, the data in the array is not observable by its nature.  While this data would load into the user interface, any changes made to the values of the individual objects themselves are not observable and do not participate in two-way binding.  You could do a conversion like:

from (var i = 0, len = d.Data.length; i < len; i++)
{
viewModel.itemData.push({ firstName: ko.observable(d.Data[i].firstName), .. });
}

Through this conversion, each object is observable and participates in two-way binding.

Now that we have our data, it loads into the user interface, either through the observable templates as I blogged about before, or through an inline template.