1. #1
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default Answered: I want my selected grid rows to remain selected. Even if I'm editing a cell. But no..

    Answered: I want my selected grid rows to remain selected. Even if I'm editing a cell. But no..


    So, I have a grid. I have a thousand rows selected, and it took me an hour to pick out the right ones. See below (only five rows pictured, obviously)

    1.png

    Now, imagine I want to change that "asdf" to "asdfg" using the nifty cell editor. No problem! I'll just click it, and...
    2.png

    $%*@... why did that happen? Where are my selections? It looks like Extjs is trying to be obnoxiously helpful.

    How can I prevent a cell editor click from messing with my selections?

    Yours Truly,
    -Kramer

  2. You would have to override the selection model and check if the mouse down was over a certain element.

    The issue with selection vs editing is the selection is done in the mousedown event where edit is either in the click or dblclick event so the selection is always going to happen before the editor even knows what's going on.

  3. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,327
    Answers
    3540
    Vote Rating
    850
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    The reason is because when you are editing you click on the grid row causing the grid to select that row.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  4. #3
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default


    Thanks Mitchell. I figured as much. Is Extjs capable of ignoring such clicks when they are for the purpose of cell editing? Could Extjs keep row selection state unchanged for all actions except for clicking the checkbox column? That would be spectacular.

  5. #4
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,327
    Answers
    3540
    Vote Rating
    850
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    You would have to override the selection model and check if the mouse down was over a certain element.

    The issue with selection vs editing is the selection is done in the mousedown event where edit is either in the click or dblclick event so the selection is always going to happen before the editor even knows what's going on.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  6. #5
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default


    Ah! Gracias, SeƱor Forum Manager! Buenos huevos.

  7. #6
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default


    After some time, I realized that your suggestion sounds a lot like the checkOnly option of Ext.selection.CheckboxModel. But I'm already using that option.

    Also, when I change my clicksToEdit option on my Ext.grid.plugin.CellEditing plugin to "2", the first click has no effect on the selection of any rows in my grid.

    Both of these clues lead me to believe that the selection model is not what is causing the problem here.

    So, what is?

    Well, with clicksToEdit set to "2", I double-click on a cell to edit it, and Bam! As the cell editor appears, all rows deselect, and the row I'm editing within selects.

    So, I think it's Ext.grid.plugin.CellEditing that's causing this. I did some investigation.

    Here is Ext.grid.plugin.CellEditing.startEdit()
    Code:
    startEdit: function(record, columnHeader) {
        // ... snip ...
        me.grid.view.cancelFocus();
        me.view.focusCell({
            row: context.rowIdx,
            column: context.colIdx
        });
        ed = false;
        if (ed) {
            me.editTask.delay(15, me.showEditor, me, [ed, context, value]);
            return true;
        }
        return false;
    }
    If I add the line above (in red) "ed = false;" then row selection remains unchanged, but the cell editor doesn't appear, which is still a problem.

    Why is the cell editor messing with row selections? What can we do about this?

    Thanks again,
    -Kramer

  8. #7
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default Solution

    Solution


    In the absence of an official solution, I developed this extension to Ext.grid.plugin.CellEditing. It works pretty well.

    Code:
    Ext.define('Ext.grid.plugin.CellEditing', {
        extend: 'Ext.grid.plugin.CellEditing',
        toReselectAfterEdit: [],
       
        showEditor: function(ed, context, value) {
            var xsm = this.grid.getSelectionModel();
            //if (typeof(this.toReselectAfterEdit) == 'undefined') this.toReselectAfterEdit = [];
            if (xsm.isSelected(context.record)) this.toReselectAfterEdit.push(context.record);
            
            var me = this,
                record = context.record,
                columnHeader = context.column,
                sm = me.grid.getSelectionModel(),
                selection = sm.getCurrentPosition();
    
            me.context = context;
            me.setActiveEditor(ed);
            me.setActiveRecord(record);
            me.setActiveColumn(columnHeader);
    
            /*
            if (sm.selectByPosition && (!selection || selection.column !== context.colIdx || selection.row !== context.rowIdx)) {
                sm.selectByPosition({
                    row: context.rowIdx,
                    column: context.colIdx
                });
            }
            */
    
            ed.startEdit(me.getCell(record, columnHeader), value);
            me.editing = true;
            me.scroll = me.view.el.getScroll();
        },
        
        completeEdit: function() {
            this.callParent(arguments);
            this.reselectRowsThatShouldNeverHaveBeenDeselected();
        },
        
        onEditComplete: function() {
            this.callParent(arguments);
            this.reselectRowsThatShouldNeverHaveBeenDeselected();
        },
        
        reselectRowsThatShouldNeverHaveBeenDeselected: function() {
            if (this.toReselectAfterEdit) {
                var record;
                while (record = this.toReselectAfterEdit.pop()) {
                    this.grid.getSelectionModel().deselect(record);
                    this.grid.getSelectionModel().select(record, true);
                }
            }
        }
    });

  9. #8
    Sencha Premium Member
    Join Date
    Nov 2012
    Location
    GER
    Posts
    10
    Answers
    1
    Vote Rating
    0
    m.k is on a distinguished road

      0  

    Default


    You should avoid using toReselectAfterEdit: [] in the Class definition, because this Array reference is shared between all instances of the Class through their prototype.
    Try to always initialize reference type class members inside the constructor.

  10. #9
    Sencha User
    Join Date
    Aug 2012
    Posts
    10
    Vote Rating
    0
    JPKramer707 is on a distinguished road

      0  

    Default Revised Solution

    Revised Solution


    Thanks m.k, you're right. Cleaned up version is here:

    Code:
    Ext.define('Ext.grid.plugin.CellEditing', {
        extend: 'Ext.grid.plugin.CellEditing',
        
        constructor: function() {
            this.callParent(arguments);
            this.toReselectAfterEdit = [];
        },
       
        showEditor: function(ed, context, value) {
            var me = this,
                record = context.record,
                columnHeader = context.column,
                sm = me.grid.getSelectionModel(),
                selection = sm.getCurrentPosition();
    
            if (sm.isSelected(context.record)) this.toReselectAfterEdit.push(context.record);
            me.context = context;
            me.setActiveEditor(ed);
            me.setActiveRecord(record);
            me.setActiveColumn(columnHeader);
    
            /*
            // The absence of this piece of code from the parent method is key. 
            if (sm.selectByPosition && (!selection || selection.column !== context.colIdx || selection.row !== context.rowIdx)) {
                sm.selectByPosition({
                    row: context.rowIdx,
                    column: context.colIdx
                });
            }
            */
    
            ed.startEdit(me.getCell(record, columnHeader), value);
            me.editing = true;
            me.scroll = me.view.el.getScroll();
        },
        
        completeEdit: function() {
            this.callParent(arguments);
            this.reselectRowsThatShouldNeverHaveBeenDeselected();
        },
        
        onEditComplete: function() {
            this.callParent(arguments);
            this.reselectRowsThatShouldNeverHaveBeenDeselected();
        },
        
        reselectRowsThatShouldNeverHaveBeenDeselected: function() {
            if (this.toReselectAfterEdit) {
                var record;
                while (record = this.toReselectAfterEdit.pop()) {
                    this.grid.getSelectionModel().deselect(record);
                    this.grid.getSelectionModel().select(record, true);
                }
            }
        }
    });

Thread Participants: 2