Я использую jqGrid (4.3.1) в веб-приложении ASP.NET MVC 3.
У меня есть уникальная ситуация (по крайней мере, для которой я не могу найти решение), в которой мне передаются мои данные из внешнего источника - в разбитых на фрагменты - поэтому я не могу использовать свойство url сетки Тем не менее, я все еще должен реализовать сортировку, разбиение на страницы и фильтрацию на стороне сервера.
Мой план (как только я решу ниже) использовать методы onPaging, onSortCol и beginSearch для обратного вызова веб-службы и обновления данных сетки в обратном вызове.
Данные предоставляются в формате, который может использовать jqGrid (я могу легко отобразить его с помощью опции jsonReader):
jsonReader: {
repeatitems: false,
root: "Rows",
page: "Page",
total: "TotalPages",
records: "RecordCount",
userdata: "FooterTotals",
id: "ClaimId"
},
Я передаю данные через опцию datastr и устанавливаю тип данных 'jsonstring'.
loadonce установлен в false (я пробовал оба пути), а мой rowNum установлен в 10.
Когда я делаю начальный вызов, возвращается набор данных с ~ 900 записями, и сетка отображает первые 10 записей, , но пейджер игнорирует 'total' & 'records' и думает, что у меня есть только 1 страница данных .
корневые данные не игнорируются (отображаются 10 записей), а пользовательские данные не игнорируются (т. Е. Нижний колонтитул отображается правильно). поэтому сетка выборочно игнорирует данные «итого» и «записи» из источника данных.
У меня такой вопрос - запрещает ли использование типа данных: jsonstring и datastr (и предоставление json в сетку вместо URL) использовать возможности подкачки / сортировки / фильтрации на стороне сервера?
если так, есть ли способ сделать то, что я хочу?
обратите внимание, что если я верну весь набор записей 900 count и установлю loadonce в true, все будет работать нормально, хотя и на стороне клиента.
весь мой jqGrid, для справки:
g.claims.LoadGrid = function (url, pagerDiv, grid, caption, drillData) {
jQuery(grid).jqGrid({
url: url,
datastr: drillData != null ? drillData : g.claims.gridData,
datatype: 'jsonstring',
mtype: 'POST',
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
if (postData.filters === undefined) postData.filters = null;
postData.quick = $("#quickSearchText").val();
return JSON.stringify(postData);
},
jsonReader: {
repeatitems: false,
root: "Rows",
page: "Page",
total: "TotalPages",
records: "RecordCount",
userdata: "FooterTotals",
id: "ClaimId"
},
colNames: ['ClaimId', 'Claim Reference', 'Status', 'Handler', 'Create Date', 'Division', 'Line Of Business', 'Policy Reference', 'Incurred Amount', 'Paid Amount'],
colModel: [
{ name: 'ClaimId', index: 'ClaimId', width: 90, sorttype: 'integer', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'ClaimRef', index: 'ClaimRef', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'Status', index: 'Status', width: 100, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'Handler', index: 'Handler', width: 140, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'CreateDateDisplay', index: 'CreateDateDisplay', width: 90, align: 'center', sorttype: 'date', formatter: 'date', formatoptions: { srcformat: 'M-d-Y', newformat: 'd-M-Y' }, editable: true, datefmt: 'd-M-Y',
editoptions: { dataInit: g.claims.initDateEdit },
searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'], dataInit: g.claims.initDateSearch }
},
{ name: 'Division', index: 'Division', width: 90, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'LineOfBusiness', index: 'LineOfBusiness', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'PolicyRef', index: 'PolicyRef', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'IncurredAmount', index: 'IncurredAmount', width: 120, sorttype: 'currency', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} },
{ name: 'PaidAmount', index: 'PaidAmount', width: 120, sorttype: 'currency', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} }
],
rowNum: 10,
rowList: [10, 20, 30],
pager: pagerDiv,
loadonce: false,
sortname: 'ClaimId',
viewrecords: true,
sortorder: "desc",
height: 250,
ignoreCase: true,
loadui: 'disable',
autowidth: true,
caption: caption,
sortable: true,
shrinkToFit: false,
footerrow: true,
userDataOnFooter: true,
gridview: false,
loadComplete: function () {
var filters, quick, i, l, rules, rule, iCol, $this = $(this);
if (this.p.search === true) {
filters = $.parseJSON(this.p.postData.filters);
if (filters !== null && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
rules = filters.rules;
l = rules.length;
for (i = 0; i < l; i++) {
rule = rules[i];
iCol = g.GetColumnIndexByName($this, rule.field);
if (iCol >= 0) {
$('>tbody>tr.jqgrow>td:nth-child(' + (iCol + 1) + ')', this).highlight(rule.data);
}
}
}
}
quick = $("#quickSearchText").val();
if (quick !== null) {
var colCount = g.GetColumnCount($this);
for (i = 0; i < colCount; i += 1) {
$('>tbody>tr.jqgrow>td:nth-child(' + (i + 1) + ')', this).highlight(quick);
}
}
return;
},
onSelectRow: function (id) {
var ret = jQuery(grid).jqGrid('getRowData', id);
alert(ret.ClaimRef);
//_currentRequestId = ret.RequestId;
//ShowRequest();
},
loadError: function (xhr, textStatus, errorThrown) {
var errorMsg = xhr.responseText;
var msg = "Some errors occurred during processing:";
msg += '\n\n' + textStatus + '\n\n' + errorMsg;
g.trackError(msg, document.URL, 0);
}
});
jQuery(grid).jqGrid('navGrid', pagerDiv, { refresh: false, edit: false, add: false, del: false, search: false });
//jQuery(grid).jqGrid('setFrozenColumns');
jQuery(grid).jqGrid(
'navButtonAdd',
pagerDiv,
{
caption: "",
buttonicon: "ui-icon-newwin",
title: "choose columns",
onClickButton: function () {
$(this).jqGrid('columnChooser', {
done: function () {
$(grid).trigger("resize");
}
});
}
}
);
jQuery(grid).jqGrid(
'navButtonAdd',
pagerDiv,
{
caption: "",
buttonicon: "ui-icon-refresh",
title: $.jgrid.nav.refreshtitle,
onClickButton: function () {
$(this).jqGrid('setGridParam', { datatype: 'json' });
$(this).trigger('reloadGrid', [{ page: 1}]);
}
}
);
jQuery(grid).jqGrid('filterToolbar', {
stringResult: true,
searchOnEnter: false,
defaultSearch: 'cn',
beforeSearch: function () {
var postedData = $(this).jqGrid('getGridParam', 'postData');
g.claims.FilterPageSort(postedData);
return false;
}
});
jQuery(grid).fluidGrid({ example: "#gridParent", offset: 0 });
};
ОБНОВЛЕНИЕ (больше информации для Олега):
Ajax вызывает метод контроллера (в котором есть комментарии, которые ссылаются на классы, описанные ниже). Этот метод придерживается JDG-сериализованной JD-структуры postData (с несколькими дополнительными параметрами):
[HttpPost]
public ActionResult GetLagChart(int page, int rows, string sidx, string sord, bool _search, string filters, string quick)
{
var claims = WarehouseDataProvider.Instance.GetClaim(quick);
//will eventually be passed in as jqGrid filters - not yet implemented
var startPeriod = 201101;
var endPeriod = 201112;
//the return of this method is of type Chart - see below
var lag = WarehouseDataProvider.Instance.GetLagChart(claims, startPeriod, endPeriod);
var viewModel = new LagChartViewModel
{
LagChart = lag,
GridData = GetResults(claims, page, rows, sidx, sord)
};
return this.JsonNet(viewModel);
}
Класс Chart, упомянутый в коде выше:
public class Chart
{
public List<ColumnSeries> Series { get; set; }
public List<string> Categories { get; set; }
}
public class ColumnSeries
{
public string Name { get; set; }
public List<object> Values { get; set; }
}
класс jqGrid GridData, упомянутый выше:
public class GridData<T>
{
public int TotalPages { get; set; }
public int Page { get; set; }
public int RecordCount { get; set; }
public List<T> Rows { get; set; }
public object FooterTotals { get; set; }
}
Пример отправки Json на веб-службу (контроллер с поддержкой HttpPost):
{ "страница": 1, "строки": 10, "sidx": "ClaimId", "Sord": "прямом", "_ поиска": ложные, "фильтры": нулевой, "быстрый": "отл «}
Ответ Ajax:
{
"GridData": {
"TotalPages": 92,
"Page": 1,
"RecordCount": 911,
"Rows": [
{
"ClaimId": 229731,
"ClaimRef": "XXX111345",
"ClaimTitle": "title 1",
"Status": "Claim - Finalised",
"IncurredAmount": 0.00,
"PaidAmount": 0.00,
"Handler": "Person One",
"Handler1": "Person One",
"Handler2": "Person One",
"Handler3": "Person One",
"Division": "Person One",
"Branch": null,
"LineOfBusiness": "Wholesale Excess",
"PolicyRef": "SFSF9090888",
"CreateDateDisplay": "03-30-2012",
"DateOfAdvice": "2009-06-01T00:00:00",
"DateOfLoss": "2007-07-08T00:00:00",
"LossPeriod": 200707,
"DateOfFirstReserve": "2009-06-03T00:00:00",
"AdviceLag": 695,
"ReserveLag": 3
},
{
"ClaimId": 229933,
"ClaimRef": "EXC123488",
"ClaimTitle": "Title 2",
"Status": "Claim - Finalised",
"IncurredAmount": 0.00,
"PaidAmount": 0.00,
"Handler": "Person Two",
"Handler1": "Person Two",
"Handler2": "Person Two",
"Handler3": "Person Two",
"Division": "Excess",
"Branch": null,
"LineOfBusiness": "Wholesale Excess",
"PolicyRef": "NY676767777",
"CreateDateDisplay": "03-30-2012",
"DateOfAdvice": "2009-06-02T00:00:00",
"DateOfLoss": "2006-01-01T00:00:00",
"LossPeriod": 200601,
"DateOfFirstReserve": "2009-06-18T00:00:00",
"AdviceLag": 1249,
"ReserveLag": 17
},
...
],
"FooterTotals": {
"ClaimId": "Totals",
"IncurredAmount": -27910474.80,
"PaidAmount": -27910474.80
}
},
"LagChart": {
"Series": [
{
"Name": "Average Advice Lag",
"Values": [
1499,
1048,
897,
2354,
1450,
444,
334,
816,
508,
108,
256,
109
]
},
{
"Name": "Average Reserve Lag",
"Values": [
44,
131,
23,
76,
67,
18,
122,
45,
29,
15,
3,
14
]
}
],
"Categories": [
"Jan 2011",
"Feb 2011",
"Mar 2011",
"Apr 2011",
"May 2011",
"Jun 2011",
"Jul 2011",
"Aug 2011",
"Sep 2011",
"Oct 2011",
"Nov 2011",
"Dec 2011"
]
}
}