JQGrid Sorting is not working - MVC3 - asp.net-mvc-3

I am trying to sort the each columns in my JQGrid but its not working. Please refer my code below and help me
//View Code
$("#JQGridID").jqGrid({
url: '/Control/ActionResult/',
datatype: 'json',
mtype: 'POST',
colNames: ['Number', 'Unit'],
colModel: [
{ name: 'NNumber', index: 'Number', align: 'left', sortable: true, sorttype: 'int' },
{ name: 'NUnit', index: 'Unit', align: 'Center', sortable: true }
], pager: jQuery('#pager'),
cmTemplate: { title: false },
width: widthValue - 15,
height: 435,
rowNum: 20,
rowList: [20, 30, 40, 50, 60],
viewrecords: true,
gridComplete: loadCompleteFunction,
altRows: true,
sortorder: 'desc',
sortname: 'Number',
sortable: true,
onSortCol: function (index, idxcol, sortorder) {
if (this.p.lastsort >= 0 && this.p.lastsort !== idxcol
&& this.p.colModel[this.p.lastsort].sortable !== false) {
$(this.grid.headers[this.p.lastsort].el).find(">div.ui-jqgrid-sortable>span.s-ico").show();
}
}
,
onSelectRow: showMessageDetails,
postData: {
},
loadError: function (xml) { alert('Unable to load result data.'); }
});
//Control code
[HttpPost]
public ActionResult GetSearchPositionResult(string sidx, string sord, int page, int rows)
{
_Object = new PositionModel();
_Object.CurrentPage = page;
_Object.PageRowCount = rows;
_Object.load();
var result = new
{
total = _Object.TotalPages,
page = page,
sort = sidx,
sord = sord,
records = _Object.TotalRows,
rows = _ObjectPM.SearchResult.Select(p => new
{
cell = new string[]{
p.Number,
p.Unit
},sidx
}).OrderBy(a => a.sidx).ToArray(), };
return Json(result, JsonRequestBehavior.AllowGet);
}

In case of datatype: 'json' the sorting of data (sortable: true in colModel) is not handled on client-side by jqGrid but it has to be handled on server-side by your code. In another words you need to sort your _Object.SearchResult by the column name which you will receive in sidx parameter (the sorting direction is passed in sord parameter).
Here you can find a sample project which can help with using jqGrid in ASP.NET MVC: jqGrid in ASP.NET MVC 3 and Razor

Related

How to set Total Pages in JQGrid if I'm using server side paging?

