jqGrid:内联编辑整行,但专注于单元格进入编辑模式

时间:2011-07-17 10:11:00

标签: javascript jquery jqgrid

我们的Web应用程序使用jqGrid进行数据输入,数据按行和行进行编辑。

客户希望获得更“类似Excel”的体验,以便在通过单击单元格将行切换到内联编辑时,该单元格将获得焦点(当前,该行中的第一个单元格获得焦点)。

6 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。很沮丧。我修改了jquery.jqGrid.js文件以适应设置焦点在单击的单元格上。

在我的editRow函数中,我添加了以下代码:

function editRow(id, row, col, z)
{
    grid.jqGrid("editRow", id, true, function ()
    {
        var f = $("input, select", z.target).focus();

        return f;
    });
}

这将创建一个变量f,最终将传递给$ .jgrid.extend中的“oneditfunc”

问题出在setTimeout函数中。

$("td:eq("+focus+") input",ind).focus();

因为焦点设置为上面.each函数中的第一个可编辑字段而执行此操作。这是传递焦点索引的好地方,但不可能。

// End compatible
return this.each(function ()
{
    var $t = this, nm, tmp, editable, cnt = 0, focus = null, svr = {}, ind, cm, bfer;
...

然后我添加了以下代码。 (包含>>>的行未更改。它只是帮助您在代码中找到插入点。)

    >>>     $($t).triggerHandler("jqGridInlineEditRow", [rowid, o]);


    if ($.isFunction(o.oneditfunc))
    {
        // modified to allow for setting focus on the 
        // field clicked on

        // sets a return value.  this was added to the original code.  if using
        // legacy code, should see no change as r will be undefined
        var r = o.oneditfunc.call($t, rowid);

        // if get a return value, this indicates you want to set focus
        if (r && r[0])
        {
            var focusIndex = focus;
            var i = 0;

            // look for the field name that was clicked on
            // cm, which is built above, has no index value associated
            // with it, so we must keep track of
            var focusField = $.grep(cm, function(c)
            {
                // find the field name which was clicked on
                if (c.name == r[0].name)
                    focusIndex = i;

                i++;

                return c.name == r[0].name;
            });

            // if the field is editable, then update focus index
            // which is defined above
            if (focusField[0].editable)
            {
                focus = focusIndex;
            }
        }
    }

最优雅的解决方案?可能不是,但它确实允许所有遗留代码工作并找出点击了哪个字段,因此可以设置焦点

答案 1 :(得分:0)

不幸的是,网格只能将焦点设置到行中的第一个可编辑字段。您可以在grid.inlinedit.js的源代码中看到这一点。在这里,它通过迭代它们并找到第一个来计算要设置焦点的行的索引:

if(cm[i].editable===true) {
    if(focus===null) { focus = i; }

以及之后的重点:

$("td:eq("+focus+") input",ind).focus();

选择存储在focus变量中的索引处的元素 - 供参考,请参阅:eq selector文档。

那就是说,如果你是如此倾向,你可以编辑这段代码来添加你自己的自定义逻辑来控制哪个元素获得焦点......

答案 2 :(得分:0)

我同意Justin的观点,即jqGrid并不直接支持您所需要的行为。你可以收到的需要的方式可能更复杂,只是jqGrid的一个选项。从the code查看the answer。我希望它会对你有所帮助。

答案 3 :(得分:0)

这是jqGrid的严重缺陷。 如果网格比窗口宽,则还需要向右滚动以使单击的单元格可见。为此,您可以使用来自的代码 http://www.trirand.com/blog/?page_id=393/help/inline-edit-problem-with-scrolling/

        if (rowID && rowID !== lastSelectedRow) {
           var scrollPosition = 0;
           scrollPosition = grid2.closest(".ui-jqgrid-bdiv").scrollLeft();
            grid2.jqGrid('restoreRow', lastSelectedRow);
            grid.jqGrid('editRow', rowID, true);
            lastSelectedRow = rowID;
            setTimeout(function(){ 
              grid2.closest(".ui-jqgrid-bdiv").scrollLeft(scrollPosition);
              },100); 

答案 4 :(得分:0)

就我而言,我使用了Justin Ethier和Steve的答案来提出我自己的解决方案(对于jqGrid 4.4.3):

在jqGrid的源代码中,我只注释掉以下行(这是为了防止编辑行的第一个输入接收焦点):

// commented out 
// $("td:eq("+focus+") input",ind).focus();

然后,我创建一个全局js变量,它将保持网格上点击的来源:

var clickedCell;

最后,在单击单元格时设置该变量。

$('#myJqGrid td').on('click', function(e){ clickedCell = this; });

为了能够将事件附加到表格单元格,我们需要确保网格已经创建,因此必须在" gridComplete"中完成。 jqGrid的功能,例如:

$('#myJqGrid').jqGrid('setGridParam', {
    gridComplete: function(id){ 
                      $('#myJqGrid td').on('click', function(e){  clickedCell = this; });
                  }
});

最后,在编辑行时,我检索单击的单元格(保存在变量" clickedCell"),并将焦点放在其中的输入或文本区域。这必须在" onSelectRow" jqGrid的功能:

$('#myJqGrid').jqGrid('setGridParam', 
                          { 
                             onSelectRow : function(id) {
                                 ... 
                                 //switching the selected row to editmode
                                 $('#myJqGrid').jqGrid(
                                    'editRow', 
                                    id, 
                                    {
                                       keys: true,
                                       // when editing the row, give the focus to the input
                                       //or textarea within the last clicked cell
                                       oneditfunc: function() {
                                           $('input, textarea', clickedCell).focus();
                                    }
                                 );
                                 ...
                             }
                          }
                       });

唯一的问题是,在没有触及jqGrid的源代码的情况下,确实没有解决方案。如果你没有,它仍然可以工作,但是第一个输入仍然会首先获得焦点,即使在分配了正确的焦点之后也会移动页面的水平滚动。

答案 5 :(得分:0)

我在另一个与stackoverflow相关的问题中发布了这个答案。希望这适用于你。

我以某种方式通过将dblclick事件附加到表的每个td来成功完成此操作,我知道这不是最好的方法,但您可以随意优化它,您也可以忽略使用的setTimeout仅用于测试。

 $("#jqGrid").on("dblclick", "td", function (event) {   
                 //   setTimeout(function () {
                        console.log(this);
                        $(event.target).find("input,select").focus();                     
                  //  }, 0);
                });

希望这会对你有所帮助。