Jasinski Technical Wiki

Navigation

Home Page
Index
All Pages

Quick Search
»
Advanced Search »

Contributor Links

Create a new Page
Administration
File Management
Login/Logout
Your Profile

Other Wiki Sections

Software

PoweredBy

Page History: Quick Reference - jqGrid

Compare Page Revisions



« Older Revision - Back to Page History - Newer Revision »


Page Revision: Tue, Oct 30, 2012, 10:29 AM


This page is a Draft. Its content is not complete and might contain errors.

Client Side

UI Code

<div id="uxUserGridDiv"><table id="uxUserGrid"></table></div>
<div id="uxUserGridPager"></div>

Alternate
<input type="button" class="newItemButton" id="btnNewNote" onclick="newNote(@Model.ContactID);" value="New Note" /><br />
<div id="gridNotes"><table id="jqgridNotes"></table></div>
<div id="pagerNotes"></div>

To generate this code programmatically, see jQuery-UI Tab Code Generator

JavaScript Code

/*===============================================================================================*/
$(document).ready(function () {

    loadUserGrid();

});
/*===============================================================================================*/
function loadUserGrid() {

    $("#uxUserGrid").GridUnload();

    $("#uxUserGrid").jqGrid({
        url: '/Security/GetUsersForManager',
        editurl: '/Security/MaintainUserForManager',
        colModel: [
            {label: 'UserName', name: 'UserName',
                index: 'UserName', jsonmap: 'UserName',
                width: 150, align: 'left', editable: false
            },
            { label: 'Active', name: 'Active', index: 'Active', jsonmap: 'Active',
                width: 50, align: 'center', editable: true, edittype: 'checkbox',
                formatter: 'checkbox'
            },
            { label: 'Actions', name: 'Actions', index: 'Actions', width: 75, sortable: false,
                formatter: actionRowNoDelFormatter
            }
        ],
        pager: jQuery('#uxUserGridPager'),
        sortname: 'UserName',
        sortorder: 'asc',
        imgpath: '/Content/Themes/Redmond/Images',
        rowNum: -1,
        postData: { propertyId: getPropertyID },
        jsonReader: { id: 'PropertyID' } /* Primary Key - needed for delete operation */
        onSelectRow: function (id) { onGridRowSelect('uxUserGrid', id); }
    }).navGrid('#uxUserGridPager',
    {
        edit: false, add: false, del: false, search: false, refresh: true
    },
    updateDialog,
    updateDialog,
    updateDialog
    );
}

The following JavaScript function is the code behind the "Create New" button found in the second ("Alternate") UI above. We set the primary key field to -1 (to cause the code to create a new table row) and the "parent ID" to be the id passed in (ultimately from the view model).

function newNote(id) {
    rowData = { ContactID: id, ContactNoteID: -1 };
    actionRowAdd(this, 'jqgridNotes', rowData);
}

Dates Columns

In the colmodel for a date column, include the following, adjusting the newformat as needed.

align: 'center', formatter: 'date', formatoptions: { newformat: 'm/d/Y h:i:s A' },
                editoptions: { dataInit: function (el) { $(el).datepicker(); } }

Dropdown Columns

In the colmodel for a dropdown column, include the following.

editable: true, align: 'left', edittype: 'select',
formatter: function (cellValue, options, rowObject) {
    return rowObject.RelationType; /* display field for the dropdown */
},
editoptions: {
    value: $.ajax({
        type: "GET",
        url: "/Controller/Method",
        async: false
    }).responseText}