I'm new to JQGrid and learning the paging currently. I'm trying to implement server side paging.
Consider I have 45 records. Since, Server side returns the requested records of a specified page based on page size(say 10), my pager changes to 1 immediately after clicking next button. I'm not able to move on to further pages since the total page is 1 now. Total page is automatically getting calculated based on the records present. So how to manage the total pages value in this case?
$("#jqGridOutbox").jqGrid({
datatype: 'json',
mtype: 'POST',
colNames: ['Title', 'Submitted By', 'Assigned To', 'Submitted On', 'History', 'WorkFlow Name'],
colModel: [
{ name: 'TitleOut', index: 'Title', width: 173, sortable: true, search: true, formatter: ShowItemFormatterOutbox },
{ name: 'CreatedByOut', index: 'CreatedBy', width: 173, sortable: true, searchoptions: {} },
{ name: 'PendingOnOut', index: 'PendingOn', width: 173, sortable: true, searchoptions: {} },
{ name: 'CreatedOnOut', index: 'CreatedOn', width: 173, sortable: true, searchoptions: {} },
{ name: 'HistoryOut', index: 'History', width: 80, sortable: false, search: false, formatter: ViewHistoryFormatter },
{ name: 'WorkFlowNameOut', index: 'WorkFlowName', width: 170, sortable: true, search: true }
],
datatype: function (postData) { getDataOutBox(postData, OutMode, OutPageNumber); },
ajaxGridOptions: { contentType: "application/json" },
loadonce: 'false',
viewrecords: 'true',
width: 987,
viewsortcols: [true, 'vertical', true],
height: 250,
rowList: [2, 5, 10, 20, 30, 100],
hidegrid: 'false',
rowNum: 2,
autowidth: true,
gridview: true,
shrinkToFit: false,
showQuery: 'true',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
cell: "cell",
id: "Title",
userdata: "userdata",
repeatitems: true
},
gridComplete: function () {
$("#load_jqGridOutbox").hide();
$("tr.jqgrow:odd").css("background", "white");
$("tr.jqgrow:even").css("background", "#f7f7f7");
},
pager: '#jqGridOutboxPager',
pagerpos: 'center'
});
The function mapped to datatype is GetDataOutBox()
function getDataOutBox(pdata, mode, pageNumber) {
var params = new Object();
params.page = pdata.page;
params.pageSize = pdata.rows;
params.sortIndex = pdata.sidx;
params.sortDirection = pdata.sord;
params.Title = $("#gs_TitleOut").val() == undefined ? '' : $("#gs_TitleOut").val();
params.CreatedBy = $("#gs_CreatedByOut").val() == undefined ? '' : $("#gs_CreatedByOut").val();
params.PendingOn = $("#gs_PendingOnOut").val() == undefined ? '' : $("#gs_PendingOnOut").val();
params.CreatedOn = $("#gs_CreatedOnOut").val() == undefined ? '' : $("#gs_CreatedOnOut").val();
params.WorkFlowName = $("#gs_WorkFlowNameOut").val() == undefined ? '' : $("#gs_WorkFlowNameOut").val();
params.mode = mode;
params.pageNumber = pageNumber;
$("#load_jqGridOutbox").show();
$.ajax({
url: 'ClaySysWorkFlowDashBoard.aspx/GetOutboxData',
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(params),
dataType: "json",
success: function (data, st) {
if (st == "success") {
var grid = $("#jqGridOutbox")[0];
grid.addJSONData(data.d);
//$("#jqGridOutbox")[0].updatepager(false, true);
}
},
error: function () {
alert("An error has occured retrieving the data!");
}
});
}
The model which gets returned is
public class JQGrid
{
public class Row
{
public int id { get; set; }
public List<string> cell { get; set; }
public Row()
{
cell = new List<string>();
}
}
public int page { get; set; }
public int total { get; set; }
public int records { get; set; }
public List<Row> rows { get; set; }
public JQGrid()
{
rows = new List<Row>();
}
}
Based on the page number, I select only the respective set of 10 records. Thus after returning that, the total pages changes to 1.

Sorting issue with jqgrid

