如何使jqGrid根据行数据

时间:2015-04-24 19:20:10

标签: dynamic jqgrid options

我正在使用带有内联编辑的jQrid版本3.8.1,并且网格中的每一行都有几个要填充的下拉列表。当用户编辑行时,我需要执行AJAX查询以获取每个列表的值。我见过this post关于如何做到这一点。 dataUrlbuildSelect功能似乎是此处的标准答案。虽然有一些我无法弄清楚的问题:

  1. 用户正在编辑的行具有必须传递到dataUrl值的值。例如,假设每行包含一个名为“SpecialValue”的字段,而对于第1行,SpecialValue = 100.第1行的dataUrl字段将为“http://my.services.com?SpecialValue=100”。我该怎么做?

  2. 网格中的每一行都有大约10个需要填充的选择框。出于效率原因,我不想进行10次单独的AJAX调用。进行一次调用以获取所有数据,将其拆分并相应地填充每个选择框会更好。那可能吗?我尝试在onSelectRow内执行此操作,但网格最终忽略了我放在那里的值(我猜测在编辑行时会触发事件的顺序)。

  3. 编辑:

    在阅读了奥列格的答案并进行了更多的研究后,我很清楚使用dataUrlbuildSelect对我来说效果不佳。我正在使用的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: {} },
        ...
    ]
    

1 个答案:

答案 0 :(得分:2)

您还没有编写当前使用的jqGrid版本,但dataUrl可以定义为带有(rowid, value, name)参数的回调函数,这些参数必须返回您可以动态构建的URL关于这些信息。该功能从v4.5.3开始存在(参见the line)。您可以在回调内部使用getCellgetRowDatagetLocalRow来获取该行其他列的数据。因此,您可以相对容易地解决您的第一个问题。

第二个问题在我看来完全独立于第一个问题。最好将不同帖子中的问题分开,以便搜索引擎更好地索引信息,从而帮助其他人找到它。

如何解决第二个问题没有简单的方法,但可以肯定建议一个解决方案,但是人们必须更多地了解你做了什么以及如何做。如何开始内联编辑(您使用inlineNavformatter: "actions"还是直接致电editRow)?您使用的是哪个版本的jqGrid(直到版本4.7),free jqGridGuriddo 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")

更新:您在问题的更新部分使用了未知函数getSelectValuesFromJSONgetLookupValuesFromJSON。两者似乎都使用同步 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;更接近我的建议你。使用onSelectRowbeforeSelectRow并不重要。您可以向服务器发出异步 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的外观可能很糟糕。这是你想要的吗?