PDA

View Full Version : [UNKNOWN][3.0.0] EditorGrid Tab Key navigation with RowSelection Model



NOSLOW
28 Aug 2009, 2:00 AM
The tabbing doesn't behave properly when using
selModel: new Ext.grid.RowSelectionModel() and dynamically controlling edit behavior of individual cells via the grid's 'beforeedit' event. Here's a slightly modified version of the classic editor grid example to demonstrate this. Just hit the tab key 2-3 times after the grid loads with data and you'll see that you lose the order of tabbing beyond the first non-editable cell (the price field on the first row):



<html>
<head>
<base href="http://extjs.com/deploy/ext-3.0.0/examples/grid/" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Editor Grid Example</title>

<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

<!-- overrides to base library -->

<!-- page specific -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<style type="text/css">

</style>

<!-- ** Javascript ** -->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>

<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="../../ext-all.js"></script>

<!-- overrides to base library -->

<!-- extensions -->
<script type="text/javascript" src="../ux/CheckColumn.js"></script>

<!-- page specific -->

<script type="text/javascript" src="../shared/examples.js"></script>
<!-- <script type="text/javascript" src="edit-grid.js"></script> -->

<script type="text/javascript">
/*!
* Ext JS Library 3.0+
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){

/**
* Handler specified for the 'Available' column renderer
* @param {Object} value
*/
function formatDate(value){
return value ? value.dateFormat('M d, Y') : '';
}

// shorthand alias
var fm = Ext.form;

// the check column is created using a custom plugin
var checkColumn = new Ext.grid.CheckColumn({
header: 'Indoor?',
dataIndex: 'indoor',
width: 55
});

// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel({
// specify any defaults for each column
defaults: {
sortable: true // columns are not sortable by default
},
columns: [
{
id: 'common',
header: 'Common Name',
dataIndex: 'common',
width: 220,
// use shorthand alias defined above
editor: new fm.TextField({
allowBlank: false
})
}, {
header: 'Light',
dataIndex: 'light',
width: 130,
editor: new fm.ComboBox({
typeAhead: true,
triggerAction: 'all',
// transform the data already specified in html
transform: 'light',
lazyRender: true,
listClass: 'x-combo-list-small'
})
}, {
header: 'Price',
dataIndex: 'price',
width: 70,
align: 'right',
renderer: 'usMoney',
editor: new fm.NumberField({
allowBlank: false,
allowNegative: false,
maxValue: 100000
})
}, {
header: 'Available',
dataIndex: 'availDate',
width: 95,
renderer: formatDate,
editor: new fm.DateField({
format: 'm/d/y',
minValue: '01/01/06',
disabledDays: [0, 6],
disabledDaysText: 'Plants are not available on the weekends'
})
},
checkColumn // the plugin instance
]
});

// create the Data Store
var store = new Ext.data.Store({
// destroy the store if the grid is destroyed
autoDestroy: true,

// load remote data using HTTP
url: 'http://extjs.com/deploy/ext-3.0.0/examples/grid/plants.xml',

// specify a XmlReader (coincides with the XML format of the returned data)
reader: new Ext.data.XmlReader({
// records will have a 'plant' tag
record: 'plant',
// use an Array of field definition objects to implicitly create a Record constructor
fields: [
// the 'name' below matches the tag name to read, except 'availDate'
// which is mapped to the tag 'availability'
{name: 'common', type: 'string'},
{name: 'botanical', type: 'string'},
{name: 'light'},
{name: 'price', type: 'float'},
// dates can be automatically converted by specifying dateFormat
{name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y'},
{name: 'indoor', type: 'bool'}
]
}),

sortInfo: {field:'common', direction:'ASC'}
});

// create the editor grid
var grid = new Ext.grid.EditorGridPanel({
selModel: new Ext.grid.RowSelectionModel(), // NOSLOW
id: 'broken-tabbing',
store: store,
cm: cm,
renderTo: 'editor-grid',
width: 600,
height: 300,
autoExpandColumn: 'common', // column with this id will be expanded
title: 'Modified - Edit Plants?',
frame: true,
// specify the check column plugin on the grid so the plugin is initialized
plugins: checkColumn,
clicksToEdit: 1,
tbar: [{
text: 'Add Plant',
handler : function(){
// access the Record constructor through the grid's store
var Plant = grid.getStore().recordType;
var p = new Plant({
common: 'New Plant 1',
light: 'Mostly Shade',
price: 0,
availDate: (new Date()).clearTime(),
indoor: false
});
grid.stopEditing();
store.insert(0, p);
grid.startEditing(0, 0);
}
}]

,listeners: {// NOSLOW
beforeedit: function(e) {
switch (e.field) {
case 'price':
if (e.record.data.light == 'Shade') {
return false;
}
}
}
}
});

// manually trigger the data store load
store.load({
// store loading is asynchronous, use a load listener or callback to handle results
callback: function(){
Ext.getCmp('broken-tabbing').startEditing(0,0);
}
});
});
</script>

