Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Saturday, August 7, 2010

The jQuery formula - Blocking UI and showing progress dialog across Ajax calls with Asp.Net MVC

This post in in continuation to my previous post where I create a progress dialog blocking the UI across asynchronous postbacks for WebForms. I will do the same thing here using Asp.Net MVC, except for the fact that there no such thing as postback in MVC, It’s all Get - Post -Put – Delete (a true web framework) . Much of the initial content will be common not identical.

The goal here is to not allow user to interact with the application, at the same time showing the user a dialog saying “Wait, let me first finish what you just asked me to do!”

The version of jQuery that I’m using is 1.4.1 (downloadable here) and the version of jQuery UI I’m using is 1.8.2(downloadable here). I’ll be using ASP.NET MVC 2.0 but this demo is valid for any web framework which allows making Ajax calls using jQuery.

The source code for this demo can be downloaded here.

Plugging in jQuery UI in to a new ASP.NET web application:

Well start with creating a new web application using Visual Studio 2010:

The application template by default contains the jQuery scripts in the /Scripts folder (I deleted the files non-relevant to this demo to minimize solution size).  jQueryUI scripts and CSS is required to be downloaded and include it in the solution via the following entries in the master page:

    <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>    
    <script src="../../Scripts/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script>
    <link href="../../Content/jQueryUI/redmond/jquery-ui-1.8.2.custom.css" rel="stylesheet" type="text/css" />

Creating a jQuery UI dialog with the content to show

We need to create two methods one to open the jQuery dialog and the other to close it. With the intention to keep all related javascript in one place and out of the .aspx pages, I created a new JScript file called jqueryProgressDialog.js, placed it in the Scripts folder and create two methods in it:

function showProgressDialog() {

    $("#progressDialog").dialog({
        autoOpen: false,
        modal: true,
        bgiframe: true
    });

    $('#progressDialog').dialog('open');

}

function hideProgressDialog() {

    if ($('#progressDialog').dialog('isOpen')) {

        $('#progressDialog').dialog('close');
    }
}

And include this script file in our master page -

    <script src="../../Scripts/jqueryProgressDialog.js" type="text/javascript"></script>

What will be shown in the dialog box will be defines using a DIV tag with id = “progressDialog”. We will put this in the Master Page so that it is available to the while application.

    <div id="progressDialog" title="Welcome to my demo!" style="display: none;">
        <img src="../../Images/AjaxProgress.gif" alt="Processing"/>
        <p>
            Please wait while your request is processed.
        </p>
    </div>

Obviously this solution will not work for the pages that do not  inherit from this master page.

 

Calling the progress dialog while asynchronous request

To consume this infrastructure, we need to add specify out show and hide dialog functions to the start and end of a request. You can either surpass the framework’s Ajax helpers and go the jquery way making Ajax calls -

The View -

    <p>
        <input type="button" value="Click here to for a 2 seconds long asynch call" onclick="makeAnAjaxCall();" />
    </p>

    <script type="text/javascript">

        function makeAnAjaxCall() {

            $.ajax({
                type: "GET",
                url: '<%= Url.Action("SleepFor2Seconds", "Home") %>',
                data: "{}",
                cache: false,
                beforeSend: showProgressDialog,
                complete: hideProgressDialog
            });
        }
    
    </script>

The Controller:

        public bool SleepFor2Seconds()
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            return true;
        }

Or go with the framework infrastructure for secure posting your forms.

The View -

    <div>
        <% using (Ajax.BeginForm(new AjaxOptions()
                                 {
                                     HttpMethod = "post",
                                     OnBegin = "showProgressDialog",
                                     OnComplete = "hideProgressDialog"
                                 }
                     ))
           {%>
        <fieldset>
            <legend>Some form</legend>
            <p>
                FirstName:
                <%= Html.TextBox("FirstName", "FirstName")%>
            </p>
            <p>
                LastName:
                <%= Html.TextBox("LastName", "LasName")%>
            </p>
            <%= Html.AntiForgeryToken()%>
            <p>
                <input type="submit" value="Click here to Asynchronously post this form" />
            </p>
        </fieldset>
        <% } %>
    </div>

NOTE: For the Ajax.BeginForm to work the helper script files MicrosoftAjax.js and MicrosoftMvcAjax.js are required.

    <script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

