Javascript 使 ExtJS GridPanel 的某些单元格不可编辑

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2269817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:32:48  来源:igfitidea点击:

making certain cells of an ExtJS GridPanel un-editable

javascriptgridviewextjs

提问by Alex Wood

I currently have a GridPanel with the Ext.ux.RowEditor plugin. Four fields exist in the row editor: port, ip address, subnet and DHCP. If the DHCP field (checkbox) of the selected row is checked, I need to make the other three fields un-editable.

我目前有一个带有 Ext.ux.RowEditor 插件的 GridPanel。行编辑器中有四个字段:端口、IP 地址、子网和 DHCP。如果选中行的 DHCP 字段(复选框),我需要使其他三个字段不可编辑。

I've been trying to perform this code when the beforeedit event is triggered, but to no avail... I've only found ways to make the entire column un-editable. My code so far:

我一直在尝试在触发 beforeedit 事件时执行此代码,但无济于事......我只找到了使整个列不可编辑的方法。到目前为止我的代码:

this.rowEditor.on({
    scope: this,
    beforeedit: this.checkIfEditable
});

checkIfEditable:function(rowEditor, rowIndex) {
    if(this.getStore().getAt(rowIndex).get('dhcp')) {
        // this function makes the entire column un-editable:
        this.getColumnModel().setEditable(2, false); 

        // I want to make only the other three fields of the current row 
        // uneditable.
    }
 }

Please let me know if any clarification is needed.

如果需要澄清,请告诉我。

Any help potentially extending RowEditor to accomplish the target functionality would be greatly appreciated as well!

任何可能扩展 RowEditor 以完成目标功能的帮助也将不胜感激!

回答by Patrick

You can add into RowEditor.js within the function startEditingthe call to the function isCellEditable

您可以将函数startEditing调用添加到 RowEditor.js函数中isCellEditable

//.... RowEditor.js
startEditing: function(rowIndex, doFocus){
//.... search for the starting of the below loop into the source code
            var cm = g.getColumnModel(), fields = this.items.items, f, val;
            for(var i = 0, len = cm.getColumnCount(); i < len; i++){
                val = this.preEditValue(record, cm.getDataIndex(i));
                f = fields[i];
                f.setValue(val);

                // *** here add a call to isCellEditable *** //
                f.setDisabled(!cm.isCellEditable(i, rowIndex));
                // ***************************************** //

                this.values[f.id] = Ext.isEmpty(val) ? '' : val;
            }
//....

Then override the isCellEditableof your column model and disabled the field based on you condition:

然后覆盖isCellEditable您的列模型并根据您的条件禁用该字段:

YYY.getColumnModel().isCellEditable = function(colIndex, rowIndex){
 if (grid.getStore().getAt(rowIndex).get('dhcp')) {
    // you can do more check base on colIndex
    // only to disabled the one you want
    return false; 
  }
  return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, colIndex, rowIndex);
}

回答by Shea Frederick

As the docs state:

正如文档所述:

If the listener returns false the editor will not be activated.

如果侦听器返回 false,则不会激活编辑器。

So...

所以...

this.rowEditor.on({
      scope: this,
     beforeedit: this.checkIfEditable
});

checkIfEditable:function(rowEditor, rowIndex) {
         if(this.getStore().getAt(rowIndex).get('dhcp')) {

             return false; 

         }
 }

Simply returning false will be enough to cancel the editing ability.

简单地返回 false 就足以取消编辑能力。



Gotcha.

明白了。

Interesting idea - a bit of a hassle to implement, but possible.

有趣的想法 - 实施有点麻烦,但可能。

You need to approach this from two directions:

你需要从两个方向来解决这个问题:

1 ) edit starts

1 ) 编辑开始

2 ) checkbox is checked/unchecked

2)复选框被选中/取消选中

For the first part, I think you could use almost the same code I have above, remove the 'return false' and use the reference to the rowEditor to loop through the items collection, disabling (call the disable method on them) the fields that are not your checkbox field.

对于第一部分,我认为您可以使用与上面几乎相同的代码,删除“return false”并使用对 rowEditor 的引用来循环遍历项目集合,禁用(对它们调用 disable 方法)字段不是您的复选框字段。

The second part of this is to add a handler to the checkbox which would do the same thing.

第二部分是向复选框添加一个处理程序,它会做同样的事情。

回答by Allie

The following works to make a specific cell uneditable (add the event to the roweditor):

以下工作使特定单元格不可编辑(将事件添加到行编辑器):

    beforeedit: function (roweditor, rowIndex) {
        var data = roweditor.grid.store.getAt(rowIndex).data;
        var cm = roweditor.grid.getColumnModel();

        // disable the first column (can not be edited)
        if (** make your check here ***) {
            var c = cm.getColumnAt(0);
            c.editor.disable();
        }
        roweditor.initFields();
    }

回答by CaptainPlinky

