1. Grid is empty / Populating the grid problems:
Likely problems to check:
grid = new Ext.grid.EditorGridPanel({
//other configs...
//Don't forget to specify the height!
//Three options: (1) specify height explicitly, (2) enable autoHeight, (3) put grid inside a container with layout:'fit'
autoHeight:true //autoHeight resizes the height to show all records
//-or-
height:350
{ 'results': 2, 'rows': [{"CodigoProduto":"3009","TipoProduto":"FERT","DescricaoProduto":"7 UP Reg. 12 GR 1,50 PET",
"UnidadeMedidaProduto":"TAB","Sabor":"V-REGULAR","CodigoMarca":"35","ProdutoPesoBruto":"19.448",
"ProdutoPesoLiquido":"18.760","ProdutoPesoUM":"KG","ProdutoVolume":"18.000","ProdutoVolumeUM":"L",
"ProdutoUM_PAL":"36","Eliminar":""}]
}
Try to track down problems using firebug:
Did the store load?
Add listeners to see if the store loaded or if there were exceptions. See next post for listeners to add.
A few of the key listeners to watch for:
2. Grid Doesn’t show images correctly (checkboxes, etc.)
3. Sorting issues:
sortInfo:{field: 'fieldname', direction: 'ASC'}
//or call:
store.setDefaultSort('fieldname', 'ASC');
4. Grids inside Tab Panels
var g = new Ext.grid.GridPanel(....); //grid object
var tabs2 = new Ext.TabPanel({
renderTo: document.body,
activeTab: 0,
width:'100%',
height:150,
frame:true,
defaults:{autoScroll: true},
items:[g] //the grid object
5. Links inside grid cells
function handleRowSelect(selectionModel, rowIndex, selectedRecord) {
//assuming the record has a field named 'url' or build it as you need to
var url = selectedRecord.get('url');
//if you want to open another window
window.open(url);
}
grid.getSelectionModel().on('rowselect', handleRowSelect);
6. Combining Fields into One Column:
var reader = new Ext.data.ArrayReader({}, [
//combine two fields into one
//the first field does not have obj.
//any additional fields that are combined use a preceding obj.
//sorting will be by the first field specified (first_name in this example)
{name: 'full_name', type: 'string', mapping: 'first_name + " " + obj.last_name'},
{name: 'age'}
]);
var grid = new Ext.grid.GridPanel({
store: new Ext.data.Store({
reader: reader,
data: Ext.grid.dummyData
}),
columns: [
{header: 'Full Name', dataIndex: 'full_name'},
{header: 'Age', dataIndex:'age'}
]
});
7. How to modify appearance, behavior of specific rows or columns?
.x-grid3-td-company {
cursor: text;
}
gridView = new Ext.grid.GridView({
//forceFit: true,
getRowClass : function (row, index) {
var cls = '';
var data = row.data;
switch (data.SEVERITY) {
case 'C' :
cls = 'alarmGridCritical'
break;
case 'M' :
cls = 'alarmGridMinor'
break;
}
return cls;
}
});
8. How to add click handlers to specific Grid cells?
function(grid, rowIndex, columnIndex, e) {
var record = grid.getStore().getAt(rowIndex); // Get the Record for the row
// Get field name for the column
var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
var data = record.get(fieldName);
}
9. Store is empty even after calling load() on my Store
myStore.load();
alert(myStore.getCount());// no way! won't work. the store was just requested, it's not 'back' from the server yet.
//add listener to store's load event:
myStore.on({
'load':{
fn: function(store, records, options){
//store is loaded, now you can work with it's records, etc.
console.log('Data Store listener fired (load), arguments:',arguments);
console.log('Store count = ',store.getCount());
}
,scope:this
}
10. Make grid resize with the window
12. How to reload a Grid from a different URL?
Usually, this question means that different '''parameters''' need to be passed to the same server script. The answer is "Do not embed parameters in the DataProxy's URL"
To add parameters to a Grid's server requests add a listener for its Proxy's beforeload event:
var proxy = new Ext.data.HttpProxy({
url: '/DoSearch.php'
});
// Add the HTTP parameter searchTerm to the request
proxy.on('beforeload', function(p, params) {
params.searchTerm = searchValue;
});
13. XML Issues
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
14. Grid still shows records even when it should be empty
15. How to debug the response going into JsonReader
16. How to drag/drop/reorder rows?
17. Horizontal scrolling issues
grid.getStore().on({
beforeload: function() {
this.prevScrollState = this.getScrollState();
this.prevScrollState.top = 0;
},
load: function() {
this.restoreScroll(this.prevScrollState);
remove this.prevScrollState;
},
scope: grid.getView()
});
18. Mixing fixed width and variable width columns
Imagine a scenario where there are columns 'Salutation' and 'Name' which needs to be at 50px width each, and a column 'notes' which should be sized to the grid's size.
19. How to hide a column
20. How to wrap contents within a cell of a fixed width grid column?
The goal is to have the contents of a cell automatically wrap into a fixed defined width according to the column definition instead of having to manually drag the column width to expand the column.
td.x-grid3-td-<your id> {
overflow: hidden;
}
td.x-grid3-td-<your id> div.x-grid3-cell-inner {
white-space: normal;
}
If you want to apply this to the entire grid apply it to the basic td class of the grid.
21. How to add a column with tools for each record?
{header: "Controls",
width: 60,
sortable: false,
renderer: function() {
return '<div class="controlBtn"><img src="../shared/icons/fam/cog_edit.png" width="16" height="16" class="control_edit"><img src="../shared/icons/fam/folder_go.png" width="16" height="16" class="control_go"></div>';
},
dataIndex: 'company'}
grid.on('click', function(e) {
var btn = e.getTarget('.controlBtn');
if (btn) {
var t = e.getTarget();
var v = this.view;
var rowIdx = v.findRowIndex(t);
var record = this.getStore().getAt(rowIdx);
var control = t.className.split('_')[1];
switch (control) {
case 'edit':
console.log('edit this record - ' + record.id);
break;
case 'go':
console.log('go to this record - ' + record.id);
break;
}
}
}, grid);
Add the following CSS rule in array-grid.html to give some padding and change the cursor.
<style>
.controlBtn img {
padding-left: 4px;
cursor: pointer;
}
</style>
// vim: ts=4:sw=4:nu:fdc=2:nospell
/**
* RowAction plugin for Ext grid
*
* Contains renderer for an icon and fires events when icon is clicked
*
* @author Ing. Jozef Sakalos <jsakalos at aariadne dot com>
* @date December 29, 2007
* @version $Id: Ext.ux.grid.RowAction.js 126 2008-01-31 03:33:50Z jozo $
*
* @license Ext.ux.grid.RowAction is licensed under the terms of
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
* that the code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* License details: http://www.gnu.org/licenses/lgpl.html
*/ Ext.ns('Ext.ux.grid');
/**
* @class Ext.ux.grid.RowAction
* @extends Ext.util.Observable
*
* Creates new RowAction plugin
* @constructor
* @param {Object} config The config object
*
* @cfg {String} iconCls css class that defines background image
*/
Ext.ux.grid.RowAction = function(config) {
Ext.apply(this, config);
this.addEvents({
/**
* @event beforeaction
* Fires before action event. Return false to cancel the subsequent action event.
* @param {Ext.grid.GridPanel} grid
* @param {Ext.data.Record} record Record corresponding to row clicked
* @param {Integer} rowIndex
*/
beforeaction:true
/**
* @event action
* Fires when icon is clicked
* @param {Ext.grid.GridPanel} grid
* @param {Ext.data.Record} record Record corresponding to row clicked
* @param {Integer} rowIndex
*/
,action:true
});
Ext.ux.grid.RowAction.superclass.constructor.call(this);
};
Ext.extend(Ext.ux.grid.RowAction, Ext.util.Observable, {
header:''
,sortable:false
,dataIndex:''
,width:20
,fixed:true
,lazyRender:true
,iconCls:''
// private - plugin initialization
,init:function(grid) {
this.grid = grid;
var view = grid.getView();
grid.on({
render:{scope:this, fn:function() {
view.mainBody.on({
click:{scope:this, fn:this.onClick}
});
}}
});
if(!this.renderer) {
this.renderer = function(value, cell, record, row, col, store) {
cell.css += (cell.css ? ' ' : '') + 'ux-grid3-row-action-cell';
var retval = '<div class="' + this.getIconCls(record, row, col) + '"';
retval += this.style ? ' style="' + this.style + '"' : '';
retval += this.qtip ? ' ext:qtip="' + this.qtip +'"' : '';
retval += '> </div>';
return retval;
}.createDelegate(this);
}
} // eo function init
// override for custom processing
,getIconCls:function(record, row, col) {
return this.boundIndex ? record.get(this.boundIndex) : this.iconCls;
} // eo function getIconCls
// private - icon click handler
,onClick:function(e, target) {
var record, iconCls;
var row = e.getTarget('.x-grid3-row');
var col = this.grid.getView().getCellIndex(e.getTarget('.ux-grid3-row-action-cell'));
if(false !== row && false !== col) {
record = this.grid.store.getAt(row.rowIndex);
iconCls = this.getIconCls(record, row.rowIndex, col);
if(Ext.fly(target).hasClass(iconCls)) {
if(false !== this.fireEvent('beforeaction', this.grid, record, row.rowIndex)) {
this.fireEvent('action', this.grid, record, row.rowIndex, e);
}
}
}
} // eo function onClick
});
// eof
22. How to center elements in a toolbar?
myToolbar.getEl().child("table").wrap({tag:'center'})
var t = myGridPanel.getBottomToolbar().el;
var c = t.createChild("<center></center>");
c.appendChild(t.child("table"));
23. How to delete all selected rows?
Ext.each(contactgrid.getSelectionModel().getSelections(), contactgrid.getStore().remove, contactgrid.getStore());
tbar: [
{
text: 'Delete Contacts',
iconCls:'remove',
handler : function(t){
console.log(' inside "Delete Contacts" with arguments = ',arguments); grid = contactgrid;
//get the store associated with the grid:
store = grid.getStore();
//returns array of record objects for selected rows (all info for row)
var selections = grid.selModel.getSelections();
console.log(' grid = ',grid);
console.log(' selections = ',selections);
var n = selections.length;
for(var i = 0; i < n; i++){
console.log(' Number Selected =',n);
console.log(' selections =',selections);
console.log(' store before remove attempt #',i,': ',store,' store has ',store.getCount(),' records');
store.remove(selections[i]);
console.log(' store after remove attempt #',i,': ',store,' store has ',store.getCount(),' records');
}//end for
}//end handler
}//end Delete Contacts
24. Issues with paging or total record count
bbar: new Ext.PagingToolbar({
pageSize: 25, //when you go to next page I believe it uses this number
...
})
store.load({params:{start: 0, limit: 25}});//pass params for first page load
//or if you want to use autoLoad in the store's configuration:
autoLoad: {params:{start: 0, limit: 25}}
/* By specifying the start/limit params in ds.load
* the values are passed here
* if using ScriptTagProxy the values will be in $_GET
* if using HttpProxy the values will be in $_POST (or $_REQUEST)
* the following two lines check either location, but might be more
* secure to use the appropriate one according to the Proxy being used
*/
$start = (integer) (isset($_POST['start']) ? $_POST['start'] : $_GET['start']);
$end = (integer) (isset($_POST['limit']) ? $_POST['limit'] : $_GET['limit']); //check for the 'sort' and 'dir' in the POST array.
$sortDir = isset($_POST['dir']) ? $_POST['dir'] : 'ASC';//default to ASC if not set
$sortBy = isset($_POST['sort']) ? $_POST['sort] : 'company';//default to company name if not set
$sql_count = 'SELECT * FROM ' . $table;
$sql = $sql_count . ' ORDER BY ' . $sortBy. ' ' . $sortDir . ' LIMIT ' . $start . ', '. $end;
$result_count = mysql_query($sql_count);
$rows = mysql_num_rows($result_count);
25. Get a record from the grid by row index
var record = grid.getStore().getAt(rowIndex);
26. Load data to a grid from two diferent server calls/stores
var store2 = new Ext.data.Store({
...
});
var store1 = new Ext.data.Store({
...
listeners: {
load: function(store) {
store2.addRecords({records: store.getRange()},{add: true});
}
}
});
var store1 = new Ext.data.Store({
...,
fields: ['field1', 'field2']
}); var store2 = new Ext.data.Store({
...
id: 'field2',
fields: ['field2', 'fieldA', 'fieldB']
});
var renderA = function(value) {
var rec = store2.getById(value);
return rec ? rec.get('fieldA') : '';
}
var renderB = function(value) {
var rec = store2.getById(value);
return rec ? rec.get('fieldB') : '';
}
var columns = [
{header: 'Field 1', dataIndex: 'field1'},
{header: 'Field A', dataIndex: 'field2', renderer: renderA},
{header: 'Field B', dataIndex: 'field2', renderer: renderB}
];
27. "Auto size" columns to the largest element in them
28. Disable editing of particular rows
var grid = new Ext.grid.EditorGridPanel({
...
isCellEditable: function(colIndex, rowIndex) {
var field = this.getColumnModel().getDataIndex(colIndex);
if (field == 'value') {
var record = this.getStore().getAt(rowIndex);
if (!record.get('enable_edit').getValue()) { //enable_edit is field in record
return false;//return false to deny editing
}
}
return Ext.grid.EditorGridPanel.prototype.isCellEditable.call(this, colIndex, rowIndex);
}
});
myColumnModel.isCellEditable = function(colIndex, rowIndex){ return !someBooleanStoredSomewhere; };
this.on('beforeedit', Comment.Methods.commentUpdateCheckPermission);
commentUpdateCheckPermission : function (commentData) {
if (cds.data.items[commentData.row].data.user_ID != Ext.util.Format.uppercase(VMOC.myUUID)) {
Ext.MessageBox.alert('Permission denied', 'You do not have permission to edit this comment.');
cds.rejectChanges();
commentData.cancel = true;
}
}
29. What is difference between contentEl, applyTo and renderTo?
For most use cases you should be able to use the contentEl config option with a div in your markup with a css class of x-hidden.
30. Dirty Record / Red Flag (modifying, etc.)
record.modified[this.dataIndex] = undefined; // will prevent a "dirty" flag to be displayed on the check box
grid.on('validateedit', function(e) {
var myTargetRow = 6;
if (e.row == myTargetRow) {
e.cancel = true;
e.record.data[e.field] = e.value;
}
})
grid.on('afteredit', afterEdit, this );
function afterEdit(val) {
val.record.commit();
};
.x-grid-dirty-cell {
background-image:none;
}
Or:
PHP Code:
<style type="text/css">
.x-grid3-td-[id-of-column] {background-image:none!important;}
</style>