The Controller actions:

        [HttpGet]
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(FormCollection formcollection)
        {
            Thread.Sleep(TimeSpan.FromSeconds(1));
            return View();
        }

In either case, here’s the result:

jQueryProgressDialog_MVC

Friday, August 6, 2010

The jQuery formula - Blocking UI and showing progress dialog across asynchronous postbacks with ASP.NET Web Forms.

The goal here is to not allow user to interact with the application, at the same time showing the user a dialog saying “Wait, let me first finish what you just asked me to do!” The version of jQuery that I’m using is 1.4.1 (downloadable here) and the version of jQuery UI I’m using is 1.8.2(downloadable here). I’ll be using ASP.NET 4.0 Web forms but this demo is valid for pervious version with compatible ASP.NET AJAX (AKA Microsoft Ajax) version available.

The source code for this demo can be downloaded here.

Plugging in jQuery UI in to a new ASP.NET web application:

Well start with creating a new web application using Visual Studio 2010:

The application template by default contains the jQuery scripts in the /Scripts folder (I deleted the files non-relevant to this demo to minimize solution size).  jQueryUI scripts and CSS is required to be downloaded and include it in the solution via the following entries in the master page:

    <link href="Styles/jQueryUI/redmond/jquery-ui-1.8.2.custom.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script>

Creating a jQuery UI dialog with the content to show

We need to create two methods one to open the jQuery dialog and the other to close it. With the intention to keep all related javascript in one place and out of the .aspx pages, I created a new JScript file called jqueryProgressDialog.js, placed it in the Scripts folder and create two methods in it:

function showProgressDialog() {

    $("#progressDialog").dialog({
        autoOpen: false,
        modal: true,
        bgiframe: true
    });

    $('#progressDialog').dialog('open');

}

function hideProgressDialog() {

    if ($('#progressDialog').dialog('isOpen')) {

        $('#progressDialog').dialog('close');
    }
}

And include this script file in our master page -

    <script src="Scripts/jqueryProgressDialog.js" type="text/javascript"></script>

What will be shown in the dialog box will be defines using a DIV tag with id = “progressDialog”. We will put this in the Master Page so that it is available to the while application.

    <div id="progressDialog" title="Welcome to my demo!" style="display: none;">
        <img src="Images/AjaxProgress.gif" alt="Processing"/>
        <p>
            Please wait while your request is processed.
        </p>
    </div>

Obviously this solution will not work for the pages that do not  inherit from this master page.

 

Calling the progress dialog while asynchronous request

To complete the infrastructure, we need to add an instance of  ScriptManager to the master page.

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>

and use the methods exposed by PageRequestManager to specify the client side javascript methods that will be executed with the request start and end.

The PageRequestManager is a client side class that exposes events and functions to manipulate the asynchronous post back using the Script Manager. The intelessence support will be available if an instance of Scriptmanager or ScriptManagerProxy is available on the page. The methods exposed by the PageRequestManager are worth exploring if you are working extensively with Asp.Net Ajax.

PageRequestManager

To hook-up the progress dialog start stop function, we will add the following lines of script to our jqueryProgressDialog.js file (so that all the javascript code related to the dialog is at one place):

$(document).ready(function () {

    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(showProgressDialog);
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(hideProgressDialog);
});

With that the infrastructure is complete, now we need to see it work!

And to do that I will create an update panel on the home page and add a simple button in it to invoke a postback.

    <asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="true" UpdateMode="Always">
        <ContentTemplate>
            <p>
                <asp:Button ID="Button1" runat="server" Text="Click here to for a 2 second asynch postback"
                    OnClick="Button1_Click" />
            </p>
        </ContentTemplate>
    </asp:UpdatePanel>

Code behind -

        protected void Button1_Click(object sender, EventArgs e)
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
        }

And guess what showed up -

jQueryProgressDialog

 

After introduced to the ASP.NET MVC framework, it has been the framework of choice to me. So if you do not like server side ajax or (like me) prefer MVC over web forms –here’s the same trick with the MVC framework!

Thursday, February 11, 2010

Debugging Java Script in Visual Studio

Solution in the post is tested on Visual Studio 2008 & Visual Studio 2010
The best location to place java script in an ASP.NET application will be to put in a custom Java script file, conventionally “common.js” or “[appName].custom.js”.
However, it’s not always possible to do this as we sometimes need to access the client IDs of the server controls and our javascript code end up looking like this:
var submitButton = document.getElementById("<%= Button1.ClientID %>");
var name = $("#" + "<%= NameLabel.ClientID %>").text(); //using jQuery

