ASP.NET MVC And Client Side Lists with Kendo

In this post, I’m going to illustrate a very simple way to create client-side list-based UI’s in ASP.NET MVC. The idea with this example is to allow the ability to add a bulk number of list items that doesn’t require constantly posting back to add additional items. In this example, we’ll use Kendo UI Core framework templating capabilities, although any templating framework will do.

To start, let’s look at a very simple model:

public  class SystemTestModel
{
   public List Entities { get; set; }
}

public class SystemListEntity
{
   public string Name { get; set; }
   public string Value { get; set; }
   public bool IsDeleted { get; set; }
}

Here we have a View Model that has a list of child items. Very simple. Notice the entity has 2 properties, and an IsDeleted property, which will be illustrated later. For this example, the controller setup is simple; it reads the form posted values and rebuilds the non-deleted ones:

public ActionResult List()
{
   var model = new SystemTestModel { Entities = new List() };
   return View(model);
}

[HttpPost]
public ActionResult List(SystemTestModel model)
{
   //Remove non-deleted records - deleted from  client
   var entities = model.Entities.Where(i => i.IsDeleted == false);

   //Save entities to DB or other work
   //Reload UI
   return View(new SystemTestModel { Entities = entities.ToList() });
}

Within the view, the Name/Value pairs are rendered

<tbody id="Grid" data-last-index="@(Model.Entities.Count - 1)">
   @for (var i = 0; i < Model.Entities.Count; i++) {
     <tr>
         <td>
            <input type="text" name="@Html.NameFor(m => m.Entities[i].Name)" value="@Model.Entities[i].Name" />
            <input type="hidden" name="@Html.NameFor(m => m.Entities[i].IsDeleted)" value="@Model.Entities[i].IsDeleted" />
         </td>
         <td>
            <input type="text" name="@Html.NameFor(m => m.Entities[i].Value)" value="@Model.Entities[i].Value" />
         </td>
      </tr>
   }
</tbody>

Each server-side item is rendered using the collection-based naming syntax that MVC uses to identify collections. The name for a collection-based item looks like the server-side equivalent: Entities[X].[Field] (ie. Entities[0].Name). This is important because our client-side HTML template must do the same thing:


   <tr>
      <td>
          
          <input type="hidden" name="@Html.NameFor(m => m.Entities[-99].IsDeleted)" value="@Boolean.FalseString" />
      </td>
      <td>
          <input type="text" value="#= Value #" name="@Html.NameFor(m => m.Entities[-99].Value)" />
      </td>
   </tr>

Notice in the template the -99; the really neat thing about the NameFor helper is that the expression doesn’t need to be valid; -99 works and literally renders to the HTML as “Entities[-99].Name”. Notice that the script block is the same equivalent above, but will be used to render client-side additional elements. The HTML between the two doesn’t need to be exact, but similar. The view will use this template when the “Add” button is clicked.

What that really means is that the server may have rendered 2 name/value items, and the client can render additional pairs. Our approach is to ensure that we render the pairs in sequential order whether created from server or client, preserving that sequential order.

The view has an add button. The add button triggers the templating capability of kendo. The idea with the template is to get the HTML for the entry and replace the “-99” with the actual index. So if the server-side rendering produced 2 elements (using indexes 0 and 1), the client-side “Add” button generates items starting from index “2” and greater.

$(function () {
   //http://docs.telerik.com/kendo-ui/framework/templates/overview
   $("#NewButton").on("click", function (e) {
      var html = $("#ItemTemplate").html();
      //Get the last index, add 1 because we are adding an item at the new index
      var index = $("#Grid").data("last-index") + 1;
      $("#Grid").data("last-index", index);

      //Replace -99 with the new Index
      html = html.replace(/-99/g, index);

      //Can be used to apply data values from JS
      var template = kendo.template(html);
      var data = {}; //For now, not doing any template binding
      var content = template(data);
            
      $("#Grid").append(content);
   });
});

