Server-Side Paging with jqxGrid, ASP.NET MVC 3 and SQL

If you haven't already installed ASP.NET MVC 3 use this resource: http://www.asp.net/mvc/mvc3 For this tutorial you're also going to need the Entity Framework: http://www.microsoft.com/download/en/details.aspx?id=18504
For our purpose we will use the Northwind database which you can download from here. So let's begin!

Create new ASP.NET MVC 3 project and choose the "Empty project" option for template. For "View engine" select "Razor".

New Project

  1. You have to load the database. Drag the files: "NORTHWND.LDF" and "NORTHWND.MDF" and drop them over the "App_Data" directory in your project. If there's no "App_Data" folder then right click on the white space in the "Solution Explorer" choose "Add -> Add ASP.NET Folder -> App_Data".

  2. Add all required JavaScript and CSS files. In the sample we added references to jqx-all.js, jqx.base.css and jqx.classic.css.
  3. Expand the "View" directory after that the "Shared" and double click on "_Layout.cshtml". Include references to the required javascript files. In this help topic, we use jqx-all.js and the CSS files: jqx.base.css and jqx.classic.css.
  4. In the next step we're going to create our Models. Now right click on the "Models" folder. Select "Add -> New Item". Choose "Data" from the tree view in left. Select "ADO.NET Entity Data Model" and click "Add".

    Add model

    In the "Choose Model Contents" section select "Generate from database" and click Next.

    Add model

    In the "Choose Your Data Connection" section click next. The the next section ("Choose Your Database Objects") check the "Tables" and "Stored Procedures" checkboxes and click "Finish".

    Add model

  5. For our purpose we are going to use the "Orders" table. To add entity objects and DbContext you have to expand the Models directory. Double click on "Model1.edmx". In the diagram appeared, right click on the white space and choose "Add Code Generation Item". In the tree view in left, select "Code", choose "ADO.NET DbContext Generator" and click "Add".

    Code generation item

  6. After that press F6 to Build your project.
  7. Now we are ready to add our Controller. Right click on the "Controller" folder and after that choose "Add -> Controller". Rename it "OrdersController". The choosen template should be "Controller with read/write actions and views, using Entity Framework". For Model class select "Customer (Project.Models)" and for Data context class "NORTHWNDEntities2 (Project.Models)" after that choose "Add".

    Controller

  8. After the generation of the controller have been completed go to the "Controllers" folder and double click on "OrdersController.cs". Add the following code:
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Project.Models;
    namespace Project.Controllers
    {
    public class OrdersController : Controller
    {
    private NORTHWNDEntities2 db = new NORTHWNDEntities2();
    //
    // GET: /Orders/
    public ViewResult Index()
    {
    var orders = db.Orders.Include(o => o.Customer).Include(o => o.Employee).Include(o => o.Shipper);
    return View(orders.ToList());
    }
    public JsonResult GetOrders(int pagesize, int pagenum)
    {
    var query = Request.QueryString;
    var dbResult = db.Database.SqlQuery<Order>(this.BuildQuery(query));
    var orders = from order in dbResult
    select new Order
    {
    ShippedDate = order.ShippedDate,
    ShipName = order.ShipName,
    ShipAddress = order.ShipAddress,
    ShipCity = order.ShipCity,
    ShipCountry = order.ShipCountry
    };
    var total = dbResult.Count();
    orders = orders.Skip(pagesize * pagenum).Take(pagesize);
    var result = new
    {
    TotalRows = total,
    Rows = orders
    };
    return Json(result, JsonRequestBehavior.AllowGet);
    }
    //
    // GET: /Orders/Details/5
    public ViewResult Details(int id)
    {
    Order order = db.Orders.Find(id);
    return View(order);
    }
    //
    // GET: /Orders/Create
    public ActionResult Create()
    {
    ViewBag.CustomerID = new SelectList(db.Customers, "CustomerID", "CompanyName");
    ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "LastName");
    ViewBag.ShipVia = new SelectList(db.Shippers, "ShipperID", "CompanyName");
    return View();
    }
    //
    // POST: /Orders/Create
    [HttpPost]
    public ActionResult Create(Order order)
    {
    if (ModelState.IsValid)
    {
    db.Orders.Add(order);
    db.SaveChanges();
    return RedirectToAction("Index");
    }
    ViewBag.CustomerID = new SelectList(db.Customers, "CustomerID", "CompanyName", order.CustomerID);
    ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "LastName", order.EmployeeID);
    ViewBag.ShipVia = new SelectList(db.Shippers, "ShipperID", "CompanyName", order.ShipVia);
    return View(order);
    }
    //
    // GET: /Orders/Edit/5
    public ActionResult Edit(int id)
    {
    Order order = db.Orders.Find(id);
    ViewBag.CustomerID = new SelectList(db.Customers, "CustomerID", "CompanyName", order.CustomerID);
    ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "LastName", order.EmployeeID);
    ViewBag.ShipVia = new SelectList(db.Shippers, "ShipperID", "CompanyName", order.ShipVia);
    return View(order);
    }
    //
    // POST: /Orders/Edit/5
    [HttpPost]
    public ActionResult Edit(Order order)
    {
    if (ModelState.IsValid)
    {
    db.Entry(order).State = EntityState.Modified;
    db.SaveChanges();
    return RedirectToAction("Index");
    }
    ViewBag.CustomerID = new SelectList(db.Customers, "CustomerID", "CompanyName", order.CustomerID);
    ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "LastName", order.EmployeeID);
    ViewBag.ShipVia = new SelectList(db.Shippers, "ShipperID", "CompanyName", order.ShipVia);
    return View(order);
    }
    //
    // GET: /Orders/Delete/5
    public ActionResult Delete(int id)
    {
    Order order = db.Orders.Find(id);
    return View(order);
    }
    //
    // POST: /Orders/Delete/5
    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {
    Order order = db.Orders.Find(id);
    db.Orders.Remove(order);
    db.SaveChanges();
    return RedirectToAction("Index");
    }
    protected override void Dispose(bool disposing)
    {
    db.Dispose();
    base.Dispose(disposing);
    }
    }
    }

    jqxGrid automatically passes the Sort, Page and Filter parameters(Read more about that here). The GetOrders method is built in a way that it returns only the necessary set of data depending on the "pagesize" and "pagenum" parameters. The data is ordered depending on the values of the "sortorder" and "sortdatafield" parameters.
  9. After that go to the "Views/Orders" folder in your project. Double click on "Index.cshtml". Put there the following content:
    <script type="text/javascript">
    $(document).ready(function () {
    // prepare the data
    var source = {
    datatype: "json",
    datafields: [{ name: 'ShippedDate', type: 'date' },
    { name: 'ShipName' },
    { name: 'ShipAddress' },
    { name: 'ShipCity' },
    { name: 'ShipCountry' }],
    url: 'Orders/GetOrders',
    root: 'Rows',
    beforeprocessing: function (data) {
    source.totalrecords = data.TotalRows;
    }
    };
    var dataadapter = new $.jqx.dataAdapter(source, {
    loadError: function (xhr, status, error) {
    alert(error);
    }
    });
    // initialize jqxGrid
    $("#jqxgrid").jqxGrid({
    source: dataadapter,
    autoheight: true,
    pageable: true,
    virtualmode: true,
    rendergridrows: function (obj) {
    return obj.data;
    },
    columns: [{ text: 'Shipped Date', datafield: 'ShippedDate', cellsformat: 'yyyy-MM-dd', width: 200 },
    { text: 'Ship Name', datafield: 'ShipName', width: 200 },
    { text: 'Address', datafield: 'ShipAddress', width: 180 },
    { text: 'City', datafield: 'ShipCity', width: 100 },
    { text: 'Country', datafield: 'ShipCountry', width: 140 }]
    });
    });
    </script>
    <h2>Index</h2>
    <div id="jqxgrid"></div>
  10. In the last step expand "Global.asax" and double click on "Global.asax.cs". Change the "RegisterRoutes" method to look like this:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    namespace Project
    {
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801
    public class MvcApplication : System.Web.HttpApplication
    {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
    filters.Add(new HandleErrorAttribute());
    }
    public static void RegisterRoutes(RouteCollection routes)
    {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute(
    "Orders", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Orders", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
    }
    protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    }
    }
    }
  11. Press F5 to run the project.
Press F5 and see the result: jqxGrid