In addition, specify the following. (Both these fields should be returned by the server code behind url.
  • name and jsonmap = the name of the value field behind the dropdown
  • index = the name of the display field behind the dropdown

Server Code

Controller Code

public class SecurityController : JQGridController
{
    [HttpGet]
    public JsonResult GetNotes(int contactID, PagingInfo paging)
    {
        var results = ContactManager.GetNotes(contactID, paging);
        var s = JQGridResult<ContactNoteView>(results, paging.page, paging.totalPages);
        return s;
    }

    [HttpPost]
    public JsonResult MaintainNote(ContactNoteView m, FormCollection form)
    {
        int id;
        var oper = form["oper"];
        int.TryParse(form["id"], out id);
        var username = HttpContext.User.Identity.Name;

        switch (oper)
        {
            case "edit":
                ContactManager.SaveContactNote(m, username);
                break;
            case "del":
                ContactManager.DeleteContactNote(id, username);
                break;
        }
        return Json(null, JsonRequestBehavior.AllowGet);
    }
}

Business Layer

The business layer class requires the following.

  • A using statement for the namespace containing the IQueryableHelper interface (recommended to be ACME.Framework.Helpers).
  • A using statement for the namespace containing the IAuditable and IDeletable interfaces(recommended to be ACME.Common).
  • The IAuditable and IDeletable interfaces applied to the database entity (ContactNote in the example below). This best done in the ACME.DAL namespace via a {public partial class} statement, similar to the following.

public partial class ContactNote : IAuditable, IDeletable { }

public static class ContactManager 
{
    public static List<ContactNoteView> GetNotes(int contactID, PagingInfo paging)
    {
        using (var context = new MyEntities())
        {
            var q = from o in context.ContactNotes
                    where o.ContactID == contactID && !o.IsDeleted
                    orderby o.DateCreated
                    select new ContactNoteView
                    {
                        ContactNoteID = o.ContactNoteID,
                        ContactID = o.ContactID,
                        Descrip = o.Descrip
                        /* etc */
                    };

            return IQueryableHelper.CreatePagedResult<ContactNoteView>(q, paging);
        }
    }
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    private static DAL.ContactNote GetContactNote(MyEntities context, int id)
    {
        return (from o in context.ContactNotes
                where o.ContactNoteID == id
                select o).FirstOrDefault();
    }
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    public static void SaveContactNote(ContactNoteView m, string username)
    {
        using (var context = new MyEntities())
        {
            /*--- Get Database Entity ---*/
            var d = GetContactNote(context, m.ContactNoteID);

            if (d != null)
            {
                d.Updated(username);
            }
            else
            {
                d = new DAL.ContactNote();
                context.ContactNotes.AddObject(d);
                d.Created(username);
                d.ContactID = m.ContactID;
            }

            /*--- Update properties of database entity ---*/
            d.Descrip = m.Descrip;
            /* etc */

            /*--- Save back to database ---*/
            context.SaveChanges();
        }
    }
    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    public static void DeleteContactNote(int contactNoteID, string username)
    {
        using (var context = new MyEntities())
        {
            var d = GetContactNote(context, contactNoteID);

            if (d != null)
            {
                d.Deleted(username);
                context.SaveChanges();
            }
        }
    }
}

Reusable Code

PagingInfo class

This class encapsulates the paging parameters used by jqGrid.

public class PagingInfo
{
    public string sidx { get; set; }
    public string sord { get; set; }
    public int page { get; set; }
    public int rows { get; set; }
    public int totalPages { get; set; }
}

IQueryableHelper class

This class hosts the extension method CreatePagedResult, which converts an set of results into a of paged results expected by jqGrid.

public static class IQueryableHelper
{
    public static List<T> CreatePagedResult<T>(IQueryable<T> results, PagingInfo paging)
    {
        try
        {
            int pageIndex = Convert.ToInt32(paging.page) - 1;
            int pageSize = paging.rows;
            int totalRecords = results == null ? 0 : results.Count();

            if (pageSize > 0)
            {
                paging.totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
            }
            else
            {
                paging.totalPages = 1;
                pageSize = totalRecords;
            }

            if (!string.IsNullOrEmpty(paging.sidx))
            {
                if (string.IsNullOrWhiteSpace(paging.sord))
                    paging.sord = "asc";

                string sortString = string.Empty;

                var sortKeys = paging.sidx.Split(',');

                foreach (var sortKey in sortKeys)
                {
                    if (sortString.Length > 0)
                        sortString += ",";

                    sortString += sortKey + " " + paging.sord;
                }

                return results.OrderBy(sortString).Skip(pageIndex * pageSize).Take(pageSize).ToList<T>();
            }
            else
            {
                return results.Skip(pageIndex * pageSize).Take(pageSize).ToList<T>();
            }
        }
        catch (Exception ex)
        {
            paging.totalPages = 1;
            return results.ToList<T>();
        }
    }
}

JQGridController class

This class provides the JQGridResult method, which converts a List of results into a Json object expected by jqGrid.

public abstract class JQGridController : Controller
{
    protected JsonResult JQGridResult<T>(List<T> results, int page, int totalPages)
    {
        try
        {
            var jsonData = new
            {
                total = totalPages,
                page = page,
                records = results.Count(),
                rows = Json(results).Data
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }
        catch
        {
            return Json(null, JsonRequestBehavior.AllowGet);
        }
    }
}

IAuditable Interface

This class encapsulates the date and usernames for the creation and last update of a database entity. It should be applied to any entity in your entity model that has these fields. In addition, the IAuditableExtension class provides the Created and Updated extensions methods to update these fields in a consistent way.

public interface IAuditable
{
    DateTime? DateCreated { get; set; }
    string CreatedBy { get; set; }
    DateTime? DateChanged { get; set; }
    string ChangedBy { get; set; }
}
public static class IAuditableExtension
{
    public static void Created(this IAuditable e, string user)
    {
        e.DateCreated = DateTime.Now;
        e.CreatedBy = user;
    }

    public static void Updated(this IAuditable e, string user)
    {
        e.DateChanged = DateTime.Now;
        e.ChangedBy = user;
    }
}

IDeletable

The IDeletable and IDeletableExtensions interfaces encapsulate soft deleting database entities. The IDeletable interface should be applied to any database entity that has the fields and therefore can be soft-deleted.

public interface IDeletable
{
    bool IsDeleted { get; set; }
    DateTime? DateChanged { get; set; }
    string ChangedBy { get; set; }
}
public static class IDeletableExtensions
{
    public static void Deleted(this IDeletable e, string user)
    {
        e.IsDeleted = true;
        e.DateChanged = DateTime.Now;
        e.ChangedBy = user;
    }

}

ScrewTurn Wiki version 3.0.1.400. Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.