jQuery and MVC–Part 3

By James at November 19, 2010 19:11
Filed Under: JavaScript, MVC, jQuery, jQuery Plugins

In the last article I talked about MVC and doing some nifty Ajax functionalities with jQuery. In this article I will go over jQuery plugins, what they are and how to create them.

jQuery Plugins

jQuery has a plugin architecture which allows you to package up commonly used functions into a plugin. Chances are if you have a complex JavaScript function, someone has more than likely written a plugin to handle that particular functionality. The jQuery.com site has an extensive plugin library and it can sometimes be fun to browse through it to see what people have come up with.

Plugins are fairly easy to write, once you have gotten the basics of jQuery down. Here is a tooltip plugin that I wrote in just a few minutes.

   1: (function ($) {
   2:     $.fn.tooltip = function (options) { // make sure to name the function
   3:                                         // the same as your tooltip
   4:         var methods = {
   6:             //initialize stuff
   7:             init: function (options) { },
   9:             //destroy and clean up
  10:             destroy: function () {
  11:                 return this.each(function () {
  12:                     $(window).unbind("tooltip");
  13:                 })
  14:             }
  15:         };
  17:         // default settings if they aren't passed in
  18:         var settings = {
  19:             'backgroundColor': 'red',
  20:             'color': 'blue',
  21:             'toolTipText': 'Hi',
  22:             'fontWeight': 'bold'
  23:         };
  25:         // add the settings into the options
  26:         return this.each(function () {
  27:             if (options) {
  28:                 $.extend(settings, options);
  29:             }
  31:             var $this = $(this);
  32:             $this.mouseenter(function (event) {
  33:                 $this.css("color", settings.colorEnter);
  35:                 // if the div#toolTip isn't in the DOM, create a new one
  36:                 if (!$("#toolTip").length) {
  37:                     // create the element
  38:                     $('<div id="toolTip"></div>')
  39:                         // set the text to passed option
  40:                         .html(settings.toolTipText)
  41:                         // from the style sheet
  42:                         .addClass("toolTip")
  43:                         // insert the div into the DOM just after $this
  44:                         .insertAfter($this)
  45:                         // position the div
  46:                         .css({ "left": $this.width(),
  47:                         // set the backgroundColor
  48:                         "backgroundColor": settings.backgroundColor,
  49:                         // set the font
  50:                         "fontWeight": settings.fontWeight,
  51:                         // set the color
  52:                         "color": settings.color
  53:                     }); 
  54:                 }
  55:                 $("#toolTip").fadeIn(500);
  56:             });
  58:             $this.mouseleave(function () {
  59:                 $this.css("color", settings.colorLeave);
  60:                 $("#toolTip").fadeOut(500);
  61:             });
  62:         });
  63:     };
  64: })(jQuery);

It’s not a pretty thing, or even that functional, but it does show off how fast you can write a plugin. Let’s take a look at how this plugin is implemented.

1. In the <head> tag of your page include the references to your jQuery and JavaScript files.

   1: <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
   2: <script src="Scripts/jquery.tooltip.js" type="text/javascript"></script>
   3: <script src="Scripts/AppScripts.js" type="text/javascript"></script>

2. Somewhere on your page add an element that will call the plugin

   1: <div class="test">This is the element that will have the assignment</div>

3. In your custom JavaScript, attach the plugin to the element and pass in any options you need to.

   1: $(document).ready(function () {
   2:     $("div.test").tooltip({ "toolTipText": "Hello from ComponentOne", 
   3:         "color":"white" })
   4:         .click(function () { alert("hi"); });
   5: });

4. Add the following to your style sheet to style up the test div.

   1: .test{width:200px;
   2:    float:left;background:silver;
   3:    color:White;border:1px solid White;
   4:    cursor:pointer;padding:5px}

5. Open the page in a browser, then hover over the test div. If all goes well, you should see the following.




Obviously this isn’t the world’s greatest plugin, but does cover the basics of getting started. Information on building more functional plugins can be found at http://docs.jquery.com/Plugins/Authoring

TableSorter, a more functional plugin

Since we are working with tabular data in this application, I want to use a plugin that will modify an HTML table and make it sortable. Searching through the plugins library I found “TableSorter” at http://tablesorter.com. It is written by Christian Bach at www.lovepeacenukes.com and does a great job of providing a pretty nifty data grid from a static HTML Table.

Let’s take a look.


In the head tag of the HTML file place a reference to the TableSorter plugin right after the reference to the jQuery file.


