我正在使用带有内联编辑的jQrid版本3.8.1,并且网格中的每一行都有几个要填充的下拉列表。当用户编辑行时,我需要执行AJAX查询以获取每个列表的值。我见过this post关于如何做到这一点。 dataUrl
和buildSelect
功能似乎是此处的标准答案。虽然有一些我无法弄清楚的问题:
用户正在编辑的行具有必须传递到dataUrl
值的值。例如,假设每行包含一个名为“SpecialValue”的字段,而对于第1行,SpecialValue = 100.第1行的dataUrl
字段将为“http://my.services.com?SpecialValue=100”。我该怎么做?
网格中的每一行都有大约10个需要填充的选择框。出于效率原因,我不想进行10次单独的AJAX调用。进行一次调用以获取所有数据,将其拆分并相应地填充每个选择框会更好。那可能吗?我尝试在onSelectRow
内执行此操作,但网格最终忽略了我放在那里的值(我猜测在编辑行时会触发事件的顺序)。
在阅读了奥列格的答案并进行了更多的研究后,我很清楚使用dataUrl
和buildSelect
对我来说效果不佳。我正在使用的jqGrid版本不支持以我需要的方式使用dataUrl
。即使它确实如此,我也不想为每个下拉列表发送多个单独的请求。
我决定在gridComplete
触发时执行一个请求,将所有下拉列表所需的所有数据提取到单个JSON结构中。然后,当用户选择一行进行内联编辑时,我将从该JSON结构填充行中的每个列表(下面的代码使用getSelectValuesFromJSON()函数 - 我没有给出它的定义,但你可以对它进行成像查看结构,并在列表框中获取适当的值列表。
我有一些候选解决方案,但我对这两种解决方案都不是百分之百。
解决方案1 :
在onSelectRow
内,我调用editRow
覆盖on oneditfunc
,以便从我需要的网格中获取数据。假设需要Field1
中的值才能将值放入Field2
的列表中。
onSelectRow: function (index, status, e) {
jQuery('#my_grid').jqGrid('editRow', index, true, function(rowId) {
var f1Val = $('#my_grid').jqGrid('getCell', index, 'Field1');
var selectVals = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
_.each(selectVals, function(selectVal) {
$(select).append($("<option></option>").attr("value", selectVal).text(selectVal));
});
});
}
这有效,但我对这条线犹豫不决
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
依赖于我不太了解的aria-describedby
属性。看似hacky和脆弱。
解决方案2 :
当用户选择一行时,利用beforeSelectRow
动态更改Field2列的模型。
beforeSelectRow: function(index, e) {
var f1Val = getGridCellValue('#my_grid', index, 'Field1');
var values = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var valStr = "";
_.each(values, function(value) {
valStr += value + ":" + value + ";"
});
jQuery('#grid_pipes').setColProp('Field2', { editoptions: { value: valStr } });
return true;
}
这也有效,但我不确定这是不是一个好主意。动态更改列的模型是否有效?如果用户同时选择了多行,该怎么办?是否只有一个列的模型?那是什么意思?
为了回答Oleg的一些问题,dataType
已设置为使用$ .ajax将数据发布到服务器的函数。我想我已经读过这不再是推荐的方法了。我继承了这段代码,所以我不确定为什么会这样做,但除非有一个非常令人信服的理由,否则它可能不会改变。
未指定loadonce
布尔值,因此我猜这意味着它默认为false
。
这是列模型的缩写版本(没有什么特别的不同寻常):
colModel: [
{ name: 'PK', index: 'PK', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field1', index: 'Field1', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field2', index: 'Field2', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
{ name: 'Field3', index: 'Field3', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
...
]
答案 0 :(得分:2)
您还没有编写当前使用的jqGrid版本,但dataUrl
可以定义为带有(rowid, value, name)
参数的回调函数,这些参数必须返回您可以动态构建的URL关于这些信息。该功能从v4.5.3开始存在(参见the line)。您可以在回调内部使用getCell
,getRowData
或getLocalRow
来获取该行其他列的数据。因此,您可以相对容易地解决您的第一个问题。
第二个问题在我看来完全独立于第一个问题。最好将不同帖子中的问题分开,以便搜索引擎更好地索引信息,从而帮助其他人找到它。
如何解决第二个问题没有简单的方法,但可以肯定建议一个解决方案,但是人们必须更多地了解你做了什么以及如何做。如何开始内联编辑(您使用inlineNav
,formatter: "actions"
还是直接致电editRow
)?您使用的是哪个版本的jqGrid(直到版本4.7),free jqGrid或Guriddo jqGrid JS?如何在colModel
中定义带选择的列?您使用哪datatype
以及您使用loadonce: true
?我建议您使用 发布单独的问题。
更新:如果您必须使用旧版本的jqGrid,则无法动态生成dataUrl
,但因为您只需要添加SpecialValue=100"
部分在URL中你可以按照我在许多旧答案中描述的技巧(第一个可能是here,但是对用户的选择可能会被误解)。您可以使用ajaxSelectOptions.data
来定义jQuery.ajax请求的data
参数。问题只是您只能定义一个ajaxSelectOptions.data
属性。因此,您可以添加以下 jqGrid选项:
ajaxSelectOptions: {
data: {
SpecialValue: function () {
var rowid = $myGrid.jqGrid("getGridParam", "selrow");
return $myGrid.jqGrid("getCell", rowid, "SpecialValue");
}
}
}
($myGrid
类似于$("#grid")
)
更新:您在问题的更新部分使用了未知函数getSelectValuesFromJSON
,getLookupValuesFromJSON
。两者似乎都使用同步 Ajax请求,这是不好的。此外,您只为{em>一个 editoptions.value
设置Field2
,而不是设置所有选择。
onSelectRow: function (rowid) {
var $myGrid = $(this);
$.ajax({
url: "someUrl",
dataType: "json";
data: {
specialValue: $myGrid.jqGrid("getCell", rowid, "Field1")
},
success: function (data) {
// for example response data have format:
// { "Field2": ["v1", "v2", ...], "Field3": ["v3", "v4", ...] }
var filed, str;
for (filed in data) {
if (data.hasOwnProperty(filed)) {
str = $.map(data[filed], function (item) {
return item + ":" + item
}).join(";");
$myGrid.jqGrid("setColProp", filed, {
editoptions: {
value: str
}
});
}
}
$myGrid.jqGrid("editRow", rowid, true);
}
});
}
然而,&#34;解决方案2&#34;更接近我的建议你。使用onSelectRow
或beforeSelectRow
并不重要。您可以向服务器发出异步 Ajax请求,该服务器返回您需要的所有选择的信息。 从服务器获得响应(success
回调内)后,您可以为所有选择设置editoptions.value
,然后才能启动editRow
。在这种方式中,您将确保该行的编辑将在所有选择中使用行特定选项。
其他一些评论。我建议您验证网格中的gridview: true
选项。此外,我怀疑您以不正确的方式填充网格,因为您隐藏了PK
列,而您使用index
代替rowid
作为beforeSelectRow
和{的第一个参数{1}}。了解jqGrid 的当前实现始终在网格的每一行(onSelectRow
元素)上分配id
属性非常重要。因此,必须在输入数据的每个项目中提供<tr>
信息。如果您希望向用户显示 ID信息(以及id
中包含主键的列),那么您应该只在列定义中包含colModel
属性。例如,您可以将key: true
添加到key: true
列的定义中,这样您就会PK
(或者rowid
在您的情况下)具有相同的值,例如{{1} }。它简化了许多代码部分。例如,jqGrid在编辑请求中向服务器发送index
参数。在请求中使用PK
是切实可行的。此外,如果您使用id
格式的PK
,则可以在repeatitems: false
中加入jsonReader
,而不是隐藏id: "PK"
列。它通知jqGrid从jsonReader
获取rowid。 jqGrid会将PK
保存在PK
的{{1}}属性中,您不需要在网格中添加具有相同信息的其他PK
。
最后一句话。我强烈建议您将复古版jqGrid 3.8.1更新为更新的版本,例如free jqGrid。即使您不使用任何功能(例如Font Awesome),您也会获得性能优势,而现代Web浏览器的外观看起来会更好。你应该明白jqGrid 3.8.1是用旧的(和慢的jQuery 1.4.2)测试的。该版本与Internet Explorer 8一起用作最新的IE版本(IE9于2011年3月晚些时候发布),并且它更加面向IE6 / IE7。现代Chrome / Firefox / Safari的外观可能很糟糕。这是你想要的吗?