I want to implement sorting of visible rows in jqgrid the default behavior of jqgrid is sorting all records. i have handled it on server side but the problem is when i do sort i always get page as 1 even when i am on page2 or other.below is my code i also tried loadComplete, & onPaging method.
$(document).ready(function () {
$("#grid").jqGrid({
emptyrecords: "No records to view",
ignoreCase: true,
datatype: "json",
url: '#Url.Action("LoadData", "Home")',
mtype: "GET",
height: 'auto',
rowNum: 5,
rowList: [5, 10, 15, 20],
colNames: ['EmployeeId', 'EmployeeCity', 'EmployeeName'],
colModel: [
{ name: 'EmployeeId', index: 'EmployeeId', key: true, width: 200, sorttype: 'int' },
{ name: 'EmployeeName', index: 'EmployeeName', width: 200, sorttype: 'text' },
{ name: 'EmployeeCity', index: 'EmployeeCity', width: 200, sorttype: 'text' }
],
pager: '#pager',
sortname: 'EmployeeId',
viewrecords: true,
sortorder: "asc",
caption: "jqGrid Example"
}).navGrid("#pager",
{ search: false, refresh: false, add: false, edit: false, del: false },
{},
{},
{}
);
});
And , My server side code is ,
public ActionResult LoadData(int page, int rows, string sidx, string sord)
{
List<Employee> employeeList = new List<Employee>();
for (int i = 1; i < 18; i++)
{
employeeList.Add(
new Employee() { EmployeeId = i, EmployeeCity = "Mumbai_" + i, EmployeeName = "Jason_" + i }
);
}
var totalRecords = 0;
var totalPages = 0;
var griddata = new List<Employee>();
if (employeeList != null)
{
griddata = employeeList.Skip((page - 1) * rows).Take(rows).ToList();
switch (sidx.ToLower())
{
case "employeeid":
if (sord.ToLower() == "asc")
griddata.OrderBy(x => x.EmployeeId).ToList();
else
griddata.OrderByDescending(x => x.EmployeeId).ToList();
break;
default:
griddata.OrderByDescending(x => x.EmployeeName).ToList();
break;
}
totalRecords = employeeList.Count;
totalPages = (int)Math.Ceiling((double)totalRecords / (double)rows);
}
var employeeListData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = griddata,
};
return Json(employeeListData, JsonRequestBehavior.AllowGet);
}
You are ordering your data on server side after you get paging. I mean this section:
griddata = employeeList.Skip((page - 1) * rows).Take(rows).ToList();
switch (sidx.ToLower())
{
case "employeeid":
if (sord.ToLower() == "asc")
griddata.OrderBy(x => x.EmployeeId).ToList();
else
griddata.OrderByDescending(x => x.EmployeeId).ToList();
break;
default:
griddata.OrderByDescending(x => x.EmployeeName).ToList();
break;
}
Just change the order like this:
switch (sidx.ToLower())
{
case "employeeid":
if (sord.ToLower() == "asc")
employeeList = employeeList.OrderBy(x => x.EmployeeId).ToList();
else
employeeList = employeeList.OrderByDescending(x => x.EmployeeId).ToList();
break;
default:
employeeList = employeeList.OrderByDescending(x => x.EmployeeName).ToList();
break;
}
griddata = employeeList.Skip((page - 1) * rows).Take(rows).ToList();
Yes finally done in a simple way.
Added one hidden field.
<input type="hidden" id="exampleGrid" value="" />
Modified jqgrid as
$(document).ready(function () {
$("#grid").jqGrid({
emptyrecords: "No records to view",
ignoreCase: true,
datatype: "json",
url: '#Url.Action("LoadData", "Home")',
mtype: "GET",
height: 'auto',
rowNum: 5,
rowList: [5, 10, 15, 20],
colNames: ['EmployeeId', 'EmployeeName', 'EmployeeCity'],
colModel: [
{ name: 'EmployeeId', index: 'EmployeeId', key: true, width: 200, sorttype: 'int' },
{ name: 'EmployeeName', index: 'EmployeeName', width: 200, sorttype: 'text' },
{ name: 'EmployeeCity', index: 'EmployeeCity', width: 200, sorttype: 'text' }
],
pager: '#pager',
sortname: 'EmployeeId',
viewrecords: true,
loadComplete: function () {
var page = $('#grid').jqGrid('getGridParam', 'page');
$("#exampleGrid").val(page);
},
onSortCol: function (index, iCol, sortOrder) {
$('#grid').jqGrid('setGridParam', {
page: $("#exampleGrid").val()
});
},
sortorder: "asc",
caption: "jqGrid Example"
}).navGrid("#pager",
{ search: false, refresh: false, add: false, edit: false, del: false },
{},
{},
{}
);
});

How to save/restore the CheckBox state in jqGrid across webMethod?