In the View in which you want to show the table, write your code to render a table with the data you want to show. One thing about the TableSorter plugin is that it requires valid HTML tables complete with <thead> and <tbody> tags. The following markup is written with the new MVC 3 Razor View Engine.

   1: <table id="studentTable" class="studentTable {sortlist: [[6,0]]}">
   2:     // sortlist is a function of the plugin which automatically sorts
   3:     // on a specific column
   4:     <thead>
   5:     <tr>            
   6:         <th>First Name</th>
   7:         <th>Last Name</th>
   8:         <th>Email</th>
   9:         <th class="{sorter: false}">Comments</th> 
  10:         // sorter class is a plugin option
  11:         <th>Submit Date</th>
  12:         <th>Approved Date</th>
  13:         <th>Approved</th>
  14:     </tr>
  15:     </thead>
  16:     <tbody>    
  17:     @foreach (var item in Model)
  18:     {        
  19:         var approvedDate = string.Empty;
  20:         if (item.ApprovedDate.HasValue) { 
  21:             approvedDate = item.ApprovedDate.Value.ToShortDateString(); 
  22:         }
  23:           <tr>               
  24:             <td>@item.FirstName</td>
  25:             <td>@item.LastName</td>
  26:             <td>@item.Email</td>
  27:             <td>@item.Comments</td>
  28:             <td>@item.SubmitDate.ToShortDateString()</td>
  29:             <td>@approvedDate</td>
  30:             <td>
  31:               <span style="display:none" class="hiddenSpan">@item.Approved</span>
  32:               @Html.Hidden("Approved", item.Approved)
  33:               @Html.Hidden("studentId", item.Id)
  34:               @{var chk = "chkGraphic chkUnChecked";}
  35:               @if (item.Approved.HasValue && item.Approved.Value.Equals(true))
  36:               {
  37:                   chk = "chkGraphic chkChecked";
  38:               }
  39:               <div class="@chk"></div>
  40:               <img src="../../Content/Images/ajax-loader.gif" 
  41:               class="ajaxLoader ajaxLoaderSmall" />
  42:             </td>
  43:         </tr>
  44:     }    
  45:     </tbody>
  46: </table>

Since we are rendering a table, we can use the $(document).ready(function(){});

Add the following in your custom JavaScript file:

   1: /// <reference path = "/Scripts/jquery-1.4.1-vsdoc.js"/>
   3: $(document).ready(function () {
   4:     $("#studentTable").tablesorter({ widgets: ['zebra'] });
   5:     // zebra is a “widget” included in the plugin which will alternate
   6:     // the row colors of the table
   7: });

Run the page and sort the columns. One thing to note in the markup is in the last column. The plugin sorts on the data contained in the columns of each row. Since I want to sort on “Approved”, I add a hidden field with that data as the first element in the cell.



The TableSorter plugin has many more options than this brief demo show. If you want to explore it more, download it at http://tablesorter.com.

A Freebie

If you look at lines 30 - 42 in the markup you may be wondering what all the other stuff is, including the <div class=”@chk”></div>. I wanted to spiff up the form and use graphics for the checkboxes, but still keep the functionality of a checkbox. Here is how to do it.

1. In the style sheet add the following classes.

   1: .chkGraphic{cursor:pointer;width:22px;height:22px;float:left;margin-right:5px}
   2: .chkChecked{background:url(Images/checkBoxOn.png)no-repeat}
   3: .chkUnChecked{background:url(Images/checkBoxOff.png)no-repeat}

2. In your custom JavaScript file, add the following functions.

   1: $("div.chkGraphic").live("click", function () { toggleGraphicCheckBox(this); });
   3: function toggleGraphicCheckBox(elem) {
   4:     var $elem = $(elem);
   5:     $elem.siblings("img.ajaxLoader").show();
   6:     var valueField = $elem.siblings("input[type=hidden][name=Approved]");
   7:     if ($elem.hasClass("chkChecked")) {
   8:         $elem.removeClass("chkChecked").addClass("chkUnChecked");
   9:         valueField.val("False");
  10:     } else {
  11:         $elem.removeClass("chkUnChecked").addClass("chkChecked");
  12:         valueField.val("True");
  13:     }
  14:     $("span.hiddenSpan").html(valueField.val());
  15:     toggleStudentApproval($elem);
  16: }
  18: function toggleStudentApproval(elem) {    
  19:     var approved = elem.siblings("input[type=hidden][name=Approved]").val();
  20:     var studentId = elem.siblings("input[type=hidden][name=studentId]").val();
  21:     $.ajax({
  22:         url: "/Home/GetStudent/" + studentId + "/" + approved,
  23:         type: "GET",
  24:         success: function (result) {
  25:             showStudentApproval(result, elem);
  26:         }
  27:     });
  28: }
  30: function showStudentApproval(result, elem) {    
  31:     var id = result.Id;
  32:     var td = elem.parent("td").prev("td");
  33:     td.html("");
  34:     if (result.ApprovedDate != null)
  35:         td.html(result.ApprovedDate);
  36:     elem.siblings("img.ajaxLoader").fadeOut(500);
  37: }