The first step here is get the templated HTML, and update the current index appropriately. When this UI posts back, the updated index sequence posts back the new items correctly at positions 2 and greater. When the UI reloads, we now have server-side items created from the new index, and new items can be added again.

You may have noticed the IsDeleted property; this can be used to indicate items as deleted. The UI can have a delete button, which can trigger JavaScript that can hide the entire TR tag of the item from view and update the hidden field. When posted back, a permanent delete can happen (purge from the DB if it was originally persisted).

The main goal of this approach is bulk entry of lists without having to postback to add each item, like web forms used to do.

Here is the entire View (assumes JQuery and Kendo scripts included):

@model SystemTestModel

<form action="" method="post">

   <div class="row">
      <div class="col-md-12">

         <table class="table table-bordered table-hover">
            <thead>
               <tr>
                  <th>Name
                  <th>Value
               </tr>
            </thead>
            <tbody id="Grid">
               @for (var i = 0; i < Model.Entities.Length; i++)
               {
                    <tr>
                      <td>
                         <input type="text" name="@Html.NameFor(m => m.Entities[i].Name)" value="@Model.Entities[i].Name" />
                          <input type="hidden" name="@Html.NameFor(m => m.Entities[i].IsDeleted)" value="@Model.Entities[i].IsDeleted" />
                        </td>
                         <td>
                             <input type="text" name="@Html.NameFor(m => m.Entities[i].Value)" value="@Model.Entities[i].Value" />
                           </td>
                          </tr>

               }
            </tbody>
         </table>

      </div>
   

   <div class="row">
      <div class="col-md-12">

         <button type="submit" name="Action" value="SAVE" class="btn btn-primary">
             Save 
         </button>
         <button type="button" name="Action" value="NEW" class="btn btn-default">
             New
         </button>

      </div>
   </div>

</form>

@section scripts {
   
      <script type="text/x-kendo-template">
               <tr>
                    <td>
                        <input type="text" value="#= Name #" name="@Html.NameFor(m => m.Entities[-99].Name)" />
                        <input type="hidden" name="@Html.NameFor(m => m.Entities[-99].IsDeleted)" value="@Boolean.FalseString" />
                    </td>
                     <td>
                        <input type="text" value="#= Value #" name="@Html.NameFor(m => m.Entities[-99].Value)" />
                     </td>
              </tr>
      </script>

<script type="text/javascript">
      $(function () {

         //http://docs.telerik.com/kendo-ui/framework/templates/overview
         $("#NewButton").on("click", function (e) {
            var html = $("#ItemTemplate").html();
            //Get the last index, add 1 because we are adding an item at the new index
            var index = $("#Grid").data("last-index") + 1;
            $("#Grid").data("last-index", index);

            //Replace -99 with the new Index
            html = html.replace(/-99/g, index);

            //Can be used to apply data values from JS
            var template = kendo.template(html);
            var data = {}; //For now, not doing any template binding
            var content = template(data);
            
            $("#Grid").append(content);
         });

      });
   </script>

}

And Controller:

public class SystemListEntity
   {
      public string Name { get; set; }

      public string Value { get; set; }

      public bool IsDeleted { get; set; }

   }


    public class SystemController : BaseController
    {

         public ActionResult List()
         {
            var model = new SystemTestModel { 
                          Entities = new List<SystemListEntity>() };

            return View(model);
         }

         [HttpPost]
         public ActionResult List(SystemTestModel model)
         {
            var entities = model.Entities.Where(i => i.IsDeleted == false);

            //Save entities

            //Reload UI
            return View(new SystemTestModel { Entities = entities.ToList() });
         }
}

Some Considerations For MVC 6 Client Attributes

One of the new features coming is the addition of Tag Helpers, which are server-side attributes that get interpreted and translated into a client-side attributes. This transforms the previous approach we used to use of the following:

@Html.ActionLink("Text", "Action", "Controller")
@* OR *@
<a href="@Url.Action("Action", "Controller")">Text</a>

Both of the above examples translate to the same result; Html.ActionLink builds a link with a single HREF attribute. One of the changes available with tag helpers is to instead use new “asp” prefixed attributes to perform the rendering:

<a asp-controller="Controller" asp-action="Action">Text</a>

These attributes get translated to a href client-side attribute with the appropriately generated URL. There are a variety of tags available that support server-side attributes, outside of the hyperlink. For instance, the form and label tags also support attributes, as well as others that you can find more at the following resources:

There is lots of good content out there on the subject already. I wanted to discuss in this post the merits of tag helpers, and discuss some of the pros and cons. Whatever is discussed with tag helpers, it’s important to remember that you can always utilize the old way of developing the user interface. To my knowledge, that isn’t going away.

It is important to remember that tag helpers are server-side; they still run server-side code, and so you cannot use asp attributes at client time. The client-side interpreters do not know of these attributes, but the server does as in this post. So if you like to use jQuery or Kendo UI templating, tag helpers won’t really give you much, as you have to render the link anyway. Now, there are server-side tricks to rendering client content that can be utilized, which I have written about in the past on this blog, and so there are ways to leverage that depending on what you are doing.

You also have to be careful which attributes you use where, as certain attributes are supported for certain tags. I haven’t found a comprehensive list yet, other than the Mikesdotnetting post. So be careful as you use new attributes to account for that. Also, some properties define expressions to the field in the model that may contain additional information. For instance, the label may support a field to grab the display information. In this case, the attribute defines the name of the field to display information for, which corresponds to the property in the model. It will be interesting to see how Tag Helpers support deep nested models, and whether we need to render names like Customers[0].FirstName when working with lists. This is one area where the old tags make it a little more clear.

These are some preliminary ideas to think about; I’m sure I’ll be amending this post as I think of other considerations after publishing this post ūüôā

Dynamic Script Registering Component in ASP.NET MVC

One of the performance enhancements recommended in tools like YSlow and others is to put your JavaScript script files at the bottom of the page. The great difficulty in a web forms or MVC web application with doing that is scripts at the bottom of the page are typically added in the master page. Any pages or views can make use of a special section just for scripts, but partial views or user controls can’t take advantage of that.

I’m about to illustrate a solution that will do just that. It’s setup for MVC, but could be easily adapted for web forms by making the helpers as controls. You have to understand that MVC is a top down structure. So as views or partials render, they render their contents in place. The common approach is to have a section for scripts:

site.master:


  // master page common scripts


@* for any custom scripts in the view *@
@RenderSection("scripts", false)

The view can add a @section scripts { } to take advantage of this, but the partial view cannot. Additionally, everything is rendered in top down format; if a partial view at the top of your page has a script like:


$(function() { alert("In the partial view"); });

The problem with this script is that the final rendered view (when scripts are defined at the bottom) will look like:


$(function() { alert("In the partial view"); });


.
.
.
view content
. . // master page common scripts // view scripts

Since it’s top down, it’s also dependent on order, so scripts defined have no dependency (lacking a dependency feature like angular or script JS).

The following solution was meant to give more control over placement of defined scripts. Scripts are defined in a wrapper, and queued up for later rendering. The solution I’m providing is simple, but easily enhanced to add dependencies in scripts, custom ordering, and more features.

To give an idea of what we need to do, the system will achieve something like the following:

view.cshtml:

@Html.AddScript("ViewInit", () => @$(function() { .. }));

partial view:

@Helper Script()
{
   
     ..
   
}

@Html.AddScript("PartialInit", (m) => Script());

master:

@Html.PlaceScripts()

The idea is to add scripts via a method, which queues them up to be rendered, and writes them out at the point the PlaceScripts method is called. Note that for partial views, I’m using a little trick I noted earlier, whereby using a helper is the only way to circumvent exceptions that occur when using the action-based approach.