</head>
<body>
<h1>Editor Grid Example</h1>
<p>This example shows how to create a grid with inline editing.</p>
<p>Note that the js is not minified so it is readable. See <a href="edit-grid.js">edit-grid.js</a>.</p>


<p>The data in the grid is loaded from <a href="plants.xml">plants.xml</a>.</p>

<!-- the custom editor for the 'Light' column references the id="light" -->
<select name="light" id="light" style="display: none;">
<option value="Shade">Shade</option>
<option value="Mostly Shady">Mostly Shady</option>
<option value="Sun or Shade">Sun or Shade</option>

<option value="Mostly Sunny">Mostly Sunny</option>
<option value="Sunny">Sunny</option>
</select>

<div id="editor-grid"></div>
</body>
</html>


Thanks,
NOSLOW

mystix
28 Aug 2009, 2:36 AM
slightly off-topic question:
what's the use case for using a RowSelectionModel with an EditorGrid?

NOSLOW
28 Aug 2009, 3:30 AM
I have drag and drop enabled to re-order the rows.

mystix
28 Aug 2009, 4:05 AM
I have drag and drop enabled to re-order the rows.

so a single mousedown starts a drag while a double-click starts a cell edit?

mystix
28 Aug 2009, 4:07 AM
additionally, are you trying your test case against SVN HEAD or the official 3.0.0 download?
(btw, 3.0.1 has been released to all support subscription members already, so you might want to check that out if you're able to)

NOSLOW
28 Aug 2009, 4:45 AM
Actually, "mouse-down-drag-begin" will start the dragging. Single mouse click (no drag movement) will enable the editor. It's works pretty nice that way.

NOSLOW
12 Sep 2009, 7:18 AM
Same behavior is experienced in v3.0.1.

I like how in row selection mode, you can click in any editable cell and invoke that cell's editor, and then tab to the next editable cell (ones that has a configured editor) with the editor invoked, yet skips over read-only cells (ones that DO NOT have an editor configured).

I don't like how in cell selection mode that tabbing through an editor grid visits every cell, even cells that don't have editors. Whenever you hit one of these read-only cells, you then have to manually invoke the editor on the next editable cell. Take for example a grid with 10 columns, and only one column is editable. You wouldn't want to have to hit the TAB key 9 times to get to the next editable cell, right?

Simply put, Editor grids should have these options, independent of row selection model:

1. invokeEditorOnFocus: true/false
2. tabOverReadOnlyCells: true/false

And when I say &quot;ReadOnlyCells&quot;, I mean columns that don't have editors configured, AND dynamically set read-only cells that use the editor grid's beforeedit eventhandler and dynamically returns false under certain conditions to disable the editor for that cell only.

I'd like to hear opinions on this

angelflaree
14 Sep 2009, 3:08 PM
I found an issue related to RowSelectionModel too.

I have a grid that has one column editable. Previously (before using Ext3.0.1) when I'm using Ext 2.X or Ext 3.0, I'm always able to enter value all through the rows by using "ENTER" key. That is, I can enter value in the 1st row no matter the new value is the same as the old value or not, then hit ENTER key and the grid automatically focus to the cell in the same column 2nd row, there I can continue entering value. I didn't do any extra coding, this seems to be the default behavior in grid.

Now when I hit ENTER key, the grid just stop editing the 1st row and doesn't bring focus to the 2nd row. I am not sure if this is the desired change for Ext 3.0.1.