背景
我从其他开发人员处获得了一些涉及显示搜索结果的不完整工作。他的方法是使用内联Javascript和jQuery将结果呈现在HTML表中,如下所示。
我正在尝试完成这项工作,但我更愿意编写更少的代码并使用jqGrid,因为它包含排序功能,并使代码更整洁。让jqGrid显示结果很简单,但是将单选按钮放在空白列中比我想象的要难。
应用程序中jqGrid的版本是3.7.2。网格需要在左侧有单选按钮以供选择,以使内容与应用程序的其余部分保持一致。
我被困的地方
似乎没有办法在jqGrid中拥有未绑定的列。也就是说,每列似乎都需要基础数据中的字段。如果您没有虚拟字段,则行数据和列标题会变得不对齐。
我遇到了example(请参阅行编辑 - >自定义编辑),它返回数据中带有虚拟字段的JSON,然后修改网格数据以插入按钮。
我的偏好是没有虚拟数据,因为感觉很脏 :)我希望我的JSON只包含表示搜索结果所需的数据。所以我认为最好在脚本代码中添加虚拟字段,以便保持服务器端的代码清洁。
我试图在jqGrid渲染之前修改从AJAX调用返回的数据。我已经尝试挂钩loadComplete
事件,但是当我修改数据时,它似乎已经渲染了。
我还尝试在success
ajaxGridOptions
字段options
上挂钩,但这似乎完全覆盖了事件,jqGrid不会呈现数据。
如何在jqGrid呈现之前修改从Web服务调用返回的数据?
答案 0 :(得分:2)
我设法弄清楚该怎么做。不要让 jqGrid 自动加载数据,而是需要手动执行请求,然后通过调用addJSONData
加载它。
我的jqGrid在标记中定义如下:
<fieldset>
<div style="display:none" class="searchResults">
<table id="eventSearchDialog-results">
</table>
<div id="eventSearchDialog-pager">
</div>
</div>
</fieldset>
我使用以下代码初始化网格:
// Initialize the grid
this._searchResults = this._dialog.find("#eventSearchDialog-results");
this._searchResults.jqGrid(
{
datatype: "local",
colNames: ['', 'Event Name', 'Event Type', 'Start Date', 'End Date', 'Location', 'Event Country', 'Sports'],
colModel: [
{ name: 'selector', index: 'selector', width: 30 },
{ name: 'EventName', index: 'EventName', formatter: jqgridCellFormatter, width: 150 },
{ name: 'EventType', index: 'EventType', formatter: jqgridCellFormatter, width: 120 },
{ name: 'StartDate', index: 'StartDate', formatter: jqgridCellFormatter, width: 100 },
{ name: 'EndDate', index: 'EndDate', formatter: jqgridCellFormatter, width: 100 },
{ name: 'Location', index: 'Location', formatter: jqgridCellFormatter, width: 100 },
{ name: 'EventCountry', index: 'EventCountry', formatter: jqgridCellFormatter, width: 100 },
{ name: 'Sports', index: 'Sports', formatter: jqgridCellFormatter }
],
rowNum: 10,
rowList: [10, 20, 30],
pager: this._dialog.find("#eventSearchDialog-pager"),
pginput: true,
sortname: 'EventName',
viewrecords: true,
sortorder: "asc",
hidegrid: false,
height: "auto",
shrinkToFit: true,
width: 630,
jsonReader:
{
page: "pageIndex",
total: "pageCount",
records: "recordCount",
root: "rows",
repeatitems: true
},
prmNames:
{
page: "pageIndex",
rows: "pageSize",
sort: "sortField",
order: "sortOrder"
}
}
);
// Set the data type to JSON, we don't do this in the options because it will cause a request to occur,
// but we do need it to be set to JSON so that the calls to addJSONData work later.
this._searchResults.jqGrid("setGridParam", { datatype: "json" });
我使用来自jQuery $.ajax()
调用的数据加载网格,并在success
事件处理程序中填充数据,然后使用addJSONData
将其加载到jqGrid中。
我的JSON看起来像这样:
{
"pageCount":1,
"pageIndex":1,
"recordCount":2,
"rows":
[
{"id":3, "cell":["Stevens Event 2", "Commonwealth Games", "03/05/2011", "16/05/2011", "sersdfweqr", "New Zealand", ["Archery"]]},
{"id":4, "cell":["Test - multiple sports", "Other", "01/05/2011", "30/06/2011", "Kobe", "Japan", ["Judo", "Karate", "Motor Sport", "Motorcycling", "Taekwondo"]]}
]
}
这是我的success
处理程序:
success: function (data, textStatus, xhr) {
// Pad data for our radio button column that has no corresponding field in the data
for (var counter = 0; counter < data.rows.length; counter++) {
data.rows[counter].cell.splice(0, 0, null);
}
thisEventSearchDialog._searchResults[0].addJSONData(data);
thisEventSearchDialog._createRadioButtons();
},
jqGrid包含需要虚拟数据的单选按钮列。没有虚拟数据,行数据与标头不匹配。
答案 1 :(得分:0)
我之前的答案中的解决方案打破了排序,因此我提出了另一种解决方案。
因为jqGrid没有提供钩子来方便地修改数据,所以有必要删回一个级别并挂钩到jQuery。我用自己的方法替换了$.ajax()
方法。首先,它检查操作是否是由jqGrid启动的操作,如果是,则填充数据,调用原始jqGrid success
处理程序,然后将单选按钮添加到网格中。排序仍然有效,数据类型仍然是json,并且没有对addJSONData
的手动调用,我仍然能够实现我之前的解决方案所需的功能。从本质上讲,制作这个小jQuery hack可以让我顺利通过,而不会使任何jqGrid黑客更糟糕。
// Set up $.ajax() hook for modifying the data before jqGrid receives it
if (!this._ajaxOverridden) {
var oldAjax = $.ajax;
$.ajax = function (options) {
// Check whether this call is from jqGrid to our web service
if (options.url == config.eventSearchUrl && options.success) {
// Wrap the success event handler with our own handler that pads the data and creates the radio buttons
var oldSuccess = options.success;
options.success = function () {
thisEventSearchDialog._padData(arguments[0]);
oldSuccess.apply(this, arguments);
thisEventSearchDialog._createRadioButtons();
}
}
oldAjax(options);
};
this._ajaxOverridden = true;
}
答案 2 :(得分:0)
这是一个老问题,它可能不适用于所提及的jqGrid版本(3.7.2),但它似乎与此相关:How to "pre-process" an ajax response before displaying in jqGrid如果我是对的(关于然后正确答案是dataFilter
参数的ajaxGridOption
参数/函数。它对我有用。