如何关闭单元格编辑器?

Posted

技术标签:

【中文标题】如何关闭单元格编辑器?【英文标题】:How to close cell-editor? 【发布时间】:2012-03-19 12:21:46 【问题描述】:

使用jqGrid我想在双击上打开一个单元格编辑器,所以我的代码包括这部分:

  ondblClickRow: function(rowid, iRow, iCol, e)
  
    jQuery('#jqGrid').setGridParam(cellEdit: true);
    jQuery('#jqGrid').editCell(iRow, iCol, true);
    jQuery('#jqGrid').setGridParam(cellEdit: false);
  

效果很好,但我不知道如何(自动)关闭单元格编辑器,当用户单击编辑元素外部或按 ESCTAB、回车等...

【问题讨论】:

【参考方案1】:

问题是您尝试在不支持的情况下实现双击单元格编辑。您当前的代码不起作用,因为如果用户按 TabEnterEscnextCellprevCell、@987654326 @ 或restoreCell 将被真正调用,但方法内部测试cellEdit 参数是否为true

为了展示如何解决我创建的the demo 使用以下代码的问题:

cellsubmit: 'clientArray',
ondblClickRow: function (rowid, iRow, iCol) 
    var $this = $(this);

    $this.jqGrid('setGridParam', cellEdit: true);
    $this.jqGrid('editCell', iRow, iCol, true);
    $this.jqGrid('setGridParam', cellEdit: false);
,
afterEditCell: function (rowid, cellName, cellValue, iRow) 
    var cellDOM = this.rows[iRow], oldKeydown,
        $cellInput = $('input, select, textarea', cellDOM),
        events = $cellInput.data('events'),
        $this = $(this);
    if (events && events.keydown && events.keydown.length) 
        oldKeydown = events.keydown[0].handler;
        $cellInput.unbind('keydown', oldKeydown);
        $cellInput.bind('keydown', function (e) 
            $this.jqGrid('setGridParam', cellEdit: true);
            oldKeydown.call(this, e);
            $this.jqGrid('setGridParam', cellEdit: false);
        );
    

已更新:如果您想在用户单击任何其他单元格时放弃或保存最后的编辑更改,则应使用以下代码扩展代码:

beforeSelectRow: function (rowid, e) 
    var $this = $(this),
        $td = $(e.target).closest('td'),
        $tr = $td.closest('tr'),
        iRow = $tr[0].rowIndex,
        iCol = $.jgrid.getCellIndex($td);

    if (typeof lastRowIndex !== "undefined" && typeof lastColIndex !== "undefined" &&
            (iRow !== lastRowIndex || iCol !== lastColIndex)) 
        $this.jqGrid('setGridParam', cellEdit: true);
        $this.jqGrid('restoreCell', lastRowIndex, lastColIndex, true);
        $this.jqGrid('setGridParam', cellEdit: false);
        $(this.rows[lastRowIndex].cells[lastColIndex])
            .removeClass("ui-state-highlight");
    
    return true;

The new demo 显示结果。

更新 2:或者,您可以使用 focusout 放弃或保存最后的编辑更改。见one more demo使用代码:

ondblClickRow: function (rowid, iRow, iCol) 
    var $this = $(this);

    $this.jqGrid('setGridParam', cellEdit: true);
    $this.jqGrid('editCell', iRow, iCol, true);
    $this.jqGrid('setGridParam', cellEdit: false);
,
afterEditCell: function (rowid, cellName, cellValue, iRow, iCol) 
    var cellDOM = this.rows[iRow].cells[iCol], oldKeydown,
        $cellInput = $('input, select, textarea', cellDOM),
        events = $cellInput.data('events'),
        $this = $(this);
    if (events && events.keydown && events.keydown.length) 
        oldKeydown = events.keydown[0].handler;
        $cellInput.unbind('keydown', oldKeydown);
        $cellInput.bind('keydown', function (e) 
            $this.jqGrid('setGridParam', cellEdit: true);
            oldKeydown.call(this, e);
            $this.jqGrid('setGridParam', cellEdit: false);
        ).bind('focusout', function (e) 
            $this.jqGrid('setGridParam', cellEdit: true);
            $this.jqGrid('restoreCell', iRow, iCol, true);
            $this.jqGrid('setGridParam', cellEdit: false);
            $(cellDOM).removeClass("ui-state-highlight");
        );
    