Here’s the markup again.

   30: <td>
   32:  <span style="display:none" class="hiddenSpan">@item.Approved</span>
   33:  @Html.Hidden("Approved", item.Approved)
   34:  @Html.Hidden("studentId", item.Id)
   35:  @{var chk = "chkGraphic chkUnChecked";}
   36:  @if (item.Approved.HasValue && item.Approved.Value.Equals(true))
   37:  {
   38:     chk = "chkGraphic chkChecked";
   39:  }
  40:  <div class="@chk"></div>
  41:  <img src="../../Content/Images/ajax-loader.gif" 
  42:        class="ajaxLoader ajaxLoaderSmall" />
  43: </td>

Now based on what you’ve read so far in this and the previous articles, take a look at all the code and see if you can figure out what will happen when the graphical checkbox is clicked. Add a comment to this article and let me know what you think it will do.

Just for grins and giggles, I converted the JavaScript above to a plugin, jquery.graphicCheckBox.js

   1: (function ($) {
   2:     $.fn.graphicCheckBox = function (options) {
   3:     var methods = {
   4:         // initialize stuff
   5:         init: function (options) { },
   6:         //destroy and clean up
   7:         destroy: function () {
   8:             return this.each(function () {
   9:                 $(window).undbind("graphicCheckBox");
  10:             })
  11:         }
  12:     };
  13:     // default settings if they aren't passed in
  14:     var settings = {
  15:         'checked': 'chkChecked',
  16:         'unchecked': 'chkUnChecked',
  17:         'urlToAction': '/Home/GetStudent/'
  18:     };
  19:         // add the settings into the options
  20:     return this.each(function () {
  21:         if (options) {
  22:             $.extend(settings, options);
  23:         }
  25:         var $this = $(this);
  26:         $this.click(function (event) {
  27:             $this.siblings("img.ajaxLoader").show();
  28:             var valueField = $this.siblings("input[type=hidden][name=Approved]");
  29:             if ($this.hasClass(settings.checked)) {
  30:                 $this.removeClass(settings.checked).addClass(settings.unchecked);
  31:                 valueField.val("False");
  32:             } else {
  33:                 $this.removeClass(settings.unchecked).addClass(settings.checked);
  34:                 valueField.val("True");
  35:             }
  36:             $("span.hiddenSpan").html(valueField.val());
  37:             toggleApproval($this);
  38:         });
  39:     });
  40:     function toggleApproval(elem) {
  41:         var approved = elem.siblings("input[type=hidden][name=Approved]").val();
  42:         var id = elem.siblings("input[type=hidden][name=studentId]").val();
  43:         $.ajax({
  44:             url: settings.urlToAction + id + "/" + approved,
  45:             type: "GET",
  46:             success: function (result) {
  47:                 showApproval(result, elem);
  48:             }
  49:         });
  50:     }
  51:     function showApproval (result, elem) {
  52:         var id = result.Id;
  53:         var hid = elem.siblings("input[type=hidden][name=studentId]").val();
  54:         var td = elem.parent("td").prev("td");
  55:         td.html("");
  56:         if (result.ApprovedDate != null)
  57:             td.html(result.ApprovedDate);
  58:         elem.siblings("img.ajaxLoader").fadeOut(500);
  59:     }
  60: }
  61: })(jQuery);

In this article we talked about extending jQuery with plugins, how to write a simple plugin, and explored a fully functional table sorter plugin. I even threw in a groovy freebie for you.

Happy Programming,


jQuery and MVC Part 2

By James at November 15, 2010 17:46
Filed Under: JavaScript, MVC, jQuery

In our last episode we went over the basics of JavaScript and the jQuery library. In this installment I will show you the basics of MVC and how it renders HTML differently than Web Forms pages, and finish up showing some basic Ajax with jQuery.

When ASP.NET first arrived it was a good thing. Web Forms allowed developers to build websites in a way that was very similar to how Windows Forms applications where built, with drag and drop of controls and a “code behind” architecture. Web Forms served their purpose for many, many applications in the enterprise, and many commercial applications, both large and small were successfully built using this technology.

When “Web 2.0” arrived, complete with Ajaxy interactions, Microsoft put forth their own brand of controls to handle this, and for the most part this worked, and continues to work well. However the Web Forms framework makes it difficult to build clean, lean web sites, as the technology depends on many different things in the rendered HTML to make it usable when posting back to the server. Two of the main items are ViewState and Control Rendering.

ViewState is sent to the browser as a way to capture what is on the page, and what has been changed when the request is sent back to the browser. For ViewState to work, controls on the page need to be rendered with specifically named ID’s. This makes it difficult to use JavaScript to find elements on the page by their ID. For example adding a button to a page that is using an ASP.NET Master Page will render the following HTML:

Source code:

   1: <asp:Panel ID="Panel1" runat="server">
   2:     <asp:Button ID="btnClick" runat="server" Text="Button" />
   3: </asp:Panel>

Rendered HTML:

   1: <div id="MainContent_Panel1">    
   2:    <input type="submit" name="ctl00$MainContent$btnClick" 
   3:       value="Button" id="MainContent_btnClick" />    
   4: </div>


   1: <div class="aspNetHidden">
   2: <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
   3:    value="/wEPDwUJNjE3ODYxMzIwZGQjyMGaAJ/BFAzxJv1b+/lEXPaj4I/hCsdqNKZUozZiyw==" />
   4: </div>

If you notice you will see both the name and the id of the button has been changed to show that it is a child of the asp:Panel which is a child of the ASP.NET MasterPage. The ViewState in this example is fairly lean, but in large pages, it can become very large, and this is data the browser needs to download.

While this is all fine and dandy, trying to access these elements can be difficult, especially when trying to use jQuery’s selector mechanisims. You may think, that if you keep the name the same when traversing the DOM, will keep it good. But if for some reason the ID of the parent element changes in your code, then the names will change. There are some tricks you can use, but they are not the basis of this tutorial.

Now, let’s look at the same page when rendered with MVC:

Source code:

   1: <asp:Panel ID="Panel1" runat="server">
   2:     <input type="submit" value="button" />
   3: </asp:Panel>

Rendered HTML:

   1: <div id="MainContent_Panel1">    
   2:    <input type="submit" value="button" />    
   3: </div>

Now keep in mind that ASP.NET MVC does not typically use ASP.NET controls and in this example I am using a standard HTML input tag for the submit button.

The ASP.NET MVC Framework – What is it?

Now before we get into a big discussion about what is better and what is not, and all the underpinnings of “who moved my cheese”, MVC is yet another way to build web sites using the .NET Framework. It is a web application framework which implements the model-view-controller pattern of development. It is based on ASP.NET and allows the development of a web application to be built using three roles; Models – the data coming into and out the application, Views – the displayed pages, and Controllers – which handle the traffic coming in for HttpRequest and HttpResponse.

Microsoft released a CTP version of MVC in December, 2007, MVC version 1 in March 2009 and MVC version 2 in March 2010. They are currently working on version 3.

The default View engine for MVC is the Web Forms view engine and this view engine uses regular .aspx pages to design the layout of the user interaction pieces of the web site or web application. Instead of PostBacks any interactions are routed to the Controllers using a Routing mechanism.

A typical ASP.NET MVC application will have the following directory structure as seen in this figure:


As you can see there are folders for Controllers, Models, and Views. Look closely and you will see that the Controllers names are associated with the folders in the Views folder. AccountController maps to Views\Account while HomeController maps to Views\Home. Views that are shared throughout the application are saved in the Views\Shared folder.

Let’s take a look.


The first part of the application allows the user to look up a student by ID. As we can see from this screen shot the student with an ID of 1 is Jeanine Abbott. There are many steps involved in doing this using HTML, CSS and jQuery, so let’s dive in.

Index.aspx has the following code:

   1: <div class="row">
   2:     Find student by ID
   3:     <input type="text" id="studentId" value=""  class="studentId" />
   4:     <input type="button" id="btnAjax" value="Get Student" />
   5:     <img src="../../Content/Images/ajax-loader.gif" class="ajaxLoader" 
   6:          alt="ajaxloader" />
   7: </div>
   8: <div class="row">
   9:    <div class="errorMessage"></div>
  10:    <div class="studentData">
  11:     <table>
  12:         <thead>
  13:         <tr>
  14:             <th>First Name</th>
  15:             <th>Last Name</th>
  16:             <th>Email</th>
  17:             <th>Submit Date</th>
  18:             <th>Approved</th>
  19:             <th>Approved Date</th>
  20:         </tr>
  21:     </thead>
  22:     <tbody>
  23:         <tr>
  24:             <td class="studentFirstName"></td>
  25:             <td class="studentLastName"></td>
  26:             <td class="studentEmail"></td>
  27:             <td class="studentSubmitDate"></td>
  28:             <td class="studentApproved"></td>
  29:             <td class="studentApprovedDate"></td>
  30:         </tr>
  31:     </tbody>
  32:     </table>
  33:   </div>
  34: </div>

