【问题标题】:jqGrid - How to set custom editoptions based on *initial* column values?jqGrid - 如何根据 *initial* 列值设置自定义编辑选项?
【发布时间】:2011-11-24 01:21:52
【问题描述】:

我正在使用带有 EF4 和 ASP.NET Web 窗体的开源 jqGrid 插件。我需要根据数据库中的列值在可内联编辑的网格行中设置一个输入元素。例如,第一行可以包含 DDL,第二行可以包含复选框等。

我正在尝试使用custom_elementcustom_values 来实现这一点,如下所示:

$("#grid1").jqGrid({
    url: 'Default.aspx/getGridData',
    datatype: 'json',
    ...
    colModel: [
    ...
    //contains the input type ('select', etc.)
    { name: 'InputType', hidden:true }, 
    ...
    //may contain a string of select options ('<option>Option1</option>'...)
    { 
      name: 'Input', 
      editable:true, 
      edittype:'custom', 
      editoptions:{
         custom_element: /* want cell value from InputType column here */ , 
         custom_value:   /* want cell value from Input column here */ 
      } 
     }, 
    ...
    ]
});

jqGrid docs 说我可以调用自定义函数来设置custom_elementcustom_values,但是我看不到如何捕获列值并将它们传递给我的自定义函数。

对于设置custom_values,我确实注意到Oleg's nice solution 使用list: 参数,但这似乎涉及额外的Ajax 调用。我想避免这种情况,因为我已经从网格的初始 Ajax 调用中获得了所需的所有数据。

总而言之,我需要在内联编辑模式下执行以下操作:

  1. 从 DB 值动态分配输入类型
  2. 从 DB 字符串动态分配输入值(用于 DDL 或复选框)

我也愿意跳过使用custom_elementcustom_values,但是我仍然面临动态设置edittypeeditoptions:{value:}参数的同样问题。

关于如何做到这一点的任何想法?我应该采取其他方法吗?

更新:感谢您为我提供的帮助。根据请求,这是我的 JSON 响应的简短示例:

{"d":[
{"Input":null,"InputType":"select"},
{"Input":"From downtown, proceed west on Interstate 70.", "InputType":"text"}
]}

有了这些数据,我想在一行中显示一个空选择,并在下一行显示一个填充的文本字段。两者都是可编辑的内联。

解决方案:我回到这个问题是为了找到一个涉及使用custom_elementcustom_values 的解决方案。这是我的解决方案(基于下面的accepted answer)更改edittypeeditoptions

loadComplete: function () {
    var rowIds = $("#grid1").jqGrid('getDataIDs');

    $.each(rowIds, function (i, row) {
       var rowData = $("#grid1").getRowData(row);

       if (rowData.InputType == 'select') {
          $("#grid1").jqGrid('restoreRow', row);
                var cm = $("#grid1").jqGrid('getColProp', 'Input');
                cm.edittype = 'select';
                cm.editoptions = { value: "1:A; 2:B; 3:C" };
                $("#grid1").jqGrid('editRow', row);
                cm.edittype = 'text';
                cm.editoptions = null;
       }
   });
}

Nota Bene:对我来说重要的一件事是记住在调用editrow 后将editoptions 设置回null。此外,正如 Oleg 在 cmets 中提到的,避免使用自定义元素使我可以轻松实现 datepicker 输入。这对我的应用很重要,所以我最终接受了 Oleg 的回答,但我仍然支持 Walter 的回答。如果这是不好的形式,我真诚地道歉。我只是想奖励最适合我的解决方案。

【问题讨论】:

  • 您写道“我已经从最初的 Ajax 调用网格中获得了我需要的所有数据”。您能否提供一个您使用的 JSON 数据示例?这样人们就可以看到您发送信息的格式。
  • @Oleg:已更新问题以包含 JSON 响应。
  • Oleg 和 Walker 的答案在实用性方面几乎相同。我接受沃尔特的回答主要是因为它是最先发布的。我应该提到,我非常感谢 Oleg 的其他 jqGrid 答案,一旦我获得足够的 SO 积分,我将慷慨地支持这些答案。
  • 接受沃尔特的回答是个好主意。尽管如此,我是完美主义者,我知道如果您使用自定义编辑,您可能会遇到一些额外的问题。主要规则是:如果你能找到没有自定义编辑的解决方案,你就不应该使用它。在您阅读了onSelectRow 处理程序中的ElementType 值之后,您可以使用var cm = grid.jqGrid('getColProp','FullName'); 获取列属性并更改cm.edittypecm.editoptions 之前 调用editRow。以这种方式,您将拥有最标准的编辑控件。
  • 查看the answer,它描述了使用 jQuery UI 自动完成和自定义编辑的问题。自定义控件将放置在具有id&lt;span&gt; 中,而您手动创建的&lt;input&gt;(请参阅Walter 的答案)具有no id。所以在当前的实现中,自动完成功能将不起作用。如果您只使用标准的edittype='text',您可以使用自动完成或日期选择器,而无需任何额外的工作。

