REQUIRED INFORMATION

Ext version tested:
  • Ext 4.1.1
Browser versions tested against:
  • Chrome 22.0
  • Firefox 16.0.1
  • Safari 6.0.1
Description:

Select a row in grid panel with single selection mode, update the underlying record by calling record.set() in the select event handler, then the grid row selection will be gone, and click on that row again will not highlight it.

Steps to reproduce the problem:
  1. Create a grid panel with single selection mode
  2. Listen the select event of the grid panel
  3. In the select event handler, update the record by calling record.set(field, value)
The result that was expected:

After updating record, the grid row selection is preserved.

The result that occurs instead:


After updating record, the grid row selection is lost.

Test Case:
Code:
Ext.onReady(function() {
    var grid = Ext.create('Ext.grid.Panel', {
        store: {
            fields: ['id', 'value'],
            data: [
                {id: 1, value: 'initial value'},
                {id: 2, value: 'initial value'}
            ]
        },
        columns: [
            {text: 'id', dataIndex: 'id'},
            {text: 'value', dataIndex: 'value', flex: 1}           
        ],
        renderTo: Ext.getBody()
    });


    grid.on('select', function(selModel, record, index) {
        // ExtJS 4.1.1 Bug: select a row, update record, selection will be lost.
        setTimeout(function() {
            record.set('value', Math.random());
        }, 1000);
    });
});

HELPFUL INFORMATION

See this URL for live test case:
http://jsfiddle.net/jaux/5LFkv/

Possible fix:

I've found this issue is because of the incorrect removal of the x-grid-row-selected class of the grid row in Ext.view.Table.onUpdate(), here is my fix:
Code:
--- old/Table.js        2012-10-12 03:50:30.000000000 -0400
+++ new/Table.js        2012-10-12 03:51:09.000000000 -0400
@@ -700,8 +700,8 @@
             index,
             newRow, newAttrs, attLen, i, attName, oldRow, oldRowDom,
             oldCells, newCells, len, i,
-            columns, overItemCls,
-            isHovered, row,
+            columns,
+            row,
             // See if an editing plugin is active.
             isEditing = me.editingPlugin && me.editingPlugin.editing;
 
@@ -709,7 +709,6 @@
 
             index = me.store.indexOf(record);
             columns = me.headerCt.getGridColumns();
-            overItemCls = me.overItemCls;
 
             // If we have columns which may *need* updating (think lockable grid child with all columns either locked or unlocked)
             // and the changed record is within our view, then update the view
@@ -718,7 +717,6 @@
                 oldRow = me.all.item(index);
                 if (oldRow) {
                     oldRowDom = oldRow.dom;
-                    isHovered = oldRow.hasCls(overItemCls);
 
                     // Copy new row attributes across. Use IE-specific method if possible.
                     if (oldRowDom.mergeAttributes) {
@@ -728,16 +726,12 @@
                         attLen = newAttrs.length;
                         for (i = 0; i < attLen; i++) {
                             attName = newAttrs[i].name;
-                            if (attName !== 'id') {
+                            if (attName !== 'id' && attName !== 'class') {
                                 oldRowDom.setAttribute(attName, newAttrs[i].value);
                             }
                         }
                     }
 
-                    if (isHovered) {
-                        oldRow.addCls(overItemCls);
-                    }
-
                     // Replace changed cells in the existing row structure with the new version from the rendered row.
                     oldCells = oldRow.query(me.cellSelector);
                     newCells = Ext.fly(newRow).query(me.cellSelector);
Additional CSS used:
  • only default ext-all.css
Operating System:
  • OSX 10.8
  • Fedora 14