As of ExtJS 3.4 you can just override isCellEditable, as in the example here:

从 ExtJS 3.4 开始,您可以只覆盖 isCellEditable,如下例所示:

http://docs.sencha.com/ext-js/3-4/#!/api/Ext.grid.ColumnModel-method-isCellEditable

http://docs.sencha.com/ext-js/3-4/#!/api/Ext.grid.ColumnModel-method-isCellEditable

回答by Snehal Masne

Here's the simpler version :

这是更简单的版本:

http://jsfiddle.net/snehalmasne/8twwywcp/

http://jsfiddle.net/snehalmasne/8twwywcp/

plugins: [
    Ext.create('Ext.grid.plugin.CellEditing', {
        clicksToEdit: 1
        ,pluginId: 'editing'
    })
]

Provide the condition below for the cells to make the un-editable :

为单元格提供以下条件以使其不可编辑:

grid.on('beforeedit', function(editor, e) {
  if (e.record.get('phone') == '555-111-1224')
    return false;
});

回答by Tim

Using Ext JS 4 and the RowEditing plugin i managed to achieve this using something like

使用 Ext JS 4 和 RowEditing 插件,我设法使用类似

rowEditor.on('beforeedit', function (context) {
       this.editor.query('textfield')[0].setDisabled(/* your condition here */);
});

the record data is available through context.record.data

记录数据可通过 context.record.data 获得

回答by Tracker1

just set the column in your columnModel/columns to editable:false for fields that should not be editable.

对于不应可编辑的字段,只需将 columnModel/columns 中的列设置为 editable:false。

columns: [ 
  { header: "Ticker", width: 60, editable:false },
  { header: "Company Name", width: 150, id: 'company'},
  { header: "Market Cap."},
  { header: "$ Sales", renderer: money},
  { header: "Employees", resizable: false}
]

回答by jearlu

I ran into the same problem. Rather than using the GridPanel with the Ext.ux.RowEditor plugin, I used the Ext.grid.EditorGridPanel. In this case, you can specify the editor for each of the other three fields (port, ip address, and subnet) in the column model with a beforeshow event handler as follows:

我遇到了同样的问题。我没有使用带有 Ext.ux.RowEditor 插件的 GridPanel,而是使用了 Ext.grid.EditorGridPanel。在这种情况下,您可以使用 beforeshow 事件处理程序为列模型中的其他三个字段(端口、IP 地址和子网)中的每一个指定编辑器,如下所示:

  editor: new Ext.form.TextArea({
    height:80,
    allowBlank: false,
    listeners:{
      beforeshow: function(column) {
        if (column.gridEditor.record.get('dhcp')) {
          column.gridEditor.cancelEdit();
        }
      }
    }
  })

回答by David Jacob Jarquin

Ha! I made a dirty one, I added an event this.fireEvent('starting', this, fields,record); AT THE END of startEditing

哈!我做了一个脏的,我添加了一个事件 this.fireEvent('starting', this, fields,record); 在开始的最后编辑

startEditing: function(rowIndex, doFocus){
    if(this.editing && this.isDirty()){
        this.showTooltip(this.commitChangesText);
        return;
    }
    if(Ext.isObject(rowIndex)){
        rowIndex = this.grid.getStore().indexOf(rowIndex);
    }
    if(this.fireEvent('beforeedit', this, rowIndex) !== false){
        this.editing = true;
        var g = this.grid, view = g.getView(),
            row = view.getRow(rowIndex),
            record = g.store.getAt(rowIndex);

        this.record = record;
        this.rowIndex = rowIndex;
        this.values = {};
        if(!this.rendered){
            this.render(view.getEditorParent());
        }
        var w = Ext.fly(row).getWidth();
        this.setSize(w);
        if(!this.initialized){
            this.initFields();
        }
        var cm = g.getColumnModel(), fields = this.items.items, f, val;
        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
            val = this.preEditValue(record, cm.getDataIndex(i));
            f = fields[i];
            f.setValue(val);
            this.values[f.id] = Ext.isEmpty(val) ? '' : val;
        }
        this.verifyLayout(true);
        if(!this.isVisible()){
            this.setPagePosition(Ext.fly(row).getXY());
        } else{
            this.el.setXY(Ext.fly(row).getXY(), {duration:0.15});
        }
        if(!this.isVisible()){
            this.show().doLayout();
        }
        if(doFocus !== false){
            this.doFocus.defer(this.focusDelay, this);
        }
        /*I ADDED THIS EVENT ---- contains the fields and record

*/ this.fireEvent('starting', this, fields,record); } }

*/ this.fireEvent('starting', this, fields,record); } }

THEN

然后

var editor = new Ext.ux.grid.RowEditor({
    saveText: 'Update',
    listeners : {
        'starting' : function(rowEditor, fields, record){
            if(!record.data.equipo_id){
                fields[4].setDisabled(false);
            }else{
                fields[4].setDisabled(true);
            }
        },