标签: c# asp.net jquery-plugins jqgrid


【解决方案1】:

试试这个:

1. 为网格的 onSelectRow 事件 (onSelectRow_handler) 定义一个处理程序。
2. 在 onSelectRow 处理程序内部:
2.1. 将全局范围的变量 (lastRow) 设置为函数的 id 参数。
2.2. 调用 jqGrid 的 editRow() 函数将网格置于编辑状态-模式。这将触发您定义为 custom_element 渲染器 (myelem) 的函数。
3. 在 myelem 内部:调用 jqGrid 的 getRowData 方法以获取您刚刚选择进行编辑的行的行数据。从那里您可以获取 ElementType 列中的值并执行您的逻辑来决定要呈现哪个元素。

您必须稍微调整一下我的代码,因为我没有对它进行 100% 端到端测试。我确实验证了步骤 3 之前的所有内容都有效。我没有对如何编写 myvalue() 进行任何研究。

function renderGrid () {

    $("#grid").jqGrid({
        datatype: "local",
        colNames: ['Id', 'ElementType', 'Name' ],
        colModel: [
            { name: 'Id', index: 'Id', key: true, hidden: true },
            { name: 'ElementType', index: 'ElementType', },
            { name: 'FullName', index: 'FullName',
              editable: true, edittype: 'custom', 
              editoptions: { custom_element: myelem, custom_value: myvalue} }],
        viewrecords: true,
        caption: "",
        autowidth: true,
        height: 'auto',
        forceFit: true ,
        onSelectRow: onSelectRow_handler           
    });


}

var lastRow = null;
function onSelectRow_handler(id) {

    if(id && id!==lastRow){            
        lastRow=id;
    }
    // editRow will send grid into edit mode which will trigger
    $("#grid").editRow(id, true);

}

function myelem(value, options) {
    var data = $("#grid").getRowData(lastRow);
    // the elementType column contains a key to
    // indicate what Input Element to render
    var elementType = data.ElementType;

    if (elementType == 'text') {        
        var el = document.createElement("input");
        el.type = "text";
        el.value = value;         
    }
    if (elementType == 'checkbox') {
        // etc
    }

    return el;
}

function myvalue(elem, operation, value) {
    if (operation === 'get') {
        return $(elem).find("input").val();
    } else if (operation === 'set') {
        $('input', elem).val(value);
    }
}

【讨论】:

  • 这似乎有效。在标记答案之前,我想尝试其他解决方案。再次感谢。
【解决方案2】:

如果您使用倾斜编辑,您可以直接在代码中的某处调用editRow 方法。在editRow 方法中,colModel 中与编辑相关的所有选项都将被检查和使用。所以您可以动态更改任何选项,例如editableedittypeeditoptionsThe answer 展示了如何更改 editable 属性。以同样的方式,您可以更改任何其他属性。

如果您愿意,您可以在loadComplete 事件句柄中设置有关编辑类型和选项的信息。它有data 参数,代表从服务器发送的原始数据。因此,您可以使用和其他信息扩展数据,并根据这些信息为任何列设置editableedittypeeditoptions

【讨论】:

  • 您的大部分建议都有效,但我无法更改单行edittype。 (我已经看到很多例子改变了 all 行的edittype。)在loadComplete 上,我想遍历行并将每行的edittype 更改为其他内容,例如select。我更新了我的问题以包括我的新loadComplete。谢谢,一如既往。
  • @bflow1:edittype 将仅在行编辑的初始化时使用。因此,例如,可以在onSelectRow 内部更改edittype 之前 一次调用editRow。请参阅here 演示。例如,在表单编辑的情况下,可以在 beforeInitData 中以相同的方式进行更改。
  • 我很高兴地报告您的解决方案现在对我有用。我可以将所有输入字段默认为edittype:text,然后更改loadcomplete 中任何输入字段的编辑类型,无需借助自定义编辑。 (这很重要,因为我确实需要能够使用日期选择器。)我将在上面发布我的解决方案以供参考。虽然我的链接与您的链接没有什么不同(当然也是基于您的链接),但它确实显示了对 edittype 的更改,而不是 edittype 参数。奥列格,非常感谢,一如既往。每当我找到它们时,我都会支持你的 SO 答案!
  • @bflow1:不客气!我很高兴得知您有有效的解决方案。恭喜!对您发布的代码的小评论。您可以将$(this) 保存在loadComplete开头 变量中。您可以稍后在loadComplete 的内部函数中使用该变量。这可以消除$("#grid1") 的使用并准备好代码,以便在另一个网格中剪切和粘贴。
  • 感谢您的提示。在我的实际生产代码中,我正在做你说的。我的问题中的代码与我的生产代码相比非常简化,因此每个人都更容易阅读问题。我通常在写问题时这样做。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2014-03-10
  • 2013-03-21
  • 2014-06-23
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多