We need to place such code in the .aspx or .ascx files within the script tags. There are a couple of ways in which we can debug either of them in Visual Studio.
NOTE: For the solutions mentioned below to work, we need to uncheck the disable script debugging in the Internet Explorer settings. Also this solution works only with Internet Explorer. We always have the option to fire the bug and go crazy!

A very quick and handy way the works very well in the development phase is using the debugger; command.
The debugger; command is frowned upon by some as the whole idea of making a change in the code in order to debug sounds odd. The good thing about debugger is that we can place this in the “onload” and “oninit” handlers or $(document).ready() and expect the control to. This would work every where, whether within a script block on a page or in the custom .js file.

Refer to the example below:

<%@ Page language="C#" autoeventwireup="true" codebehind="Default.aspx.cs" inherits="DebuggingJS._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Debugging Java Script</title>
    <script src="Scripts/jquery-1.3.2.min-vsdoc.js" type="text/javascript"></script>
    <script src="Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
</head>
<body onload="client_Load()">
    <form id="form1" runat="server">
    <script type="text/javascript">
    
        function client_Load() {

            debugger;

            var text = $("#" + "<%= Label1.ClientID %>").html();
            $("#" + "<%=Label1.ClientID %>").html(text + "<br />client_Load()called!");
        }

        $(document).ready(function() {
        
            debugger;

            var text = $("#" + "<%= Label1.ClientID %>").html();
            $("#" + "<%= Label1.ClientID %>").html(text + "<br />$(document).ready() called!");
        });

    </script>
    <div>
        <asp:label runat="server" id="Label1"></asp:label>
    </div>
    </form>
</body>
</html>

Word of caution - This command needs to be deleted before you check-in or publish, for obvious reasons.

On a side note, if you see what the script is doing, $(document).ready() is fired before body tag’s onload is being fired on my machine.

Another option the Visual studio provides us - The visual studio style debugging:
Run a web application in Debug Mode, check out the solution Explorer:
The Windows Internet Explorer node gives the response that the application will send to the browser. This includes rendered HTML (localhost file in the image), java script files and other resource files.
So what do we have to do if the script is sitting in a separate .js file?
Well NOTHING!
Just put a brake point as we always do and run the application in debug mode.


And we can expect the obvious result.

However, it’s worth noticing that the java script that hits the breakpoint is in the Windows Internet Explorer node.

In case of java script in the .aspx/.ascx files:
Open the rendered page in Windows Internet explorer node, spot the code that needs to be debugged and put a break point on it.
You’re all set!
Hit refresh, if it’s a page load / document ready handler or take the user action needed, Visual studio will be sure to stop on the debug point.

Not just that, you can check value or variables just like you quick watch and add watch.
This comes like a blessing if you are working with a third party control and looking to find out an exhaustive list of client side APIs.
Just like I’m blessed with the Telerik’s RAD Grid’s client side methods and properties below:
You get the exhaustive client side method and properties at one place.
How neat is that!

Friday, June 26, 2009

jQuery UI Dialog in jQuery Grid (jqGrid) with ASP.NET MVC

This post is in continuation with my previous post where we created an ASP.NET MVC with JQgrid. Also, as we will be using the same solution on which we worked in the last post. Versions used –

  • jQuery – 1.3.2
  • jqGrid – jqGrid 3.5 ALFA 3.
  • jQuery UI 1.7.1

The source code of the demonstration can be downloaded here.

A jQuery Dialog box is just HTML markup tags that sit in DIV tag inside your page. This DIV tag is made invisible to the user when the user is on the page by style="display:none" attribute. This is done obviously because the user need to see this content in a dialog box only when it is invoked. Let’s start with including jQuery script files to the solution. It can be downloaded from here. I’ve added the jQuery UI scripts in a subfolder called “jQueryUI” within the Scripts folder. Now open the solution and go to Index.aspx where we have the jqGrid. On this page copy paste the following HTML tags in the MainContent place holder (it is not important where you put this tag on the page):