I am using jqGrid with "multiselect: true" and webMethods. I need to persist state, so I am going to put the Grid state in the DB, in order to do this I need to know which rows have selected checkboxes and pass that through the webMethod, then on the other side I need to be able to specify to the Grid to select or unselect a particular checkbox.
This is my current binding code, serializeGridData doesn't pick up the checkbox state.
$(document).ready(function () {
jQuery("#selectedInmateList").jqGrid({
url: "<%= AdminPath %>WebMethods/WebService1.asmx/GetUsersJSON3",
postData: {
inmateList: function () {
return InmateListArg;
}
},
mtype: 'POST',
datatype: 'json',
ajaxGridOptions: { contentType: "application/json" },
serializeGridData: function (postData) {
var propertyName, propertyValue, dataToSend = {};
for (propertyName in postData) {
if (postData.hasOwnProperty(propertyName)) {
propertyValue = postData[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue
}
}
}
return JSON.stringify(dataToSend);
},
onSelectRow: function (id) {
},
jsonReader: {
root: "d.rows",
page: "d.page",
total: "d.total",
records: "d.records"
},
colNames: ['select', 'LastName', 'FirstName', 'id'],
colModel: [
{ name: 'select', index: 'select', width: 300, align: 'center' },
{ name: 'LastName', index: 'LastName', width: 300, align: 'center' },
{ name: 'FirstName', index: 'FirstName', width: 300, align: 'center' },
{ name: 'id', index: 'id', align: 'center', hidden: true }
],
pager: '#prod_pager',
rowList: [10, 20, 30],
sortname: 'Code',
sortorder: 'desc',
rowNum: 10,
loadtext: "Loading....",
shrinkToFit: false,
multiselect: true,
emptyrecords: "No records to view",
//width: x - 40,
height: "auto",
rownumbers: true,
//subGrid: true,
caption: 'Selected Inmates'
});
});
If I understand your correctly you need first of all to send the current list of selected rows to the server. For example if the user select or unselect new row you can send the current list of the rows directly to the server. You can do this inside of onSelectRow and onSelectAll callbacks. Additionally you need that the server send you back only the data of the current page (the full data if you use loadonce: true option), but the list of ids of the rows which need be selected too. Inside of loadComplete you can call in the loop setSelection method to select the rows.
I would recommend you to examine the code of the callback onSelectRow, onSelectAll and loadComplete of the demo created for the answer. The old answer provide the basis of the same idea.
To pass the selected row IDs into the webMethod I used this:
var selectedIDs = jQuery('#selectedInmateList').jqGrid('getGridParam', 'selarrrow');
Then I added that to my webMethod param 'InmateListArg'
Then I added a hidden column which indicated if the row should be checked or not, then I used the loadComplete event to select the desired row based on the data in the hidden column.
$(document).ready(function () {
jQuery("#selectedInmateList").jqGrid({
url: "<%= AdminPath %>WebMethods/WebService1.asmx/GetUsersJSON3",
postData: {
inmateList: function () {
return InmateListArg;
}
},
mtype: 'POST',
datatype: 'json',
ajaxGridOptions: { contentType: "application/json" },
serializeGridData: function (postData) {
var propertyName, propertyValue, dataToSend = {};
for (propertyName in postData) {
if (postData.hasOwnProperty(propertyName)) {
propertyValue = postData[propertyName];
if ($.isFunction(propertyValue)) {
dataToSend[propertyName] = propertyValue();
} else {
dataToSend[propertyName] = propertyValue
}
}
}
return JSON.stringify(dataToSend);
},
onSelectRow: function (id) {
},
loadComplete: function (id) {
idsOfSelectedRows = [];
var gridData = jQuery("#selectedInmateList").getRowData();
for (i = 0; i < gridData.length; i++) {
var isChecked = gridData[i]['checked'];
var id = gridData[i]['id'];
if (isChecked == 'True') {
idsOfSelectedRows.push(id);
}
}
var $this = $(this), i, count;
for (i = 0, count = idsOfSelectedRows.length; i < count; i++) {
$this.jqGrid('setSelection', idsOfSelectedRows[i], false);
}
},
jsonReader: {
root: "d.rows",
page: "d.page",
total: "d.total",
records: "d.records"
},
colNames: ['select', 'LastName', 'FirstName', 'id', 'checked'],
colModel: [
{ name: 'select', index: 'select', width: 300, align: 'center' },
{ name: 'LastName', index: 'LastName', width: 300, align: 'center' },
{ name: 'FirstName', index: 'FirstName', width: 300, align: 'center' },
{ name: 'id', index: 'id', align: 'center' /*, hidden: true*/ },
{ name: 'checked', index: 'checked', align: 'center' }
],
pager: '#prod_pager',
rowList: [10, 20, 30],
sortname: 'Code',
sortorder: 'desc',
rowNum: 10,
loadtext: "Loading....",
shrinkToFit: false,
multiselect: true,
emptyrecords: "No records to view",
//width: x - 40,
height: "auto",
rownumbers: true,
//subGrid: true,
caption: 'Selected Inmates'
});
jQuery("#prodgrid").jqGrid('navGrid', '#prod_pager',
{ edit: false, add: false, del: true, excel: true, search: false });
});

