Sunday 13 November 2011

Qtip integration with JqGrid in ASP.NET MVC


Introduction:
In this article I am going to demonstrate with code example how to integrate qtip with JqGrid in asp.mvc application. This is a generic implementation in a way that you simply set a custom property named “description” in ColModel  to whatever you want to display in tooltip such as text, images and server side data etc.
To understand this example effectively I will assume that you have the basic knowledge of JqGrid  (http://www.trirand.com/blog/), QTip (http://craigsworks.com/projects/qtip/)  and ASP.NET MVC (http://www.asp.net/mvc).

Create a new ASP.NET MVC Application:

In visual studio 2010 sp1 go to
File -> Project ->



Select “web” under Visual C# then choose ASP.NET MVC 3 Web Application and change the name of the solution to “JqGridWithQTipIntegration”.
In next step let the options selected as default with “Internet Application” and “view engine as .aspx”.
Click Ok button to create new asp.net mvc 3 web application.
After project creation you are going to have following hierarchy in solution explorer.

Build a custom Model for Demo:

In model folder in asp.net mvc web application add new classes named as “SomeEntity.cs” and “Repository.cs”.
SomeEntity.cs
  public class SomeEntity
    {
        public int Id { get; set; }
        public int IntProperty { get; set; }
        public string StringProperty { get; set; }
        public DateTime DateProperty { get; set; }
    }

Repository.cs
/// <summary>
    /// Trivial repository of random data for demo purposes. Not for use in a real application!
    /// </summary>
    public class Repository
    {
        private static IQueryable<SomeEntity> _data;

        public IQueryable<SomeEntity> SelectAll()
        {
            return _data;
        }

        /// <summary>
        /// Demo data is static so that we can demonstrate sorting with the same data for the whole lifetime of the application.
        /// </summary>
        static Repository()
        {
            var data = new List<SomeEntity>();
            var rand = new Random();
            for (int i = 0; i < 100; i++)
            {
                data.Add(new SomeEntity
                    {
                        Id = i,
                        IntProperty = rand.Next(99),
                        StringProperty = rand.Next(99).ToString(),
                        DateProperty = new DateTime(2000 + rand.Next(10), rand.Next(11) + 1, rand.Next(27) + 1)
                    });
            }
            _data = data.AsQueryable();
        }
    }

Add ActionMethod in HomeController that will return server side data for JqGrid:

Add following Action Method in Home Controller. This will return server side data to bind JqGrid which is of type Json and it will take parameters which JqGrid send with ajax request as shown below.
(link for jqgrid default parameters with ajax request)
public ActionResult GridDemoData(int page, int rows, string search, string sidx, string sord)
        {
            int currentPage = Convert.ToInt32(page) - 1;
            int totalRecords = 0;
            var repository = new Repository();
            var data = repository.SelectAll();
            totalRecords = data.Count();
            var totalPages = (int)Math.Ceiling(totalRecords / (float)rows);
            var jsonData = new
            {
                total = totalPages,
                page,
                records = totalRecords,

                rows = (
                           from m in data
                           select new
                           {
                               id = m.Id,
                               cell = new object[]
                                                                            {
                                                                            
                                                                                m.IntProperty,
                                                                                m.StringProperty,
                                                                                String.Format("{0:MM/dd/yyyy}", m.DateProperty)
                                                                            }
                           }).ToArray()
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);

        }

JqGrid and Qtip Setup Requirements:

You need to include following files in Site.Master to implement solution.
·         ui.jqgrid.css is used for jqgrid style and formatting
·         jquery-ui-1.8.custom.css used for style and formatting
·         jquery-1.5.1.min.js used for jquery framework
·         jquery-ui-1.8.7custom.min.js used for jquery ui like dialog etc.
·         grid.locale-en.js used for jqgrid localization
·         jquery.jqGrid.min.js required for jqgrid
<link href="<%= ResolveUrl("~/Content/themes/redmond/ui.jqgrid.css") %>" rel="stylesheet"
        type="text/css" />
    <link href="<%= ResolveUrl("~/Content/Site.css") %>" rel="stylesheet" type="text/css" />
    <link href="<%= ResolveUrl("~/Content/themes/redmond/jquery-ui-1.8.custom.css") %>"
        rel="stylesheet" type="text/css" />
    <script src="<%: Url.Content("~/Scripts/jquery-1.5.1.min.js") %>" type="text/javascript">
    </script>
    <script src="../../Scripts/jquery-ui-1.8.7custom.min.js" type="text/javascript"></script>
    <script src="../../Scripts/grid.locale-en.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery.jqGrid.min.js" type="text/javascript"></script>

Note: order of files included is important because if you change the order then JqGrid will not be operational.

JqGrid configuration:

Below is JavaScript and HTML code for JqGrid.
·         HTML elements added for JqGrid in Index.aspx
<table id="grid" cellpadding="0" cellspacing="0">
        </table>
        <div id="pager" style="text-align: center;">
        </div>
        <div id="search" style="margin-left: 30%; display: none">
        </div>

·         JavaScript code for JqGrid in Home.GridDemo.js
var lastsel;
$(function () {

    $("#grid").jqGrid({
        colNames: ['Int', 'String', 'Date'],
        colModel: [
                        { name: 'IntProperty', index: 'IntProperty', sortable: true,
                            editable: true, editoptions: { dataInit: ShowHint },
                            description: 'IntProperty tooltip goes here'
                        },
                        { name: 'StringProperty', index: 'StringProperty', sortable: true,
                            editable: true, editoptions: { dataInit: ShowHint },
                            description: 'StringProperty tooltip goes here'
                        },
                        { name: 'DateProperty', index: 'DateProperty', sortable: true,
                            editable: true, editoptions: { dataInit: ShowHint },
                            description: 'DateProperty tooltip goes here'
                        },
                      ],
        pager: $("#pager"),
        sortname: 'IntProperty',
        rowNum: 10,
        rowList: [10, 20, 50],
        sortorder: "",
        height: 300,
        imgpath: '/Content/jqGridCss/redmond/images',
        width: 800,
        url: "/Home/GridDemoData",
        datatype: 'json',
        mtype: 'GET',
        onCellSelect: function (rowid, iCol, aData) {


            if (rowid && rowid !== lastsel) {

                if (lastsel)
                    jQuery('#grid').jqGrid('restoreRow', lastsel);
                jQuery('#grid').jqGrid('editRow', rowid, true);
                lastsel = rowid;
            }
        }
    }).navGrid($("#pager"), { edit: true, add: false, del: false, search: false });
    $("#search").filterGrid($("#grid"), {
        gridModel: false,
        filterModel: [{
            label: 'Search',
            name: 'search',
            stype: 'text'
        }]
    });
});


Note that “description” is a custom property which contains text for tooltip and “ShowHint” method is called to display description text as a tooltip.

Generic Implementation of JqGrid integration with QTip:

Below is the code for JqGrid integration with Qtip in Helper.js
// this function show tool tip dialog for a certain element of jqgrid and assumes that jqgrid name is #grid
function ShowHint(elem) {
    var selector = '';

    if (this.gridName != null)
        selector = '#' + this.gridName;
    else if ($('#grid') != null) {
        selector = '#grid';

    }

    if (selector == '') {
        alert('jqgrid name is not "grid" or gridName "Edit Option" not set');
        return;

    }

    if (elem == 0)
        return;

    jQuery(elem).qtip({
        content: getColDescription(this.name, selector),
        show: 'focusin',
        hide: 'focusout',
        style:
    {

        name: 'red',
        tip: 'leftTop',
        textAlign: 'left',
        fontWeight: '500',
        fontSize: '11px'

    },
        position:
    {
        corner:
        {
            target: 'rightTop',
            tooltip: 'LeftTop'

        }
    }
    });
}

function getColDescription(colName, jqGridSelector) {
    var description = '';
    if (colName != '') {
        var colModel = $(jqGridSelector).getGridParam('colModel');
        $.each(colModel, function (index, model) {
            if (model.name == colName) {
                description = model.description;
                return false;
            }

        });
    }


    return description;
}

Web Page working Example:


You can download complete demo code with link provided.
http://code.google.com/p/jqgridwithqtipintegration/downloads/list