<div id="detailsDialog" style="display:none" title="Movie Details">    
    <table>
        <tr>
            <td><h2 id="movieName"></h2></td>
            <td>
                <img id="movieImage" src="" alt=""/>
            </td>
        </tr>
        <tr>
            <td>Director</td>
            <td id="director"></td>
        </tr>
        <tr>
            <td>Release Date</td>
            <td id="releaseDate"></td>
        </tr>
        <tr>
            <td>IMDB User Rating</td>
            <td>
                <a id="iMDBUserRating" target="_blank" href=""></a>
            </td>
        </tr>
        <tr>
            <td>Plot</td>
            <td id="plot"></td>
        </tr>
    </table>
    </div>
This is the set of tags that will be run by the Dialog box. Also for that we need to import the following scripts on the page: 
<script src="<%= this.ResolveClientUrl("~/Scripts/jQueryUI/ui.core.js") %>" type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Scripts/jQueryUI/ui.draggable.js") %>" type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Scripts/jQueryUI/ui.resizable.js") %>" type="text/javascript"></script>
<script src="<%= this.ResolveClientUrl("~/Scripts/jQueryUI/ui.dialog.js") %>" type="text/javascript"></script>
Now we have the tags ready, we need some jQuery to dynamically put data in there. The jqGrid that we are using has some events associated to it like “onSortCol”, “ondblClickRow” etc. For details on these events please refer to the documentation here. The event that we will use here will be onSelectRow. As the name suggests the event will be fired when the user clicks on a row and we will create a handler for the event. Let the name of the handler be – ShowMovieDetails. The Event with the handler needs to be added to the jqGrid’s properties:
onSelectRow: ShowMovieDetails 
Please note that ShowMovieDetails is not proceeded by the parenthesis “()”. Doing so will actually execute the function. In order to assign but not execute we drop the parenthesis. This event, when fired, sends the value of the selected row number to the handler as a parameter. In our scenario the handler needs to do the following this: 1. Create a dialog box, 2. Set the values dynamically in the DIV based on the row selected. 3. Show the dialog box. To achieve this we will use a method in jqGrid to get the cell value of the grid. This method is – getCell(rowId, columnId). This can be invoked as - $(<jqGridSelector>).getCell(rowId, colId). Here’s the handler for our purpose:
function ShowMovieDetails(rowid) {

    $('#detailsDialog').dialog({
        autoOpen: false,
        width: 550,
        height: 400,
        modal: true
    });

    $("#movieName").text($("#list").getCell(rowid, 1));
    
    $("#movieImage").attr("src", $("#list").getCell(rowid, 6));
    $("#movieImage").attr("alt", $("#list").getCell(rowid, 1));
    
    $("#director").text($("#list").getCell(rowid, 2));

    $("#releaseDate").text($("#list").getCell(rowid, 3));

    $("#iMDBUserRating").text($("#list").getCell(rowid, 4));
    $("#iMDBUserRating").attr("href", "http://www.imdb.com/find?s=tt&q=" + $("#list").getCell(rowid, 1))

    $("#plot").text($("#list").getCell(rowid, 5));

    $('#detailsDialog').dialog('open');
}
Please take note of the properties in the dialog. If you do not use the dialog('open') method separately to open the dialog box, the dialog box will open but only for the first time. Subsequent selection of rows will have no response. To mitigate this, we declared the dialog with autoOpen as false and open the dialog box separately using dialog('open'). Now go ahead and run the application for gratification. This is what shows up: There many methods attached to the Dialog Box. We can make this as an editable form of the data in the grid row and have buttons on the dialog box making Ajax call to execute CRUD operation. Also, pagination can be added to it in order to move from one row details to the next or previous one. That will actually complete the DetailsView data control using jQuery. You may explore the exposed methods here.

Thursday, May 7, 2009

jQuery Grid plug-in (jqGrid) with ASP.NET MVC

jqGrid is a great plug-in, making good use of jQuery. jqGrid can be downloaded here and the documentations can be found here. We will shortly see how to use this plug-in in ASP.NET MVC application. Versions used –

  • jQuery – 1.3.2
  • jqGrid – jqGrid 3.5 ALFA 3.

The source code of the demonstration can be downloaded here.

To get started, we create a new ASP.NET MVC Web Application.

When you create an ASP.NET MVC application the jQuery scripts get included automatically.