AddScript essentially adds the definitions to the HttpContext.Items collection, a common trick for storing singleton-like data elements that are available across the application. Since HttpContext.Items is available to add and then render scripts, it’s a great place to share content. The AddScript method shoves in data:

public void AddScript(HtmlHelper html, string key, Action fn)
{
    var http = html.ViewContext.HttpContext;
	var list = http.Items["_Scripts"] as Dictionary;
	
	if (list == null)
		list = new Dictionary();
	
	list[key] = fn;
	
	http.Items["_Scripts"] = list;
}

This method checks to see if we have a dictionary in the items collection; if not, it creates it, pushes in our item, and updates the collection. Similar, our other method, which takes a helper result, uses another overload to store the string result for easy rendering:

public void AddScript(this HtmlHelper html, string key, HelperResult fn)
{
	this.AddScript(html, key, fn(html.ViewData.Model).ToHtmlString());
}

public void AddScript(this HtmlHelper html, string key, string script)
{
    var http = html.ViewContext.HttpContext;
	var list = http.Items["_Scripts"] as Dictionary;
	
	if (list == null)
		list = new Dictionary();
	
	list[key] = script;
	
	http.Items["_Scripts"] = list;
}

We could easily add dependencies and ordering requirements to this solution if we needed; for now, let’s finish this out by showing how to grab the contents and render them:

public void PlaceScripts(this HtmlHelper html)
{
var http = html.ViewContext.HttpContext;
var list = http.Items[“_Scripts”] as Dictionary;

if (list == null)
return;

using writer = new HtmlTextWriter(html.ViewContext.Writer)
{
foreach (var entry in list)
{
if (typeof(entry.Value) is string) {
writer.WriteLine(entry.Value);
}
else {
//This is an action; the action will be
//rendered in the current output stream, and
//do not need to be directly written
entry.Value(html.ViewData.Model);
}
}
}

}

This would need greatly enhanced for dependencies and sorting; right now, we take the list in order and render it out. For HTML results or just plain string definitions, it gets rendered to the current response stream. Actions get processed the same way, but MVC handles that internally, rather than your code.

And voila, we are done; now we can define scripts in the view and partial views and expect them to be rendered where we want them placed, and have a component that can be easily enhanced to do much more.

Rendering Markup Anywhere in MVC