The next piece is in the HomeController where we have a method called GetStudent(int id)

   1: private readonly CourseEntities _db = ModelHelper.CourseEntities;
   2: public JsonResult GetStudent(int id)
   3: {
   4:     var student = (from s in _db.Students
   5:                    where s.Id.Equals(id)
   6:                    select s).FirstOrDefault();
   8:     if (student == null) 
   9:         return Json("error:Student not found.", JsonRequestBehavior.AllowGet);
  11:     var singleStudent = new SingleStudent
  12:         {
  13:             Id = student.Id,
  14:             FirstName = student.FirstName,
  15:             LastName = student.LastName,
  16:             Email = student.Email,
  17:             SubmitDate = student.SubmitDate.ToShortDateString(),
  18:             Approved = student.Approved.ToString(),
  19:             ApprovedDate = string.Empty
  20:         };
  22:     if(student.ApprovedDate.HasValue)
  23:         singleStudent.ApprovedDate = student.ApprovedDate.Value.ToShortDateString();
  25:     return Json(singleStudent, JsonRequestBehavior.AllowGet);
  26: }

The third piece of the puzzle is in the CSS. Looking at the ASPX code there are two div elements with classes of “studentData ” and “errorMessage”. In the CSS for this project these two classes have been defined as:

   1: div.studentData{display:none}
   2: div.errorMessage{display:none;color:Red;font-weight:bold;}

This makes these elements, and any elements contained within them to not be displayed when the page is first rendered.

The last piece to come into play is the JavaScript and jQuery. It is important to know that when adding your script references to your page, to make sure they are in the correct order. When you are going to use jQuery in your application and additional JavaScript files, the reference to jQuery needs to be first.

   1: <head id="Head1" runat="server">
   2:     <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
   3:     <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
   4:     <script src="../../Scripts/AppScripts.js" type="text/javascript"></script>
   5: </head>

I have written an additional JavaScript file, “AppScripts.js” and included it in the Scripts folder of the application. And by adding a reference to “jquery-1.4.1-vsdoc.js” to your additional JavaScript files, Visual Studio will provide jQuery Intellisense to make it easier reference the jQuery functions and attributes.

   1: /// <reference path = "/Scripts/jquery-1.4.1-vsdoc.js"/>
   3: $(document).ready(function () {
   4:     $("#btnAjax").click(function () { getStudent(); });    
   5: });

Going back to the first article in this series, you can see that when the document has been fully loaded into the DOM, with $(document).ready(), the element with the ID of “btnAjax” will have a click event assigned to it. The JavaScript function getStudent() is below.

   1: function getStudent(id) {
   2:     $("img.ajaxLoader").fadeIn(500);
   3:     $("div.errorMessage").fadeOut(500);
   4:     $("div.studentData").fadeOut(500);
   5:     $.ajax({
   6:         url: "/Home/GetStudent/" + $("#studentId").val(),        
   7:         type: "GET",
   8:         success: function (result) {
   9:             if (typeof (result) == "string" && result.indexOf("error:") > -1) {
  10:                 showError(result);
  11:             } else {
  12:                 showStudentData(result);
  13:             }
  14:         }
  15:     });
  16: }

Let’s step through this. Line 1 hides the ajaxLoader image, lines 2 and 3 hide the errorMessage and studentData div tags. Line 4 starts the jQuery ajax function by defining the url, the form action type, and what to do on a successful response. Because I am using a “GET” in the ajax code, I don’t have to include a <form> on the page. Looking back to the GetStudent(int id) method in the Controller, it is expecting a parameter of the type int to be passed in as well. This is done by getting the value of the text field which has an ID of “studentId”;

How the routing is setup with the application, the MVC framework will automatically cast the “1” to an int before it is passed into the method.

The GetStudent () method will take the ID passed in then select the student with a matching ID. If no student is found, GetStudent() will return a string, “error:Student not found.” If a student is found, then the method will return a Json object containing the data of the student.

Using Firebug for Firefox is a good way to see the data which is coming back from the Controller.

When an error is returned, in this case, the student was not found



When a student object is returned



The success attribute of the $.ajax function will check the type of the result coming back. If it is a string, the showError() function is called. If the type of the result coming back is an object, we know it is a JSON object and the showStudentData() function is called which will display the student’s data.

   1: function showError(result) {
   2:     var msg = result.split(":");
   3:     $("div.errorMessage").html(msg[1]).fadeIn(500);
   4:     $("img.ajaxLoader").fadeOut(500);
   5: }
   7: function showStudentData(student) {
   8:     $("td.studentFirstName").html(student.FirstName);
   9:     $("td.studentLastName").html(student.LastName);
  10:     $("td.studentEmail").html(student.Email);
  11:     $("td.studentSubmitDate").html(student.SubmitDate);
  12:     $("td.studentApproved").html(student.Approved.toLowerCase());
  13:     $("td.studentApprovedDate").html(student.ApprovedDate);
  14:     $("div.studentData").fadeIn(500);
  15:     $("img.ajaxLoader").fadeOut(500);
  16: }

Another example

In this project, I want to quickly approve a student for the current course. I could build an Edit Student form and approve them with that, but I don’t want to handle all of that overhead. All I want to do is click the Approved checkbox and go onto the next student.

