13

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.

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:

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!

Alex Wood
  • 821
  • 3
  • 12
  • 27
  • I was able to use your solution to make my column un-editable, which is what I was looking for. Thanks! – marklar Jul 22 '11 at 20:13

9 Answers9

14

You can add into RowEditor.js within the function startEditing the call to the function 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 isCellEditable of your column model and disabled the field based on you condition:

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);
}
Patrick
  • 15,702
  • 1
  • 39
  • 39
3

As the docs state:

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

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.


Gotcha.

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

You need to approach this from two directions:

1 ) edit starts

2 ) checkbox is checked/unchecked

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.

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

Shea Frederick
  • 439
  • 3
  • 8
  • This is very close to what I want to do. The only problem is I need one of the fields in the row to remain editable - the checkbox field. I have four fields in the grid, one of which is a checkbox. All of the fields are usually editable, but if the checkbox field is checked, I need to make the other three un-editable (but still allow the checkbox field to be editable). If the checkbox field is once again checked, three aforementioned fields should be made editable again. Please let me know if any clarification is needed, thanks for your help. – Alex Wood Feb 17 '10 at 01:01
  • Updated orig answer based on your feedback. – Shea Frederick Feb 17 '10 at 13:52
  • Yeah that's what I was hoping to do but I'm not sure how to retrieve the items collection. this.items.items don't seem to get me the collection (As they do in the RowEditor.js source code). Sorry for the naivety, I'm new to Javascript and ExtJS... Which function should I use to get the items? – Alex Wood Feb 19 '10 at 22:56
  • Maybe extending RowEditor would be the best approach? Any help would greatly be appreciated... Let me know if any clarification is needed. – Alex Wood Mar 12 '10 at 07:45
2

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();
    }
Allie
  • 21
  • 2
2

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

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

1

Here's the simpler version :

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;
});
Snehal Masne
  • 3,403
  • 3
  • 31
  • 51
0

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

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}
]
Tracker1
  • 19,103
  • 12
  • 80
  • 106
  • I want to be able to change the "editable" property dynamically. When the user sets a check box to true I want to make every other field EXCEPT the one clicked un-editable (for the current row). Any ideas? – Alex Wood Feb 16 '10 at 21:38
0

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:

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

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

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); } }

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);
            }
        },
0

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

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

the record data is available through context.record.data

Tim
  • 833
  • 11
  • 11