更新 3:从 jQuery 1.8 开始,应该使用 $._data($cellInput[0], 'events'); 而不是 $cellInput.data('events') 来获取 $cellInput 的所有事件列表。

【讨论】:

看起来不错,但是当用户单击活动单元格外部或网格组件外部时,是否可以添加一个功能,该活动内联编辑器会自行关闭? @***:这也是可能的。请参阅答案和新演示的“更新”部分。 大进步!但是当我单击单元格或行之外(例如网格工具栏、网格列标题等)或网格之外时,内联编辑器仍然处于活动状态并且不会关闭。是否也可以添加这样的功能?谢谢。 @***:一切皆有可能:请参阅我答案的“更新 2”部分。【参考方案2】:

声明公共变量:-

  var lastRowId=-1;

   $(document).ready(function() 
          // put all your jQuery goodness in here.
    );
 .
 .
 .
 .

  ondblClickRow: function(rowid, iRow, iCol, e)
   
      if(lastRowId!=-1)
         $("#jqGrid").saveRow(lastRowId, true, 'clientArray');
      $('#jqGrid').setGridParam(cellEdit: true);
      $('#jqGrid').editCell(iRow, iCol, true);
      lastRowId= rowid;

  

在您想要完成编辑之后

          $("#jqGrid").saveRow(jqMFPLastRowId, true, 'clientArray');




                    (or)

================================================ ==============================

声明公共变量:-

  var lastRowId=-1;
  $(document).ready(function() 
          // put all your jQuery goodness in here.
    );
 .
 .
 .
 .
  ondblClickRow: function (rowid, iRow, iCol) 
        var $this = $(this);
        $this.jqGrid('setGridParam', cellEdit: true);
        $this.jqGrid('editCell', iRow, iCol, true);
        $this.jqGrid('setGridParam', cellEdit: false);
        lastRowId=rowid;
   ,

  afterEditCell: function (rowid, cellName, cellValue, iRow) 
   if(lastRowId!=-1)
        $("#jqGrid").saveRow(lastRowId, true, 'clientArray');

【讨论】:

【参考方案3】:
// This worked Perfectly fine for me, hope will work for you as well.
var selectedCellId;
    var $gridTableObj = $('#jqGridTable');
    $gridTableObj.jqGrid(
        datatype : "jsonstring",
        datastr : gridJSON,
        height : ($(window).height() - 110),
        width : ($(window).width() - 80),
        gridview : true,
        loadonce : false,
        colNames : columnNames,
        colModel : columnModel,
        rowNum : gridJSON.length,
        viewrecords : true,
        subGrid : false,
        autoheight : true,
        autowidth : false,
        shrinkToFit : true,
        cellsubmit : 'clientArray',
        cellEdit : true,
        jsonReader : 
            root : "rows",
            repeatitems : false
        ,
        onCellSelect : function(id, cellidx, cellvalue)  // use this event to capture edited cellID
            selectedCellId = cellidx; // save the cellId to a variable
        ,
        loadComplete : function(data) 
            jQuery("tr.jqgrow:odd").addClass("oddRow");
            jQuery("tr.jqgrow:even").addClass("evenRow");
        
    );

// 附加点击事件 jqgrid "saveCell" 保存单元格。

var gridCellWasClicked = false;
window.parent.document.body.onclick = saveEditedCell; // attach to parent window if any
document.body.onclick = saveEditedCell; // attach to current document.
function saveEditedCell(evt) 
    var target = $(evt.target);
    var isCellClicked = $gridTableObj.find(target).length; // check if click is inside jqgrid
    if(gridCellWasClicked && !isCellClicked) // check if a valid click
        
        var rowid = $gridTableObj.jqGrid('getGridParam', 'selrow');
    $gridTableObj.jqGrid("saveCell", rowid, selectedCellId);
    gridCellWasClicked = false;
    
    if(isCellClicked)
        gridCellWasClicked = true; // flat to check if there is a cell been edited.
    
;

【讨论】:

以上是关于如何关闭单元格编辑器?的主要内容,如果未能解决你的问题,请参考以下文章

excel如何退出编辑状态

当我输入保存时,防止在单元格编辑时进行两次保存调用[关闭]

easyui datagrid 单元格关闭编辑框再开启编辑框就报错

在单元格内编辑textview时,将另一个单元格添加到tableview

如何使用自定义 JTable 单元格编辑器和单元格渲染器

如何使excel中的单元格不可编辑