I can do this by adding a click event to the checkboxes that have been rendered on the page with the following line of jQuery code.

   1: $("input[type=checkbox][name=Approved]").live("click", function () {
   2:     toggleStudentApproval($(this)); 
   3: });

Notice how I am using the “live” event to bind the click event to the checkboxes. What is cool about doing it this way is, the event will be bound to all selected elements now and in the future. So if the page is heavy with elements and long in loading, the $(document).ready() function may fire before all the elements have been rendered. You may also create new DOM elements with jQuery which won’t be available during $(document).ready(), so setting events with the .live() event is a good practice to start.

The JavaScript code:

   1: function toggleStudentApproval(elem) {
   2:     $(elem).siblings("img.ajaxLoader").fadeIn(500);
   3:     var approved = $(elem).attr("checked");
   4:     var studentId = $(elem).prev("input[type=hidden]").val();
   5:     $.ajax({
   6:         url: "/Home/SetStudentApproval/" + approved + "/" + studentId,
   7:         type: "GET",
   8:         success: function (result) {
   9:             showStudentApproval(result);            
  10:         }
  11:     });
  12: }

When the checkbox is clicked the code first shows the animated GIF, “ajaxLoader” that is a sibling of the checkbox. It then sets the variable “approved” to the “checked” attribute of the checkbox, then gets the value of the hidden field “studentId”. Line 6 shows the url which will be sent to the Controller, and line 9 shows the function to be called when the response is received. The request is then sent to the SetStudentApproval method in the Home Controller.

The Controller method, SetStudentApproval

   1: public JsonResult SetStudentApproval(bool approved, int id)
   2: {
   3:     var student = (from s in _db.Students
   4:                     where s.Id.Equals(id)
   5:                     select s).FirstOrDefault();
   7:     if (student == null)
   8:         return Json("error:Student not found.", JsonRequestBehavior.AllowGet);
  10:     student.Approved = approved;
  11:     student.ApprovedDate = DateTime.Now;
  12:     if (!approved)
  13:         student.ApprovedDate = null;
  14:     _db.SaveChanges();
  16:     var singleStudent = new SingleStudent
  17:     {
  18:         Id = student.Id,
  19:         FirstName = student.FirstName,
  20:         LastName = student.LastName,
  21:         Email = student.Email,
  22:         SubmitDate = student.SubmitDate.ToShortDateString(),
  23:         Approved = student.Approved.ToString()
  24:     };
  26:     if (student.ApprovedDate.HasValue)
  27:         singleStudent.ApprovedDate = student.ApprovedDate.Value.ToShortDateString();
  29:     return Json(singleStudent, JsonRequestBehavior.AllowGet);
  30: }

This method is the similar to the GetStudent method earlier in the article. For ease in reading, I copied it and added passing in the “approved” status, then passing back the student object to the JavaScript function.

The additional JavaScript functions

   1: function showStudentApproval(result) {
   2:     var id = result.Id;
   3:     var hid = getHiddenField(id);
   4:     var td = hid.parent("td").prev("td");
   5:     td.html("");
   6:     if (result.ApprovedDate != null)
   7:         td.html(result.ApprovedDate);
   8:     hid.siblings("img.ajaxLoader").fadeOut(500);
   9: }
  11: function getHiddenField(id) {
  12:     var hid;
  13:     $("input[type=hidden]").each(function () {
  14:         if ($(this).val() == id) {
  15:             hid = $(this);
  16:             return false;
  17:         }
  18:     });
  19:     return hid;
  20: }

The function showStudentApproval gets the Id of the student, then calls a helper function, getHiddenField to find the matching hidden field. This is so the table cell displaying the Approved Date can be found. The helper function gets an array of all hidden fields in the DOM, and uses the jQuery function .each() to loop through each one checking the value to see if it matches what was passed in. When it finds the correct element, the variable “hid” is set to the hidden field, then the looping is stopped. The hidden field is then sent back to the showStudentApproval function.

For ease, and since only the checkbox is visible, the hidden field, the checkbox and the animated GIF are all in the same table cell. Line 4 finds the table cell which is to the left of the cell holding these elements by traversing the DOM, looking first for the parent(), then parents previous sibling.


Line 5 shows that once you have a jQuery object in memory, you don’t have to use the $() syntax to refer to it again. This is a best practice, as using the $() to find elements which you already have in memory will lead to a degradation in performance.

Line 5 clears out the html of the table cell we found by traversing the DOM in line 4. Lines 6 and 7 set the html of the table cell to the student’s ApprovedDate.

Step 1


Step 2


Step 3


In this article we talked about some of the differences between a Web Forms application and a MVC application. Showed how to include jQuery files, and did some cool things with Ajax and jQuery to streamline an application’s functionality. In the next article, I will show you how to extend jQuery’s functionality with plugins.

Happy Programming,


jQuery and MVC–Part 1