Since I am not using a database for this example I have created a code file called “Movies.cs” in the “Models” folder which will return a list of Movies. If you are using LINQ to SQL with you Database table the grid paging becomes easier, which we will discover shortly. So here are the two classes that I put in “Movies.cs”:
using System;
using System.Collections.Generic;
using System.Linq;


namespace jQueryMVC.Models {

    public class Movie {

        public int? Id { get; set; }
        public string Name { get; set; }
        public string Director { get; set; }
        public DateTime ReleaseDate { get; set; }
        public string IMDBUserRating { get; set; }
        public string Plot { get; set; }
        public string ImageURL { get; set; }
    }

    public class Movies {
        public List<Movie> GetMovies() {

            List<Movie> movies = new List<Movie>();

            movies.Add(new Movie() { Id = 1, Name = "Iron Man", Director = "Jon Favreau", ReleaseDate = new DateTime(2008, 5, 2), IMDBUserRating = "8.0/10", Plot = "When wealthy industrialist Tony Stark is forced to build an armored suit after a life-threatening incident, he ultimately decides to use its technology to fight against evil.", ImageURL = @"Images/IronMan.jpg" });
            movies.Add(new Movie() { Id = 2, Name = "Slumdog Millionaire", Director = "Danny Boyle, Loveleen Tandan ", ReleaseDate = new DateTime(2008, 1, 23), IMDBUserRating = "8.5/10", Plot = "A Mumbai teen who grew up in the slums, becomes a contestant on the Indian version of 'Who Wants To Be A Millionaire?' He is arrested under suspicion of cheating, and while being interrogated, events from his life history are shown which explain why he knows the answers.", ImageURL = @"Images/SlumdogMillionaire.jpg" });
            movies.Add(new Movie() { Id = 3, Name = "The Dark Knight", Director = "Christopher Nolan", ReleaseDate = new DateTime(2008, 7, 18), IMDBUserRating = "9.0/10", Plot = "Batman, Gordon and Harvey Dent are forced to deal with the chaos unleashed by an anarchist mastermind known only as the Joker, as it drives each of them to their limits", ImageURL = @"Images/TheDarkKnight.jpg" });
            movies.Add(new Movie() { Id = 4, Name = "The Wrestler", Director = "Darren Aronofsky", ReleaseDate = new DateTime(2008, 1, 30), IMDBUserRating = "8.4/10", Plot = "A faded professional wrestler must retire, but finds his quest for a new life outside the ring a dispiriting struggle.", ImageURL = @"Images/TheWrestler.jpg" });
            movies.Add(new Movie() { Id = 5, Name = "The Curious Case of Benjamin Button", Director = "David Fincher", ReleaseDate = new DateTime(2008, 12, 25), IMDBUserRating = "8.2/10", Plot = "Tells the story of Benjamin Button, a man who starts aging backwards with bizarre consequences.", ImageURL = @"Images/TheCuriousCase.jpg" });
            movies.Add(new Movie() { Id = 6, Name = "Frost/Nixon", Director = "Ron Howard", ReleaseDate = new DateTime(2008, 1, 23), IMDBUserRating = "8.0/10", Plot = "A dramatic retelling of the post-Watergate television interviews between British talk-show host David Frost and former president Richard Nixon.", ImageURL = @"Images/FrostNixon.jpg" });
            movies.Add(new Movie() { Id = 7, Name = "WALL-E", Director = "And9ew Stanton", ReleaseDate = new DateTime(2008, 6, 27), IMDBUserRating = "8.6/10", Plot = "In the distant future, a small waste collecting robot inadvertently embarks on a space journey that will ultimately decide the fate of mankind.", ImageURL = @"Images/WallE.jpg" });
            movies.Add(new Movie() { Id = 8, Name = "Man on Wire", Director = "James Marsh", ReleaseDate = new DateTime(2008, 8, 1), IMDBUserRating = "8.1/10", Plot = "A look at tightrope walker Philippe Petit's daring, but illegal, high-wire routine performed between New York City's World Trade Center's twin towers in 1974, what some consider, 'the artistic crime of the century.'", ImageURL = @"Images/ManOnWire.jpg" });
            movies.Add(new Movie() { Id = 9, Name = "Milk", Director = "Gus Van Sant", ReleaseDate = new DateTime(2008, 1, 8), IMDBUserRating = "8.0/10", Plot = "The story of Harvey Milk, and his struggles as an American gay activist who fought for gay rights and became California's first openly gay elected official.", ImageURL = @"Images/Milk.jpg" });
            movies.Add(new Movie() { Id = 10, Name = "Tropic Thunder", Director = "Ben Stiller", ReleaseDate = new DateTime(2008, 8, 13), IMDBUserRating = "7.3/10", Plot = "Through a series of freak occurrences, a group of actors shooting a big-budget war movie are forced to become the soldiers they are portraying.", ImageURL = @"Images/TropicThunder.jpg" });

            return movies;
        }
    }
}
I have created an “Images” folder and put a small image related to every movie in there. The way the data and the images are handled is not the best way to use it, but the purpose is to get some data and the focus is on the use of jqGrid. With that disclaimer download the jqGrid JavaScript source files (including the scripts in the “plugins” folder) with the themes and add in to the “Scripts” and “Content” folders respectively.

