PDA

View Full Version : how to place button in grid cell?



bcamp1973
14 Nov 2007, 8:48 AM
I'm *very* new to ExtJS so i'm just learning the ropes. My Javascript (and programming skills in general) are fairly basic. I'm attempting to build a grid where the last column contains one or more buttons. The data for the grid is being pulled from an xml file. I'm guessing the buttons would be a plugin? How would i accomplish that?

Here's my xml...


<catalog>
<attribute>
<name>First Name</name>
<type>Text</type>
<min></min>
<max>30</max>
<defaultVal></defaultVal>
<required>true</required>
<action></action>
</attribute>
<attribute>
...
</attribute>
</catalog>

and my javascript...


Ext.onReady(function(){
Ext.QuickTips.init();

// shorthand alias
var fm=Ext.form;

// custom column plugin example
var checkColumn=new Ext.grid.CheckColumn({
header:"Required?",
dataIndex:'required',
width:75
});

// 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([{
id:'name',
header:"Name",
dataIndex:'name',
width:220,
editor:new fm.TextField({
allowBlank:false
})
},{
header:"Type",
dataIndex:'type',
width:130,
editor:new Ext.form.ComboBox({
typeAhead:true,
triggerAction:'all',
transform:'type',
lazyRender:true,
listClass:'x-combo-list-small'
})
},{
header:"Min",
dataIndex:'min',
width:50,
align:'center',
editor:new fm.TextField({
allowBlank:true
})
},{
header:"Max",
dataIndex:'max',
width:50,
align:'center',
editor:new fm.TextField({
allowBlank:true
})
},{
header:"Default",
dataIndex:'defaultVal',
width:80,
align:'left',
editor:new fm.TextField({
allowBlank:true
})
},
checkColumn,
{
header:"Action",
dataIndex:'action',
width:80,
align:'left'
}
]);

// by default columns are sortable
cm.defaultSortable=true;

// this could be inline, but we want to define the Plant record
// type so we can add records dynamically
var Attribute=Ext.data.Record.create([
// the "name" below matches the tag name to read, except "availDate"
// which is mapped to the tag "availability"
{name:'name', type:'string'},
{name:'botanical', type:'string'},
{name:'type'},
{name:'min'},
{name:'max'},
{name:'defaultVal'},
{name:'required', type:'bool'},
{name:'action'}
]);

// create the Data Store
var store=new Ext.data.Store({
url:'assets/xml/attributes.xml',
reader:new Ext.data.XmlReader({record:'attribute'}, Attribute),
sortInfo:{field:'name', direction:'ASC'}
});

// create the editor grid
var grid=new Ext.grid.EditorGridPanel({
store:store,
cm:cm,
renderTo:'editor-grid',
autoWidth:true,
height:300,
autoExpandColumn:'name',
title:'Edit Attributes?',
frame:true,
plugins:checkColumn,
clicksToEdit:1,

tbar:[{
text:'Add Attribute',
handler:function(){
var p=new Attribute({
name:'New Attribute Name',
type:'Text',
min:0,
max:0,
defaultVal:'',
required:false,
action:'?'
});
grid.stopEditing();
store.insert(0, p);
grid.startEditing(0, 0);
}
}]
});

// trigger the data store load
store.load();
});

Ext.grid.CheckColumn=function(config){
Ext.apply(this, config);
if(!this.id){
this.id=Ext.id();
}
this.renderer=this.renderer.createDelegate(this);
};

Ext.grid.CheckColumn.prototype={
init:function(grid){
this.grid=grid;
this.grid.on('render', function(){
var view=this.grid.getView();
view.mainBody.on('mousedown', this.onMouseDown, this);
}, this);
},

onMouseDown:function(e, t){
if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
e.stopEvent();
var index=this.grid.getView().findRowIndex(t);
var record=this.grid.store.getAt(index);
record.set(this.dataIndex, !record.data[this.dataIndex]);
}
},

renderer:function(v, p, record){
p.css += ' x-grid3-check-col-td';
return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'">*</div>';
}
};

mints
27 Nov 2007, 7:46 AM
I have once puzzled with the problem also. And I found the solution on the forum. the solution is as follows:
1)Define the button column with renderer when new ColumnModel


{
header: "Button",
dataIndex: 'button',
width: 130,
renderer: renderBtn
}

2)Define the renderder function



function renderBtn(val, p, record) {
var contentId = Ext.id();
createGridButton.defer(1, this, [val, contentId, record]);
return('<div id="' + contentId + '"></div>');
}
function createGridButton(value, contentid, record) {
new Ext.Button({text: value, handler : function(btn, e) {
alert("record data="+record.data);
}}).render(document.body, contentid);
}

Wish the code sample will be helpful.:)

m0ntassar
27 Nov 2007, 9:36 AM
Just a suggestion : You may want to use icon images, buttons are too blky ;)

bhomass
23 Aug 2008, 9:54 PM
is there a sample code on how you then attach action to the button which takes into account the item Id of the grid row?

mjlecomte
23 Aug 2008, 11:18 PM
Look for the rowactions extension/plugin on www.extjs.eu

jasmina
22 Jun 2010, 10:45 AM
Just a suggestion : You may want to use icon images, buttons are too blky ;)
This is a wonderful work. can you tell me how do i delete a row in the grid. i mean now you have a button again each row. So without selecting an cell in the row i need to delete the row when clicked on the row corresponding to that row.

SebTardif
7 Aug 2011, 1:17 PM
If we create a component in a renderer are we not responsible to destroy them or that will create a memory leak?

kyrillos52
17 Oct 2011, 11:33 PM
Hello,

To avoid repeating the thread, i post here.
I'm trying to display buttons in specific cells into a grid thanks to an id.
I have a JSONArray, called "devices" here, with the id corresponding to the cells:

[{"nom":"test","id":"1"},{"nom":"test","id":"4"},{"nom":"test","id":"6"},{"nom":"test","id":"7"}

this is myGrid.ui.js:


myGridUi = Ext.extend(Ext.grid.GridPanel,
{
title: 'Network Mapping',
ref: 'mon_grid',
store: 'DataStore',
border: false,
height: 800,
autowidth: true,
initComponent: function()
{
this.columns =
[
{
xtype: 'gridcolumn',
header: '1',
renderer: renderIcon
},
{
xtype: 'gridcolumn',
header: '2',
renderer: renderIcon
},
{
xtype: 'gridcolumn',
header: '3',
renderer: renderIcon
}
];
myGridUi.superclass.initComponent.call(this);
}
});


1 actually have this code to read into the JSONArray,
This is a grid with 3 columns and 3 rows:


// Function spells in each cells of the grid
function renderIcon(val, p)
{
// Define the contentId in order to place buttons into the grid.
var contentId = Ext.id();

// I define this variable in anoter file to make it global, I can increment it now.
cellId++;

// Read into devices, the JSONArray:
Ext.each(devices, function(op)
{
if((cellId-1) == op.id)
{
createButton.defer(1, this, [val, contentId, op.nom" "+op.id]);
return('<div id="' + contentId + '"></div>');
}
}
);
}

// Function wich create the button
function createButton(val, contentid, text)
{
new Ext.Button({
text: text,
handler: function(btn, e)
{
// Action with the button
var window = new WindowItem
({
renderTo: Ext.getBody()
});
// Display the new window
window.show();
}
}).render(document.body, contentid);
}

My problem is when I use this code, it displays all buttons in one cell.
It creates graphic errors too.