MVC3 Razor Page using jqGrid not rebinding

I have a jqGrid on a view page and it is loaded based on gathering data from a few select lists.
The first time through all is fine. If I change one of the select lists the .change function is triggered but the .jqGrid doesnt fire so the Controller method isnt hit.
My jqGrid code
$("#Builds").change(function () {
var programID = $("#ProgramID").val();
var buildID = $('#Builds').val();
$("#UpdateBuild").show();
// Set up the jquery grid
$("#jqTable").jqGrid({
// Ajax related configurations
url: '#Url.Action("_CustomBinding")',
datatype: "json",
mtype: "POST",
postData: {
programID: programID,
buildID: buildID
},
// Specify the column names
colNames: ["Assembly ID", "Assembly Name", "Cost", "Order", "Budget Report", "Partner Request", "Display"],
// Configure the columns
colModel: [
{ name: "AssemblyID", index: "AssemblyID", width: 40, align: "left", editable: false },
{ name: "AssemblyName", index: "AssemblyName", width: 100, align: "left", editable: false },
{ name: "AssemblyCost", index: "AssemblyCost", width: 40, align: "left", formatter: "currency", editable: true },
{ name: "AssemblyOrder", index: "AssemblyOrder", width: 30, align: "left", editable: true },
{ name: "AddToBudgetReport", index: "AddToBudgetReport", width: 40, align: "left", formatter: "checkbox", editable:true, edittype:'checkbox'},
{ name: "AddToPartnerRequest", index: "AddToPartnerRequest", width: 45, align: "left", formatter: "checkbox", editable:true, edittype:'checkbox'},
{ name: "Show", index: "Show", width: 20, align: "left", formatter: "checkbox", editable:true, edittype:'checkbox'}],
// Grid total width and height and formatting
width: 650,
height: 200,
altrows: true,
// Paging
toppager: true,
pager: $("#jqTablePager"),
rowNum: 10,
rowList: [10, 20, 30],
viewrecords: true, // Specify if "total number of records" is displayed
emptyrecords: 'No records to display',
// Default sorting
sortname: "AssemblyID",
sortorder: "asc",
// Grid caption
caption: "Build Template"
}).navGrid("#jqTablePager",
{ refresh: true, add: true, edit: true, del: true },
{}, // settings for edit
{}, // settings for add
{}, // settings for delete
{sopt: ["cn"]} // Search options. Some options can be set on column level
);
});
My controller Code:
[HttpPost]
public JsonResult _CustomBinding(string programID, string buildID, int page, int rows)
{
/* Variable Declarations */
BuildsRepository br = new BuildsRepository();
IEnumerable<ProgramsAssemblyBuilds> pab = br.GetProgramAssembliesBuilds(Convert.ToInt32(programID), Convert.ToInt32(buildID));
// Calculate the total number of pages
var totalRecords = pab.Count();
var totalPages = (int)Math.Ceiling((double)totalRecords / (double)rows);
var data = (from s in pab
select new
{
AssemblyID = s.AssemblyID,
cell = new object[] { s.AssemblyID, s.AssemblyName, s.AssemblyCost, s.AssemblyOrder, s.AddToBudgetReport, s.AddToPartnerRequest, s.Show}
}).ToArray();
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = data.Skip((page - 1) * rows).Take(rows)
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
Anyone have any ideas on this one?
Thanks
You should create the grid only once. So you should place the code
$("#jqTable").jqGrid({ ... });
outside of the change event handler.
To reload the grid you should use
$("#Builds").change(function () {
$("#jqTable").trigger("reloadGrid", [{page: 1}]);
$("#UpdateBuild").show();
});
At the end to have actual values from "#ProgramID" and '#Builds' you should use functions (methods) as the programID and buildID properties of postData:
// Set up the jquery grid
$("#jqTable").jqGrid({
// Ajax related configurations
url: '#Url.Action("_CustomBinding")',
datatype: "json",
mtype: "POST",
postData: {
programID: function() { return $("#ProgramID").val(); },
buildID: function() { return $('#Builds').val(); }
},
...
});
See more information here.

Display data in jqGrid Footer row in MVC Application

I need help display data in the jqGrid footer row. This is my configuration on the Server. Notice the userdata = (Hours) line.
// Format the data for the jqGrid
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from a in activities
select new
{
id = a.ActivityId,
cell = new string[] {
a.ActivityId.ToString(),
DateTime.Parse(a.Date.ToString()).ToShortDateString(),
a.Person.Name.ToString(),
a.ActivityName.ToString(),
a.Hours.ToString()
}
}).ToArray(),
userdata = (Hours)
};
// Return the result in json
return Json(jsonData, JsonRequestBehavior.AllowGet);
The userData amount that I need displayed in the footer is coming through in the JSON. I am using Fiddler to view it. Here is a screenshot of the fiddler view:
alt text http://shirey.technologyblends.com/Content/images/json.jpg
I need to display this value of "12" in the footer. This the HTML I am using to read the JSON:
jQuery("#list").jqGrid({
url: gridDataUrl + '?startDate=' + startDate.toJSONString() + '&endDate=' + endDate.toJSONString(),
datatype: "json",
mtype: 'GET',
colNames: ['Activity ID', 'Date', 'Employee Name', 'Activity', 'Hours'],
colModel: [
{ name: 'ActivityId', index: 'ActivityId', width: 40, align: 'left' },
{ name: 'Date', index: 'Date', width: 50, align: 'left' },
{ name: 'Person.Name', index: 'Person.Name', width: 100, align: 'left', resizable: true },
{ name: 'ActivityName', index: 'ActivityName', width: 100, align: 'left', resizable: true },
{ name: 'Hours', index: 'Hours', width: 40, align: 'left' }
],
loadtext: 'Loading Activities...',
multiselect: true,
rowNum: 20,
rowList: [10, 20, 30],
imgpath: gridimgpath,
height: 'auto',
width: '700',
pager: jQuery('#pager'),
sortname: 'ActivityId',
viewrecords: true,
sortorder: "desc",
caption: "Activities",
footerrow: true, userDataOnFooter: true, altRows: true
}).navGrid('#pager', { search: true, edit: false, add: false, del: false, searchtext: "Search Activities" });
Try to use following
var jsonData = new {
total = totalPages,
page = page,
records = totalRecords,
rows = (
from a in activities
select new {
id = a.ActivityId,
cell = new string[] {
a.ActivityId.ToString(),
DateTime.Parse(a.Date.ToString()).ToShortDateString(),
a.Person.Name.ToString(),
a.ActivityName.ToString(),
a.Hours.ToString()
}
}).ToArray(),
userdata = new {
Hours = 12
}
};
then the userdata part of the JSON data will be
"userdata":{"Hours":12}
which follows to displaying of the bold value 12 in the column Hours of the footer part of the jqGrid table.

Resources