Please note that we have not included the jquery.js file that comes along with the plug-in as it is available with ASP.NET MVC in Visual Studio. Since we named the JavaScript source for jqGrid as “jqGridJs” to keep the plug-in source separate, we need to change the path in the file “jquery.jqGrid.js”. All we need is to change the value of the variable pathtojsfiles as shown below:

Include the jQuery script “jquery-1.3.2.js” in the master page – “Site.Master”
<script type="text/javascript" src="<%= this.ResolveClientUrl("~/Scripts/jquery-1.3.2.js") %>"></script>

We will be creating the grid in the home/Index view, so copy the following HTML tags in “Views/ Home/ Index.aspx”:
<table id="list" class="scroll"></table>
    <div id="pager" class="scroll" style="text-align:center;"></div> 
Also import the CSS file and script files in the view:
<link href="/Content/jqGridCss/ui.jqgrid.css" rel="stylesheet" type="text/css" />
    <link href="/Content/jqGridCss/redmond/jquery-ui-1.7.1.custom.css" rel="stylesheet" type="text/css" />

    <script src="<%= this.ResolveClientUrl("~/Scripts/jquery.jqGrid.js") %>" type="text/javascript"></script>
    <script src="<%= this.ResolveClientUrl("~/Scripts/jqGridJs/jqModal.js") %>" type="text/javascript"></script>
    <script src="<%= this.ResolveClientUrl("~/Scripts/jqGridJs/jqDnR.js") %>" type="text/javascript"></script>
Please note that the order in which the JavaScript files are included is important. Now copy the following code in the same view, after the above declarations. This is the function which is responsible of creating the grid on the client’s side.
<script type="text/javascript">
        jQuery(document).ready(function() {
            jQuery("#list").jqGrid({
            url: '/Home/GetMovieData/',
                datatype: 'json',
                mtype: 'GET',
                colNames: ['id', 'Movie Name', 'Directed By', 'Release Date', 'IMDB Rating', 'Plot', 'ImageURL'],
                colModel: [
                  { name: 'id', index: 'Id', width: 55, sortable: false, hidden: true },
                  { name: 'Movie Name', index: 'Name', width: 250 },
                  { name: 'Directed By', index: 'Director', width: 250, align: 'right' },
                  { name: 'Release Date', index: 'ReleaseDate', width: 100, align: 'right' },
                  { name: 'IMDB Rating', index: 'IMDBUserRating', width: 100, align: 'right' },
                  { name: 'Plot', index: 'Plot', width: 55, hidden: true },
                  { name: 'ImageURL', index: 'ImageURL', width: 55, hidden: true}],
                pager: jQuery('#pager'),
                rowNum: 5,
                rowList: [5, 10, 20],
                sortname: 'id',
                sortorder: "desc",
                height: '100%',
                width: '100%',
                viewrecords: true,
                imgpath: '/Content/jqGridCss/redmond/images',
                caption: 'Movies from 2008'
            });
        });
    </script>
Take a look at the script, the colNames show the name of the column which will be shown to the user. The colModel shows the details of the rendering of the columns. The index is the value which will be sent to the server as the parameter to sort with.
Also the “datatype” specifies that the script is expecting json data from the url “/Home/GetMovieData/”. So now, we need to create the action GetMovieData in the home controller.

This controller needs to return json data in a specific format. To read the details, please refer the documentation here. Thanks to the Json helper method in the Controller class, you need not worry about it.

