PDA

View Full Version : Ext.form.combobox in gridpanel



blessan
27 Jun 2010, 8:03 PM
I wanted to ask, is it possible to add a Ext.form.combobox in grid panel. I was able to implement a select box in a column using the renderer method. But I wanted it o be a combobox so I could change the css styles.
I tried the editor panel. The combobox gets rendered. But by default only the value is displayed and the comboxbox only shows when I click on the cell.
Is there a way to show a combobox always on the grid column?

blessan
27 Jun 2010, 9:28 PM
Does anybody know how to get it done. I just need a combobox when the grid loads. I dont want to click on a cell to get the combobox as implemented in editor grid.

Condor
27 Jun 2010, 11:09 PM
Have a look at the EditableGrid user extension (http://www.sencha.com/forum/showthread.php?79232-EditableGrid-Shows-editors-for-all-cells).

blessan
28 Jun 2010, 12:48 AM
I checked ur link condor. And it s what I need. I copied the whole code. But when I try to run it, i get the following code in firebug.

p.init is not a function
if(this.applyTo){this.applyToMarkup(th....parentNode;this.allowDomMove=false;} I dont know what the problem is.

Heres the code in my files

test.html


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Editor Grid Example</title>
<link rel="stylesheet" type="text/css" href="../extjs2.3/resources/css/ext-all.css" />
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../extjs2.3/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../extjs2.3/ext-all.js"></script>
<script type="text/javascript" src="GroupingView.js"></script>
<script type="text/javascript" src="test.js"></script>
<link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
</body>
</html>


test.js


Ext.onReady(function(){
Ext.QuickTips.init();
new Ext.grid.GridPanel({
title: 'EditableGrid plugin test',
id:'test',
width: 250,
height: 150,
store: [[1, 'One'], [2, 'Two'], [3, 'Three'], [4, 'Four'], [5, 'Five']],
viewConfig: {
forceFit: true
},
columns: [{
header: 'Value',
dataIndex: 'field1',
editor: {
xtype: 'numberfield',
minValue: 0,
maxValue: 100
}
},{
header: 'Text',
dataIndex: 'field2',
editor: {
xtype: 'textfield',
allowBlank: false
}
}],
plugins: [{
ptype: 'editable-grid'
}],
renderTo: Ext.getBody()
});
console.info('sdfdsf');
});

Ext.ns('Ext.ux.grid');
Ext.ux.grid.EditableGrid = Ext.extend(Object, {
init : function(grid){
Ext.apply(grid.getView(), {
editors: [],
editorPadding: 2,
renderUI : function(){
this.constructor.prototype.renderUI.call(this);
this.el.addClass('x-grid-editing');
},
updateAllColumnWidths : function(){
this.constructor.prototype.updateAllColumnWidths.call(this);
var editors = this.editors,
rows = editors.length,
cols = this.cm.getColumnCount(),
col, row, ed, w = [];
for(col = 0; col < cols; col++){
w[col] = this.cm.getColumnWidth(col) - this.editorPadding;
}
for(row = 0; row < rows; row++){
for(col = 0; col < cols; col++){
ed = editors[row][col];
if(ed){
ed.setWidth(w[col]);
}
}
}
},
updateColumnWidth : function(col, width){
this.constructor.prototype.updateColumnWidth.call(this, col, width);
var editors = this.editors,
rows = editors.length,
row, ed,
w = this.cm.getColumnWidth(col) - this.editorPadding;
for(row = 0; row < rows; row++){
ed = editors[row][col];
if(ed){
ed.setWidth(w);
}
}
},
afterRender : function(){
this.constructor.prototype.afterRender.call(this);
this.destroyAllEditors();
this.renderEditors(0, this.ds.getCount() - 1);
},
insertRows : function(dm, firstRow, lastRow, isUpdate){
this.constructor.prototype.insertRows.call(this, dm, firstRow, lastRow, isUpdate);
var last = dm.getCount() - 1;
if(!isUpdate && firstRow === 0 && lastRow >= last){
return;
}
this.renderEditors(firstRow, lastRow);
},
deleteRows : function(dm, firstRow, lastRow){
if(dm.getRowCount() >= 1){
this.destroyEditors(firstRow, lastRow);
}
this.constructor.prototype.deleteRows.call(this, dm, firstRow, lastRow);
},
refreshRow : function(record){
var ds = this.ds, index;
if(typeof record == 'number'){
index = record;
record = ds.getAt(index);
if(!record){
return;
}
}else{
index = ds.indexOf(record);
if(index < 0){
return;
}
}
this.destroyEditors(index, index);
this.constructor.prototype.refreshRow.call(this, record);
this.renderEditors(index, index);
},
refresh : function(headersToo){
this.destroyAllEditors();
this.constructor.prototype.refresh.call(this, headersToo);
this.renderEditors(0, this.ds.getCount() - 1);
},
destroy : function(){
this.destroyAllEditors();
this.constructor.prototype.destroy.call(this);
},
focusCell : function(row, col, hscroll){
this.syncFocusEl(this.ensureVisible(row, col, hscroll));
var ed = this.editors[row][col], focusEl = ed ? ed : this.focusEl;
if(Ext.isGecko){
focusEl.focus();
}else{
focusEl.focus.defer(1, this.focusEl);
}
},
renderEditors: function(startRow, endRow){
var args = [startRow, 0],
cols = this.cm.getColumnCount(),
col, row, ed, w = [], rec, r, di, cell;
for(col = 0; col < cols; col++){
w[col] = this.cm.getColumnWidth(col) - this.editorPadding;
}
for(row = startRow; row <= endRow; row++){
r = [];
rec = this.ds.getAt(row);
for(col = 0; col < cols; col++){
ed = this.cm.isCellEditable(col, row) ? this.cm.getCellEditor(col, row) : null;
if(ed){
cell = this.getCell(row, col).firstChild;
cell.parentNode.removeAttribute('tabindex');
cell.innerHTML = '';
di = this.cm.getDataIndex(col);
ed = ed.field.cloneConfig({
value: rec.get(di),
width: w[col],
renderTo: cell,
ctCls: 'x-small-editor x-grid-editor ux-editable-grid'
});
ed.on('blur', this.onEditorBlur, {
store: this.ds,
row: row,
dataIndex: di
});
}
r.push(ed);
}
args.push(r);
}
this.editors.splice.apply(this.editors, args);
},
destroyEditors: function(startRow, endRow){
var removed = this.editors.splice(startRow, endRow - startRow + 1);
Ext.destroy(removed);
},
destroyAllEditors: function(){
Ext.destroy(this.editors);
this.editors = [];
},
onEditorBlur: function(field){
this.store.getAt(this.row).data[this.dataIndex] = field.getValue();
}
});
}
});
Ext.reg('editable-grid', Ext.ux.grid.EditableGrid);


test.css


.ux-editable-grid {
padding: 0;
}


When I first run the code I had another error

Ext.preg is not a function
Ext.preg('editable-grid', Ext.ux.grid.EditableGrid);

I got rid of the that by replacing preg with reg. Is there anythin else in this code to be rectified?

Condor
28 Jun 2010, 1:13 AM
Which Ext version are you using (IIRC preg() was added in Ext 3.0)?

blessan
28 Jun 2010, 1:26 AM
I am using 2.3.0. Wont this plugin work. My current project is in 2.3.0

Condor
28 Jun 2010, 1:43 AM
It could work in Ext 2.3.0, but it probably needs some changes, one of which being:

plugins: [new Ext.ux.grid.EditableGrid()]

blessan
28 Jun 2010, 1:49 AM
Could u please help me out as Im not really familiar wit the internals of Extjs. I entered what u said and this is the next error i get

ds.on is not a function
if(ds){ds.on("load",this.onLoad,this);...s);ds.on("clear",this.onClear,this);}

Condor
28 Jun 2010, 1:51 AM
Specifying a store as an array is also not supported in Ext 2. You will need to use:

store: new Ext.data.SimpleStore({
fields: ['field1', 'field2'],
data: [[1, 'One'], [2, 'Two'], [3, 'Three'], [4, 'Four'], [5, 'Five']]
})

blessan
28 Jun 2010, 3:04 AM
Thanks for the help. Now the grid is getting rendered but the edit text boxes are not displayed. This is the next error

ed.field is undefined
ed = ed.field.cloneConfig({

I guess clone config is not in 2.3.0

blessan
28 Jun 2010, 3:27 AM
I found that 'ed' only has 3 values in it. When I tested the code in 3.2.1 there were lots of values in 'ed'. I kinda tried to fix it. But dont really know where the mistake is.

Condor
28 Jun 2010, 5:21 AM
In Ext 2 it should probably be:

ed = Ext.ComponentMgr.create(Ext.applyIf({
value: rec.get(di),
width: w[col],
renderTo: cell,
ctCls: 'x-small-editor x-grid-editor ux-editable-grid'
}, ed), 'textfield');

blessan
28 Jun 2010, 8:08 PM
Thanks condor. I replaced the clone config code with the code u gave above. I have one more problem. It happens when I try to use a combo box. My code after I added the combo box is below,



Ext.onReady(function(){
Ext.QuickTips.init();
new Ext.grid.GridPanel({
title: 'EditableGrid plugin test',
id:'test',
width: 250,
height: 150,
store: new Ext.data.SimpleStore({
fields: ['field1', 'field2'],
data: [[1, 'One'], [2, 'Two'], [3, 'Three'], [4, 'Four'], [5, 'Five']]
}),
viewConfig: {
forceFit: true
},
columns: [{
header: 'Value',
dataIndex: 'field1',
editor: {
xtype: 'numberfield',
minValue: 0,
maxValue: 100
}
},{
header: 'Text',
dataIndex: 'field2',
editor: {
xtype: 'textfield',
allowBlank: false
}
},
new Ext.form.ComboBox({
fieldLabel: '',
hiddenName: 'number',
store: new Ext.data.SimpleStore({
fields: ['number'],
data : [['one'],['two'],['three'],['four'],['five']]
}),
displayField: 'number',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Choose number...',
selectOnFocus:true
})
],
plugins: [new Ext.ux.grid.EditableGrid()],
renderTo: Ext.getBody()
});
console.info('sdfdsf');
});

Ext.ns('Ext.ux.grid');
Ext.ux.grid.EditableGrid = Ext.extend(Object, {
init : function(grid){
Ext.apply(grid.getView(), {
editors: [],
editorPadding: 2,
renderUI : function(){
this.constructor.prototype.renderUI.call(this);
this.el.addClass('x-grid-editing');
},
updateAllColumnWidths : function(){
this.constructor.prototype.updateAllColumnWidths.call(this);
var editors = this.editors,
rows = editors.length,
cols = this.cm.getColumnCount(),
col, row, ed, w = [];
for(col = 0; col < cols; col++){
w[col] = this.cm.getColumnWidth(col) - this.editorPadding;
}
for(row = 0; row < rows; row++){
for(col = 0; col < cols; col++){
ed = editors[row][col];
if(ed){
ed.setWidth(w[col]);
}
}
}
},
updateColumnWidth : function(col, width){
this.constructor.prototype.updateColumnWidth.call(this, col, width);
var editors = this.editors,
rows = editors.length,
row, ed,
w = this.cm.getColumnWidth(col) - this.editorPadding;
for(row = 0; row < rows; row++){
ed = editors[row][col];
if(ed){
ed.setWidth(w);
}
}
},
afterRender : function(){
this.constructor.prototype.afterRender.call(this);
this.destroyAllEditors();
this.renderEditors(0, this.ds.getCount() - 1);
},
insertRows : function(dm, firstRow, lastRow, isUpdate){
this.constructor.prototype.insertRows.call(this, dm, firstRow, lastRow, isUpdate);
var last = dm.getCount() - 1;
if(!isUpdate && firstRow === 0 && lastRow >= last){
return;
}
this.renderEditors(firstRow, lastRow);
},
deleteRows : function(dm, firstRow, lastRow){
if(dm.getRowCount() >= 1){
this.destroyEditors(firstRow, lastRow);
}
this.constructor.prototype.deleteRows.call(this, dm, firstRow, lastRow);
},
refreshRow : function(record){
var ds = this.ds, index;
if(typeof record == 'number'){
index = record;
record = ds.getAt(index);
if(!record){
return;
}
}else{
index = ds.indexOf(record);
if(index < 0){
return;
}
}
this.destroyEditors(index, index);
this.constructor.prototype.refreshRow.call(this, record);
this.renderEditors(index, index);
},
refresh : function(headersToo){
this.destroyAllEditors();
this.constructor.prototype.refresh.call(this, headersToo);
this.renderEditors(0, this.ds.getCount() - 1);
},
destroy : function(){
this.destroyAllEditors();
this.constructor.prototype.destroy.call(this);
},
focusCell : function(row, col, hscroll){
this.syncFocusEl(this.ensureVisible(row, col, hscroll));
var ed = this.editors[row][col], focusEl = ed ? ed : this.focusEl;
if(Ext.isGecko){
focusEl.focus();
}else{
focusEl.focus.defer(1, this.focusEl);
}
},
renderEditors: function(startRow, endRow){
var args = [startRow, 0],
cols = this.cm.getColumnCount(),
col, row, ed, w = [], rec, r, di, cell;
for(col = 0; col < cols; col++){
w[col] = this.cm.getColumnWidth(col) - this.editorPadding;
}
for(row = startRow; row <= endRow; row++){
r = [];
rec = this.ds.getAt(row);
for(col = 0; col < cols; col++){
ed = this.cm.isCellEditable(col, row) ? this.cm.getCellEditor(col, row) : null;

console.info(ed);
if(ed){
cell = this.getCell(row, col).firstChild;
cell.parentNode.removeAttribute('tabindex');
cell.innerHTML = '';
di = this.cm.getDataIndex(col);
/*ed = ed.field.cloneConfig({
value: rec.get(di),
width: w[col],
renderTo: cell,
ctCls: 'x-small-editor x-grid-editor ux-editable-grid'
});
*/
ed = Ext.ComponentMgr.create(Ext.applyIf({
value: rec.get(di),
width: w[col],
renderTo: cell,
ctCls: 'x-small-editor x-grid-editor ux-editable-grid'
}, ed), 'textfield');
ed.on('blur', this.onEditorBlur, {
store: this.ds,
row: row,
dataIndex: di
});
}
r.push(ed);
}
args.push(r);
}
this.editors.splice.apply(this.editors, args);
},
destroyEditors: function(startRow, endRow){
var removed = this.editors.splice(startRow, endRow - startRow + 1);
Ext.destroy(removed);
},
destroyAllEditors: function(){
Ext.destroy(this.editors);
this.editors = [];
},
onEditorBlur: function(field){
this.store.getAt(this.row).data[this.dataIndex] = field.getValue();
}
});
}
});
Ext.reg('editable-grid', Ext.ux.grid.EditableGrid);


But I get the following error in firebug
this.ds.fields.get(i) is undefined
chrome://firebug/content/blank.gifreturn true;},autoExpand:function(prev...Id(i),style:this.getColumnStyle(i)};}
Is there a way to fix this?

blessan
28 Jun 2010, 8:30 PM
Ok I know a bit of my code above is just wrong. So I made changes. I changed the combobox code to



{
header: 'Combo',
dataIndex: 'field3',
editor:
new Ext.form.ComboBox({
fieldLabel: '',
hiddenName: 'number',
store: new Ext.data.SimpleStore({
fields: ['number'],
data : [['one'],['two'],['three'],['four'],['five']]
}),
displayField: 'number',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Choose number...',
selectOnFocus:true
})
}


I changed the grid store to


store: new Ext.data.SimpleStore({
fields: ['field1', 'field2', 'field3'],
data: [[1, 'One'], [2, 'Two'], [3, 'Three'], [4, 'Four'], [5, 'Five']]
})


Now i get no errors. And my grid gets renders in the earlier editors with number field and textfield are shown. But my 3rd column is empty. I was trying to display the combobox. Im kinda stuck here. please help.

blessan
28 Jun 2010, 9:38 PM
21162
This is how my grid now renders

blessan
28 Jun 2010, 10:13 PM
I got it working i just made a small modification to combobox declaration



{
header: 'Combo',
dataIndex: 'field3',
editor: {
xtype:'combo'
fieldLabel: '',
hiddenName: 'number',
store: new Ext.data.SimpleStore({
fields: ['number'],
data : [['one'],['two'],['three'],['four'],['five']]
}),
displayField: 'number',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Choose number...',
selectOnFocus:true
}




21165

blessan
29 Jun 2010, 1:18 AM
Hey i need some help condor. Wont renderer work along with ur extension?
I tried to put the following code in my project



{
header:'term',
dataIndex: 'term',
renderer: function(val) {
if(val === '') {console.info('test');
return "<div style='color:red;text-decoration:underline;' onclick='new createSummaryNote({domainname:Ext.getCmp(&apos;domainsNamesGridId&apos;).getSelectionModel().getSelected().data.domain_name});'> View WHOIS</div>";
} else {
return true;
}
},
editor: {
xtype:'combo',
name: 'periodCbo',
hideLabel: true,
editable: true,
boxMaxWidth:40,
selectOnFocus: true,
mode: 'local',
autoShow: true,
maskRe: /\d{[0-9]}/,
triggerAction: 'all',
displayField: 'title',
valueField: 'title',
lazyInit: false,
lazyRender: true,
store: this.periodStore
},
width: 80,
hidden: false
}


The combobox renders properly. Sometimes there is a null for this column from my store. And when that happen, I need to display a div with some text. Isnt this possible while i use your extension?

Condor
29 Jun 2010, 1:25 AM
No, the extension ALWAYS displays the editor and never the rendered cell value, so you can only change the combobox to display a different displayField.

blessan
29 Jun 2010, 1:59 AM
Oh ok. Well thanks for all the help.