By at October 27, 2010 07:27
Filed Under: JavaScript, MVC, jQuery

This is the first in a four-part series on using the JavaScript library jQuery with the ASP.NET MVC framework.


In the beginning there was static HTML and it was good. The World Wide Web was in its infancy and anyone with a computer, a text editor, an FTP program and a connection to the internet – more than likely dial-up – could create and publish web pages. But quickly these pages became boring, as they were after all, static, and web publishers began clamoring for something to make their pages zing.

Then along came a scripting language called JavaScript, and changed the way web pages and sites looked and acted, creating new ways to provide interactivity between the user and the web server. It was first released by Netscape as LiveScript in September 1995, and was renamed to JavaScript in December 1995 when it was included in the release of the Netscape browser.

As a programming language it is dynamic, weakly typed, prototype-based and supports closures and higher order functions. Not to be confused with the Java language it does have some similarities in its syntax with curly braces “{}” and semi-colons “;” and copies many names and naming conventions. However like Java, it does have a fairly steep learning curve. Because of this, JavaScript “scripts” started to become more and more popular on web development sites, allowing for easy copy and pasting. While this made JavaScript to quickly become one of the most popular languages for web development, in some circles it gained the reputation of being a “kiddie” language.

In 1999, Microsoft released the IXMLHTTPRequest interface as part of their Outlook Web Access for Microsoft Exchange Server. The Mozilla Foundation developed a wrapper to use this interface through a JavaScript object which was called XMLHttpRequest. In April, 2006 the World Wide Web Consortium published a working draft to “document a minimum set of interoperable features based on existing implementations, allowing Web developers to use these features without platform specific code”. The last revision to the specification was in November, 2009. (http://en.wikipedia.org/wiki/Xmlhttp)

With the advent of Ajax (Asynchronous JavaScript and XML) in 2005, JavaScript had begun to be looked on more favorably by the programming community, and as a more full-featured language.

The Pros and Cons

As with all languages there are many pros and cons, likes and dislikes, friends and foes. JavaScript is no different and some of the most common are:

Pros Cons
Easy to develop with and debug with the appropriate tools
Similar, comfortable syntax to Java, C#, C
Browsers seem to have their own JavaScript engine
Can be difficult to have the same behaviors act the same across browsers

The Development Experience

You get into the learning curve, and spend all your waking hours writing the most unique and elegant piece of JavaScript code, and test it in your favorite browser. It works just how you planned, until you open your site in a different browser. Ugh, events are different, you can’t seem to get to the correct DOM element, nothing just seems to work between browsers, let alone platforms. You pour over your trusty JavaScript manuals, scour forums, Google on Bing for obscure error messages, and generally get frustrated. You just feel like giving up, so what do you do?

JavaScript Libraries to the rescue

JavaScript libraries are pre-written snippets of code and controls which usually form a much larger JavaScript Framework. These libraries allow for the easier development of JavaScript intensive applications, as the majority of them handle the problems of cross-browser, cross-platform issues. Numerous libraries are available including, but not limited to, Dojo, Echo, Ext, Google Web Toolkit, jQuery, MochiKit, MooTools, Prototype, qooxdoo, Rico, script.aculo.us, Spry, and Yahoo! UI Library.

While each library has it’s good and bad points, it’s pros and cons, the rest of this series will focus the jQuery library, found at www.jquery.com


In January 2006 John Resig, released the first version of jQuery at BarCamp NYC, as a free, open source, dual-licensed (MIT and GNU) library. According to http://trends.builtwith.com, jQuery is the most popular JavaScript library; with 38.62% of web sites tested using some form of the code. Some of the main features of jQuery are:

  1. Its syntax makes it easier to navigate the DOM (Document Object Model)
  2. Easily handles and binds events to any DOM element
  3. Creates both simple and complex animations
  4. Has a complete suite of Ajax grooviness baked in
  5. Easy extensibility with plug-ins
  6. Unobtrusive
  7. Microsoft bundles jQuery with ASP.NET Web Applications and ASP.NET MVC

That’s right. Microsoft has jumped on the jQuery bandwagon, and gives it full support, even committing code back into source control. In fact, you can call Microsoft Support and get help with jQuery.


The learning curve for getting up to speed with jQuery is not terribly steep. In only a short time you can easily grok the basics, and in a few hours, do some really nifty things with jQuery.

The jQuery syntax is easy to learn with all statements starting off with a “$”. One of the cool things about jQuery is since other libraries may use the $ as well, to prevent collisions, you can use the literal “jQuery” instead. For example:

$(“some element”); or jQuery(“some element”);

DOM elements are selected by either their ID, or a className that has been assigned to them.

$(“#myElement”); returns the only ID in the DOM, “myElement”
$(“div.myElement”); returns all div elements having a class assigned of “myElement”

jQuery makes it very easy to traverse through the children of each element as well.

$(“div.main ul li”); returns all li tags within the div tag with a class of “main”


$(“div.main”).find(“li”); returns the same collection as above.

You can select specific elements in the collection with special selectors such as :odd, :even, :first, :last, :not(), etc.

     returns all odd (zero-based) li tags inside the div with a class of “main”

     returns all even (zero-based) li tags inside the div with a class of “main”

     returns the first li tag

     returns the last li tag

     returns all li tags that don’t have the “someDifferentClass” assigned to them

Unobtrusive JavaScript

How many times have we added our own “BLOCKED SCRIPTonclick(doSomething();)” code directly in our elements. It makes it difficult to maintain and debug, and rails against the philosophy of separation of concerns. jQuery helps us to get away from this by using selectors and assigning events to the elements we have found.

Additionally, unless you have written some really terrible jQuery/JavaScript, if there is an error in your jQuery syntax, jQuery will fail gracefully. This means there won’t be any pesky little JavaScript error icons in your browser or JavaScript console.


It is very easy to assign an event (click, focus, blur, etc.) to any DOM element with jQuery, and there are two main methods to do this.

The first is to wait until the DOM is fully loaded, which is checked by the jQuery event, .ready(). This event is fired when the DOM is complete and has been loaded into the memory of the browser.

$(document).ready(function() {
    $(“myElement”).click(function() { doSomething(); });

The second method is to attach a “live” event to the element with

$(“myElement”).live(“click”, function(){ doSomething(); });

The differences between these two methods are slight, but important. In the first example, we are assuming there will be an element called “myElement” in the DOM. This could be an element that is hard coded in the HTML, a button, text field, image, div or p tag. However, with jQuery’s dynamic DOM manipulation, it is possible that you would reference an element that has not been created yet.

The .live() event attaches the function you want to call to all matched elements in the selector, regardless of if they have or have not been created yet.

In the examples above, the “doSomething()” is referencing a separate JavaScript function. Another method is to replace the “doSomething()” with more jQuery functions.

$("ul.demo li:odd").each(function (index) {
     var targ = this;
     setTimeout(function () {
     }, index * 500);

jQuery functions can have standard JavaScript functions in them as well. Can you look at the code above and figure out what this event will do?

First, all of the odd li elements in the ul element with a className of “demo” are selected. Second, the jQuery .each() function loops through the collection, setting a brief timer. Third when the timer is hit, the li element has the class of “liSelected” assigned to it.

jQuery’s silent error handling will not show any indication of something going wrong, just since the element hasn’t been created it won’t be able to have the click event attached to it.


Once an element has been found, a reference to the element is kept in memory. So, instead of the following:


You can chain the actions like so:


This makes for much cleaner or succinct code writing and will help with memory as well.

Stuff you can do

As this series progresses, we will dive deeper into all the jQuery goodness. Here is a sampling:

  • Selectors – find elements in the DOM
  • Attributes – get/set attributes of found elements
  • Traversing – moving up/down elements in the DOM
  • Manipulation – get/set contents of found elements
  • CSS – get/set style attributes of found elements
  • Events – fire on click, hover, load, etc. of found elements
  • Effects – fadeIn/Out, slideIn/Out, hide/show
  • Ajax – full and complete Ajax capabilities
  • Utilities – inArray, isArray, makeArray, etc.


In closing the benefits of using jQuery are incredibly apparent. It is a solid, standardized JavaScript library, which allows for fast development, and gracefully fails with no glaring errors or frozen pages. Because of its popularity, there are lots and lots of examples, and it is very easy to get ramped up and understand its simplicity.

Check back next week when we will dive deeper into jQuery, and how you can easily spiff up your sites. Take a look at the attached demos, and send me some comments and questions.


About the author

James James is a five time and current Microsoft MVP in Client App Development, a Telerik Insider, a past Director on the INETA North America Board, a husband and dad, and has been developing software since the early days of Laser Discs and HyperCard stacks. As the Founder and President of the Inland Empire .NET User's Group, he has fondly watched it grow from a twice-a-month, early Saturday morning group of five in 2003, to a robust and rambunctious gathering of all types and sizes of .NET developers.

James loves to dig deep into the latest cutting edge technologies - sometimes with spectacular disasters - and spread the word about the latest and greatest bits, getting people excited about developing web sites and applications on the .NET platform, and using the best tools for the job. He tries to blog as often as he can, but usually gets distracted by EF, LINQ, MVC, ASP, SQL, XML, and most other types of acronyms. To keep calm James plays a mean Djembe and tries to practice his violin. You can follow him on twitter at @latringo.

And as usual, the comments, suggestions, writings and rants are my own, and really shouldn't reflect the opinions of my employer. That is, unless it really does.

James Twitter Feed

Recent Comments

Comment RSS

Month List