Create the following action in the Home Controller:
public ActionResult GetMovieData() {

            #region JQGrid Params
            string sortColumn = (Request.Params["sidx"]).ToString();
            string sortOrder = (Request.Params["sord"]).ToString();
            int pageIndex = Convert.ToInt32(Request.Params["page"]);    //Remember this is NOT 0 based
            int rowCount = Convert.ToInt32(Request.Params["rows"]);
            #endregion

            Movies movies = new Movies();
            var movieList = movies.GetMovies();

            int totalRecords = movieList.Count();
            int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rowCount);

            var jsonData = new {

                total = totalPages,
                page = pageIndex,
                records = totalRecords,
                rows = (
                    from m in movieList
                    select new {
                        i = m.Id,
                        cell = new string[] {
                        m.Id.Value.ToString(), m.Name, m.Director, m.ReleaseDate.ToShortDateString(), m.IMDBUserRating, m.Plot, m.ImageURL
                        }
                    }
                ).ToArray()
            };
            return Json(jsonData);
        }
One thing to notice here is that the name of the query string parameters are defined by the JQGrid. Now run the application and you should be able to see something like this: Our work here is almost done, well… almost, as the paging and sorting is not working yet.

Now depending on what you are using for data access, you will have to write a method to take the parameters received from the grid and sort it.

If you are using LINQ to SQL, all you need to do is add the following lines in your GetMovieData action just before selecting jsonData:
var finalList = movieList
                .OrderBy(sidx + " " + sord)
                .Skip(pageIndex * rows)
                .Take(rows);
But since the OrderBy method taking string variables is not available here, we will create a method to take care of that. Add the following Sort method in the Movies Class:
public List<Movie> Sort(List<Movie> list, string sortColumn, string sortOrder) {

            int order;

            if (sortOrder == "desc")
                order = -1;
            else
                order = 1;


            switch (sortColumn) {
                case "Name":
                    list.Sort(
                         delegate(Movie m1, Movie m2)
                         { return m1.Name.CompareTo(m2.Name) * order; } );
                    break;

                case "Director":
                    list.Sort(
                         delegate(Movie m1, Movie m2)
                         { return m1.Director.CompareTo(m2.Director) * order; });
                    break;

                case "ReleaseDate":
                    list.Sort(
                         delegate(Movie m1, Movie m2)
                         { return m1.ReleaseDate.CompareTo(m2.ReleaseDate) * order; });
                    break;

                case "IMDBUserRating":
                    list.Sort(
                         delegate(Movie m1, Movie m2)
                         { return m1.IMDBUserRating.CompareTo(m2.IMDBUserRating) * order; });
                    break;
            }

            return list;
        }
If you are using multiple grids in your application with the same typed list, it will be a good idea to create it as an extension function. No we will just make some changes in the action to make a call to this method. The final version of the action will look like this:
public ActionResult GetMovieData() {

            #region JQGrid Params
            string sortColumn = (Request.Params["sidx"]).ToString();
            string sortOrder = (Request.Params["sord"]).ToString();
            int pageIndex = Convert.ToInt32(Request.Params["page"]);
            int rowCount = Convert.ToInt32(Request.Params["rows"]);
            #endregion

            Movies movies = new Movies();
            var movieList = movies.GetMovies();

            int totalRecords = movieList.Count();
            int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rowCount);

            var finalList = movies.Sort(movieList, sortColumn, sortOrder)
                                    .Skip((pageIndex - 1) * rowCount)
                                    .Take(rowCount);

            var jsonData = new {

                total = totalPages,
                page = pageIndex,
                records = totalRecords,
                rows = (
                    from m in finalList
                    select new {
                        i = m.Id,
                        cell = new string[] {
                        m.Id.Value.ToString(), m.Name, m.Director, m.ReleaseDate.ToShortDateString(), m.IMDBUserRating, m.Plot, m.ImageURL
                        }
                    }
                ).ToArray()
            };
            return Json(jsonData);
        }
Now our jqGrid is implemented. There are many more functionalites and tweaks in the plug-in like java script based CRUD operations and search operations that can be easily integrated into this code with the help of the jqGrid documentation.

At this point you might be wondering what was the point putting Images and Plot in the Movie class and why did we put it in the hidden columns in the grid. You can completely ignore that for now as that is something I’ll be using in my next blog when we will implement jQuery UI dialog box on grid’s action.

Good Luck!