I had a hard time coming up with the title, because as you know, markup is pretty dynamic in MVC. However, I came across an interesting limitation when it came to rendering markup. I’m not talking about rendering partial view content using Html.Partial, or using a helper method. I’m actually talking about rendering markup segments, which I’ll demonstrate with a VB.NET example (sorry, I’ve been stuck in the VB world for some time, it’s become more natural than C#):

@* SomeView.vbhtml *@
@Code
Html.ScriptDefine(
   @
      alert("ME");
   )
End Code

Html.ScriptDefine is not something Microsoft created, but a custom extension I created. This was a helper method to register script segments. It is not a method defined globally or in a view, but a helper that’s code, which can be easily reused across projects, which is why I tried to utilize this technique. Somewhere in the master page, a process read all of these scripts and rendered them in the master page. This was excellent; I could define these script blocks anywhere in the view, and they would all get rendered in one place.

My helper looked like the following:

Public Sub ScriptDefine(Of TModel)(html As HtmlHelper, key as String, fn as Action(Of TModel))
    Dim script = fn(html.ViewData.Model)
    'Store reference to model and script somewhere, 
    'which the master page retrieves all of the scripts and renders
End Sub

It worked, except in one scenario: Partial Views, which is a key reason why I wanted it. See, I often found myself using scripts in a partial view. I tried using an optimization technique where scripts run at the end of the page; the only problem was a partial view that used a script had it’s <script /&rt; block defined wherever the partial was, which was usually above the end of the view. The issue with partial views has to do with the rendering process, and although I wasn’t quite sure how to figure out why, I found a better solution anyway: HelperResult.

By defining the script in a helper (a small caveat) and then storing the helper result, this solved the problem much more easily. I was able to define an extension like the following:

Public Sub ScriptDefineHelper(Of TModel)(html As HtmlHelper, key As String, fn As Func(Of TModel, HelperResult))
   Dim helperResult = fn(html.ViewData.Model) 'Returns the content as IHtmlString
   Dim list = CType(html.ViewContext.HttpContext.Items("_Scripts_"), List(Of String))

   if (list Is Nothing) Then
      list = new List(Of String)
   End If

   list.Add(helperResult.ToHtmlString()) 'Store the scripts as a string, which is easy to render later

   html.ViewContext.HttpContext.Items("_Scripts_") = list
End Sub

Now wherever we use our helper, we can use it like:

@Code
  'Use in view or partial view
  Html.ScriptDefineHelper(Function(i) Scripts())
End Code

@Helper Scripts()
   
      alert("Hello");
   
End Helper

And we can render out all the scripts with the following code (we can also use a helper method for this):

Dim items = CType(html.ViewContext.HttpContext.Items("_Scripts_"), List(Of String))
For Each item in items
  @Html.Raw(item)
Next

The real question is why do all of this, when all of the scripts could be in the page? Well, there are good reasons for doing this. First and foremost, keeping the scripts used in a partial view are best defined in the partial view. Out of sight is out of mind, especially for JavaScript. By using this technique, scripts can be defined, and rendered at the designed area, more effectively. That is the primary benefit; outside of that, there aren’t a lot of benefits.

Custom ASP.NET MVC Helper Extensions

As you probably are aware of, ASP.NET MVC was a divergence from the approach developers took to developing ASP.NET web forms applications. For web forms developers, any level of customizations occurred by creating custom ASP.NET server controls, inheriting from a particular base class and adding some functionality, something like:

public class SuperLabel : Label
{
   // Enhanced functionality
}

There are many benefits to doing this; you can initialize the control’s properties for your web application, or encapsulate repeatable code into a common class that’s reused throughout the application. For instance, if we know that we will always render our form labels in a specific manner, I could create a custom control to do this following:

public class FormLabel : WebControl
{

   protected override void Render(HtmlTextWriter writer)
    {
         writer.Write("<div>" + this.Text + "</div>");
    }

}

And that way, every label is wrapped in a div with a FormLabel class. This is a simple example of standarizing your control’s output and thus your client’s markup, but you get the idea. This is also possible in ASP.NET MVC, with the help of your own helper methods.

Note that there are two kinds of helper methods in MVC: ones who return an MvcHtmlString object and render the text inline, and ones that render inside the method and are defined as @Html.DoSomething(); (with a semi-colon at the end; in VB this method can be called in a @Code block). I’m going to talk about helpers that return an MvcHtmlString in this blog post. As a simple example of a helper we may want to standardize on, we can, for instance, wrap a DIV with a special class around the Html.EditorFor helper as in the following example:

public static class HtmlHelperExtensions
{

  public static MvcHtmlString CustomEditorFor(this HtmlHelper html, Expression<Func> expr)
  {
     return new MvcHtmlString("<div>" + html.EditorFor(expr) + "</div>");
  }

}

As you can see, we have a custom editor with a wrapper DIV around it now, which we can put in our UI by doing:

@Html.CustomEditorFor(i => i.ModelProperty)

The TModel and TProp generic references above are inferred from the current view’s model, and the property expressed in the lambda expression. If you look in other MVC helpers, they are all defined with these two generic references. The HtmlHelper class has a lot of useful features; first it has access to all the extension methods as you would use them in the UI (most defined in the System.Web.Mvc.Html namespace, but there are additional namespaces too). It also has a reference to the ViewContext and to the current model for the given view, via the HtmlHelper.ViewData.Model property (remember HtmlHelper is specific to the model, therefore it maintains an explicit, strongly-typed reference to said model).

I’ve only scratched the surface, but you can see a lot of options are available to you. For instance, if you use Twitter bootstrap, maybe you want your editor helper to look like:

 public static MvcHtmlString CustomEditorFor(this HtmlHelper html, Expression<Func> expr)
  {

     return new MvcHtmlString(
  @"<div class=\"control-group\">" + 
    html.LabelFor(
        expr, 
        new { @class = "col-md-2 control-label" }
     ).ToHtmlString() +
   @"</div>
     <div class=\"col-md-10\">" + 
    html.EditorFor(expr) + 
    "</div>");

  }

And thus, this saves you from writing a lot of HTML. In the future, I may write on some of the extensions I’ve used for twitter bootstrap to save time. I hope this is a good overview of how you can customize HTML helpers in ASP.NET MVC, which I am using this technique in a current ASP.NET MVC 5 application.

Custom Validator Execution in Windows Store Apps, Part 2

In part 1, we looked at the creation of a Windows 8 required validator control by constructing a WinJS class. In order to create a more full-fledge validation feature (but the final version of this will not as feature complete as the ASP.NET validation system, as it didn’t need to be), I had to use some additional components, which I will outlay in this blog post.

Each validator manages itself, validating the control it’s supposed to and registering itself with teh window object, using a window[“Validators”] collection. This is very similar to the Page.Validators collection in ASP.NET. ASP.NET also uses the page to trigger validation; this didn’t quite work for my scenario. Instead, I included the following component to handle validation.

var valExecutor = WinJS.Class.define(
	function (element, options) {
		this.element = element;
		this.element.winControl = this;

		this._isvalid = true;

		WinJS.UI.setOptions(this, options);
	},
	{

		clear: function () {
			var list = window["Validators"] || [];

			for (var i = 0, len = list.length; i < len; i++) {
				var item = list[i];
				item.isvalid = true;
			}
		},

		isValid: function() {
			return this._isvalid;
		},

		validate: function () {
			this._isvalid = true;
			var list = window["Validators"] || [];

			for (var i = 0, len = list.length; i < len; i++) {
				var item = list[i];
				item.validate();

				if (!item.isvalid)
					this._isvalid = false;
			}

			this.dispatchEvent("validated", { isValid: this._isvalid });

			return this._isvalid;
		}

	}
);

This is a control that you would put in the view. The executor picks up the list of validators in the windows collection, loops through them all, checks for validity, and then performs some cleanup work. We can then simply call validate() on this control to validate all of the validators, instead of each control individually (but you can do that too if you like).

This control could very easily have acted like a validation summary, putting a message in a list and displaying the list of results to the user. It could have added the useful validation groups feature too, but again, that was overkill for my needs at the moment. I didn’t have that need at the moment, but it could be very easily done. We can use our control in a view like:

<div id="valexec" 
   data-win-control="PrayerLink.UI.ValidationExecutor" 
   style="display:none"></div>

And invoke validation via:

var val = document.querySelector("#valexec").winControl;
val.validate();

if (!val.isValid()) {
	/* do something */
}

The validation occurs, we can check whether the object is valid and do something about it. And that’s all that it takes to create a simple validation control in Windows 8 store apps using HTML and JavaScript.

Intro to Windows 8 Store Apps Using JavaScript and HTML

Windows 8 is the next great operating system for Microsoft. I detailed the changes that the operating system is bringing to the common consumer. As you can see, it comes with quite a few user interface changes. However, for the developer, the focus on development shifts away from developing traditional windows applications, and moves toward developing a windows store application. This is a big paradigm shift that has an interesting twist. Applications that were previously only for mobile devices are now able to be installed on a laptop or desktop computer too. It brings about a lot of interesting possibilities.

Interestingly enough, Windows 8 or RT development supports both XAML and HTML/JavaScript. Each has it’s pros and cons, which I really don’t want to get into here. I’ve decided to use JavaScript templates for application development for this blog series. I’m choosing HTML and JavaScript for several reasons; it’s easy to layout and style, it’s easy to work with and I can personally develop an application rather quickly. It’s familiar to me as an ASP.NET and web developer, and it resembles building an application with PhoneGap. PhoneGap is another HTML/JavaScript framework that supports Windows 8 and other platforms. Transitioning from an HTML/JavaScript Windows 8 application to a PhoneGap application will be easier.

To create a new application, go into Visual Studio 2012 (within Windows 8) and select add a new project. Navigate to the JavaScript category, then Windows Store. Select one of the 5 existing templates to choose from, depending on the layout you need. Each template comes with a different set of files already defined for you; however, if you want to start from scratch, choose the Blank Template.

When you create your application, there are a few items to note. In the root of the application is default.html, the default page of that application that is the root container page for the single page application (SPA) template. This is the page always loaded into the application. With a single page application template, content can be loaded within the page, similar to an include file or a user control in ASP.NET. Page content consists of the following file types: .html, .js, and .css. The HTML file is the view that presents the content, whereas the JS file is the controller of sorts, similar to an MVC pattern implementation, leaving the CSS file to manage the user presentation. Each of the pages typically resides in the pages folder.

Let’s take a look at a sample application’s page. Below is a Login page that I used for an application. The easiest part to start is the HTML of our login page. ¬†To create a new page, select Add > New Item > Page Control. ¬†This creates the HTML, CSS, and JavaScript for you. ¬†I’ve modified the default to look as the following:

<html>
<head>
<meta charset=“utf-8” />
<title>Login</title>
<link href=“//Microsoft.WinJS.1.0/css/ui-dark.css” rel=“stylesheet” />
<script src=“//Microsoft.WinJS.1.0/js/base.js”></script>
<script src=“//Microsoft.WinJS.1.0/js/ui.js”></script><link href=“Login.css” rel=“stylesheet” />
<script src=“Login.js”></script>
</head>
<body>
¬† <div class=“Login fragment”>
<header aria-label=“Header content” role=“banner”>¬† ¬† <button class=“win-backbutton” aria-label=“Back” disabled type=“button”></button>
¬† ¬† <h1 class=“titlearea win-type-ellipsis”>
¬† ¬† ¬† <span class=“pagetitle”>Login to PrayerLink</span>
    </h1>
  </header>
<section aria-label=“Main content” role=“main”>¬† ¬† <table>
     <thead></thead>
     <tbody>
<tr>
<td>
User Name:
        </td>
<td>
<input type=“text” id=“UserName” name=“UserName” />
</td>
</tr>       <tr>
<td>
Password:
</td>
<td>
<input type=“password” id=“Password” name=“Password” />
</td>
</tr>
<tr>
<td colspan=“2”>
<button id=“LoginSubmit”>Login</button>
</td>
</tr>
</tbody>
</table>

  </section>
</div>
</body>
</html>

A lot of this code sample is provided standard from Microsoft. ¬†The header and core wrapper is automatically provided for you. ¬†Even within the page’s content, you can see it defines all of the styles and CSS content the page uses. ¬†Notice it provides the header of the page using pre-defined styles defined in the ui-dark.css stylesheet, and some other core wrapping content.

All of the login’s custom content is within the section element, with the role of main (for you JQuery enthusiasts, that would be “section[role=’main’]” :-D). Notice I have a form with standard input elements. The Windows 8 framework styles these components to have a much better appearance than the standard textbox.

WinJS.UI.Pages.define(“/pages/Login/Login.html”, {// This function is called whenever a user navigates to this page. It// populates the page elements with the app’s data.ready: function (element, options) {

var btn = element.querySelector(“#LoginSubmit”);

btn.addEventListener(“click”, hnd);

},    unload: function () {

// TODO: Respond to navigations away from this page.

},

updateLayout: function (element, viewState, lastViewState) {

///

// TODO: Respond to changes in viewState.

}

});

The page class defines certain event handlers such as ready, similar to JQuery’s ready event; unload, which runs when the page is unloaded; and updateLayout, a method that runs when the layout needs to be updated as the view changes modes between full screen to snapped to landscape, etc.

As developers, we are used to defining events in markup that point to an event handler. Rather than using this approach, it’s advisable to use the addEventHandler method on the element, which can attach an event handler using a defined method, or with a dynamic function, like the following example:

var btn = element.querySelector(“#LoginSubmit”);btn.addEventListener(“click”, hnd);

Here the “hnd” function fires when the button is clicked. On click of the button

var hnd = function (sender, e) {var user = document.querySelector(“#UserName”).value;var pwd = document.querySelector(“#Password”).value;.

.

}

In this example, the handler of the button grabs the reference to the elements using document.querySelector, using a CSS syntax for finding the elements by it’s ID. Once the element is retrieved from the DOM, we can then access the input element’s value via the value property.

This is a brief intro to windows 8 apps; I plan to go into more detail in future blog posts.

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 Part 5: Templates

In the past examples, we created a view like:

<div data-bind=”foreach:people”>
<div data-bind=”html:name”></div>
</div>

Where the model was:

function viewModel() {
var self = this;

self.people = ko.observableArray([{ name: “ABC” }]);
}

And this binding works fine; but there is another way to do this.  We can also use templates, or a section of markup

<!– name matches the ID of the template, data matches the data property –>
<div data-bind=”template: { name: ‘peopleScript’, data: itemData }”> </div>

<!– id is required –>
<script id=”peopleScript” type=”text/html”>
<ul data-bind=”foreach: $data”>
<li>
Name: <span data-bind=”text: name”> </span>
State: <span data-bind=”{ text: state }”> </span>

<span data-bind=”visible: ($root.inState($data))”>
(In State)
<span>
</li>
</ul>
</script>

Instead of using the typical bindings, we define an element with a template binding. ¬†The template binding needs a name, matching an existing template name, and a reference to an observable property (itemData is defined in the view model). ¬†Next, we have the template itself; the template is a script tag with the “text/html” designation. ¬†This is the designation Knockout came up with for its templates. ¬†A template uses a script tag, defines a markup segment with appropriate bindings directed to the context of the data. ¬†This means the template represents the itemData observable. ¬†This is why I use the $data reference in the foreach binding, referring to the itemData array of objects.

There are some pros and cons to this approach; here we have an isolated template not mixed in with the rest of the markup; this allows some separation, which in some cases is good and some bad.  It may actually be possible to load or create a template on the fly, and not be dependent on a static template (I have not actually tried this to verify it).  A template is bound to the context of the data bound to it, which can be a single object or an array.

The creation of the model is more complex in this example.  Take a look at the sample below:

$(document).ready(function() {

$.ajax({
url: “jsondata.js”,
type: “get”,
dataType: “json”,
success: function(data) {
function viewDataModel() {
var self = this;

self.itemData = [];

//translate JSON objects into observables
for (var i = 0, len = data.people.length; i < len; i++) {
self.itemData.push({ name: ko.observable(data.people[i].name), state: ko.observable(data.people[i].state) });
}

self.inState = function(person) {
var state = person.state();
if (state != null && state == “PA”)
return true;
else
return false;
}
};

ko.applyBindings(new viewDataModel());
},
error: function(ex) {
. .
}
});

});

This sample builds the view model after retrieving the data from the server; since it’s a one-time binding, this works OK. ¬†It would be more preferrable to create the view with empty values and bind it, followed by setting the individual property values with the results of the AJAX call.

I hope this post illustrated how we can use templates in a fashion that make it easier to bind snippets of markup.