Looping Json array in Rowexpander plugin - extjs

I have a grid which I would like to show extra information with RowExpander plugin. When user click the cross, the json array should available in extended row. I tried everything but didn't successed to show the expanded content.
When I click the cross, I can see json array in console which is working well. But, the array content does not available in template.
Could you please help me, what I am doing wrong?
JSON ARRAY ( normal grid data )
[{"FORM_ID":"1","SUPPLIER_NO":"678456","SUPPLIER_NAME":"PINAR UNLU MAMÜLLER","RECORD_DATE":"12.06.2012","DELIVERY_NO":"215554","GRAND_TOTAL":"573","DRIVER_NAME":"Oğuz Çelikdemir","LICENSE_PLATE":"34 OGZ 6520"},{"FORM_ID":"2","SUPPLIER_NO":"75655463","SUPPLIER_NAME":"PINAR ET VE ET ÜRÜNLERİ","RECORD_DATE":"15.06.2012","DELIVERY_NO":"215556","GRAND_TOTAL":"619","DRIVER_NAME":"Murat Kayın","LICENSE_PLATE":"34 NES 7896"},{"FORM_ID":"3","SUPPLIER_NO":"32645668","SUPPLIER_NAME":"ÜLKER BİSKÜVİ","RECORD_DATE":"19.06.2012","DELIVERY_NO":"4563657","GRAND_TOTAL":"657","DRIVER_NAME":"Metin Yılmaz","LICENSE_PLATE":"06 ANK 6500"}]
JSON ARRAY ( expanded content )
[{"PRODUCT_NAME":"İÇECEK","QUANTITY":"2.00","SAS":"100","UNIT_ID":"1","UNIT_PRICE":"34.92","TOTAL":"70"},{"PRODUCT_NAME":"ŞARKÜTERİ","QUANTITY":"4.00","SAS":"100","UNIT_ID":"1","UNIT_PRICE":"34.92","TOTAL":"140"},{"PRODUCT_NAME":"KURU GIDA","QUANTITY":"1.00","SAS":"250","UNIT_ID":"1","UNIT_PRICE":"34.92","TOTAL":"35"},{"PRODUCT_NAME":"DETERJAN","QUANTITY":"5.00","SAS":"100","UNIT_ID":"1","UNIT_PRICE":"34.92","TOTAL":"175"},{"PRODUCT_NAME":"MEYVE SEBZE ve ET","QUANTITY":"3.00","SAS":"250","UNIT_ID":"1","UNIT_PRICE":"34.92","TOTAL":"105"}]
EXTJS
var formStore = new Ext.data.JsonStore({
url: 'form-data.php',
root: 'fdata',
idProperty: 'FORM_ID',
remoteSort: true,
fields: ['FORM_ID', 'SUPPLIER_NO', 'SUPPLIER_NAME', 'RECORD_DATE', 'DELIVERY_NO', 'DRIVER_NAME', 'LICENSE_PLATE',
{ name: 'GRAND_TOTAL', type: 'float'}]
});
formStore.setDefaultSort('RECORD_DATE', 'asc');
var checkboxSel = new Ext.grid.CheckboxSelectionModel();
var rowExpander = new Ext.grid.RowExpander({});
rowExpander.on('beforeexpand', function(rowexpander, record, body, rowindex) {
Ext.Ajax.request({
url: 'form-details.php' + '?fid=' + record.get('FORM_ID'),
method: 'GET',
success: function ( result, request ) {
var jsonData = Ext.util.JSON.decode(result.responseText);
tpl.overwrite(body, jsonData);
},
failure: function ( result, request ) {
Ext.MessageBox.alert('Failed', result.responseText);
return false;
}
});
return true;
});
var tpl = new Ext.Template(
'<p>URUN ADI : {PRODUCT_NAME}</p><br/>',
'<p>TOPLAM : {QUANTITY}</p>'
);
Ext.onReady(function() {
var grid = new Ext.grid.GridPanel({
title: 'ME.117.10 - Hammaliye Formu',
store: formStore,
sm: checkboxSel,
columns: [
checkboxSel, rowExpander,
{ header: "ID",
width: 40,
dataIndex: 'FORM_ID',
sortable: false
},
{ header: "Satıcı No",
id: 'form-id',
dataIndex: 'SUPPLIER_NO',
width: 40,
sortable: false
},
{ header: "Satıcı Firma",
dataIndex: 'SUPPLIER_NAME',
width: 290,
sortable: true
},
{ header: "Kayıt Tarihi",
width: 80,
dataIndex: 'RECORD_DATE',
sortable: true
},
{ header: "İrsaliye No",
width: 80,
dataIndex: 'DELIVERY_NO',
sortable: false
},
{ header: "Tutar",
width: 80,
dataIndex: 'GRAND_TOTAL',
sortable: false
}
],
autoExpandColumn: 'form-id',
renderTo: document.getElementById('form-results'),
width: 750,
height: 500,
loadMask: true,
columnLines: true,
plugins: rowExpander
});
formStore.load();
});

I assume you're using ExtJS 3.x as that's what your coding reflects. If you need help doing it in ExtJS 3.x I cannot help you much, I'm more used to the ExtJS 4.x way of coding, so that's what I'll use to try to explain this.
I am working to implement a nested grid just like this and have just been through this procedure:
Basically you need to config your main grid with a rowexpander plugin, which you have already done (below is the way I did it):
plugins: [{
ptype: "rowexpander",
rowBodyTpl: ['<div id="SessionInstructionGridRow-{ClientSessionId}" ></div>']
}],
Then in your controller you will just have to set up an event to happen on expandbody which is a rowexpander event:
this.control({
'gridview' : {
expandbody : this.onGridExpandBody
}
});
And then finally you write your script to the <div> tag you created in rowexpander plugin template:
onGridExpandBody : function(rowNode, record, expandbody) {
var targetId = 'SessionInstructionGridRow-' + record.get('ClientSessionId');
if (Ext.getCmp(targetId + "_grid") == null) {
var sessionInstructionGrid = Ext.create('TS.view.client.SessionInstruction', {
renderTo: targetId,
id: targetId + "_grid"
});
rowNode.grid = sessionInstructionGrid;
sessionInstructionGrid.getEl().swallowEvent(['mouseover', 'mousedown', 'click', 'dblclick', 'onRowFocus']);
sessionInstructionGrid.fireEvent("bind", sessionInstructionGrid, { ClientSessionId: record.get('ClientSessionId') });
}
}
Read: Nested grid with extjs 4 for more info.

Related

Adding link against each row in grid

I need to display a 'Delete' link against each row in a editorgridpanel.
How do I create this link;as it is not mapped to any particular column in the store?
I tried the following but it does not display the link against the added records:
var sampleRecord = new Ext.data.Record.create([
{mapping: 'organizationId',name:'organizationId', type:'int'},
{mapping: 'name',name:'name', type:'string'},
{mapping: 'address',name:'address' , type:'int'}
]);
var s_grid= new Ext.grid.EditorGridPanel ({
.........
columns: [
{header: 'id', width: 120, sortable: false, dataIndex: 'organizationId'},
{header: 'name',width: 120, sortable: false, dataIndex: 'name'},
{header: 'address', sortable: false,width: 45, dataIndex: 'address'},
{header: '',width: 50, sortable: false, renderer:this.delRenderer }
],
.....
,
delRenderer:function (val, meta, rec, rowIdx) {
var tempStr="<div onclick=\"javascript:Ext.getCmp('" +"s_grid" + "').deAllocate(" + rowIdx + ");\" class='pointer'><span style='color:#0000FF'><u>Delete</u></span></div>";
return tempStr ;
},
deAllocate:function (rowIdx ) {
Ext.getCmp('s_grid').getStore().removeAt(rowIdx);
Ext.getCmp('s_grid').getView().refresh();
}
});
Help is appreciated.
You'd be better off using an ActionColumn. Anyway, you can also wrap a solution around custom element (link...) with the cellclick event. Here's an example showing both methods:
var grid = new Ext.grid.GridPanel({
renderTo: Ext.getBody()
,height: 300
,store: new Ext.data.JsonStore({
fields: ['id', 'name']
,data: [
{id: 1, name: 'Foo'}
,{id: 2, name: 'Bar'}
,{id: 3, name: 'Baz'}
]
})
,columns: [
{dataIndex: 'name'}
,{
xtype: 'actioncolumn'
,icon: 'http://images.agoramedia.com/everydayhealth/gcms/icon_delete_16px.gif'
,handler: function(grid, row) {
grid.store.removeAt(row);
}
}
,{
renderer: function(value, md, record, row, col, store) {
return '<a class="delete-link" href="#delete-record-' + record.id + '">Delete</a>';
}
}
]
,listeners: {
cellclick: function(grid, row, col, e) {
var el = e.getTarget('a.delete-link');
if (el) {
e.preventDefault();
grid.store.removeAt(row);
}
}
}
});
var lastId = 3;
setInterval(function() {
var store = grid.store,
record = new store.recordType({id: ++lastId, name: 'New record #' + lastId}, lastId);
store.add(record);
}, 3000);
Update
And just because I may be completely off topic on your question, I think your code is not working because when you call this:
renderer: this.delRenderer
Your not in a scope where this points to your grid (since it has not even been created at this point...). What you want to do is rather something like this:
var s_grid = new Ext.grid.EditorGridPanel ({
...
columns: [..., {
...
renderer: delRenderer
}]
});
function delRenderer() {
// FYI, `this` will be the column here
...
}
Or put the function inline in the grid definition...
You can change model by adding delete field :
{
name: 'delete',
convert: function () {
return 'delete';
}
You can then add extra column in your grid and check for link click by 'cellclick' event of the grid with some modifications.Here is the working example :
Working Fiddle.
Have a nice day :-)
The dataIndex config is required on your column, so just provide any field there (e.g. the id) and in your renderer function just ignore the value argument (as you are already doing).

How do I disable a control in an ExtJS grid?

I am using ExtJs 3.4. I have a checkbox control in an ExtJs Grid. I want to disable the checkbox control based on when a value in the store is equal to zero.
I have tried this and it does not disable it:
var colModel = new Ext.grid.ColumnModel(
{
columns: [
{ id: 'AircraftOid', header: "AircraftOid", width: 100, sortable: true, locked: true, dataIndex: 'AircraftOid', hidden: true },
{ id: 'nNumber', header: "N-#", width: 100, sortable: true, locked: true, dataIndex: 'NNumber' },
{ header: "Make", width: 150, sortable: true, dataIndex: 'Make' },
{ header: "Model", width: 150, sortable: true, dataIndex: 'Model' },
{ header: "Register",
width: 55,
sortable: true,
dataIndex: 'Register',
xtype: 'checkcolumn'
}
],
isCellEditable: function (col, row) {
return false;
}
});
var grid = new Ext.grid.GridPanel({
store: aircraftStore,
cm: colModel,
sm: new Ext.grid.RowSelectionModel({ singleSelect: true }),
viewConfig: {
forceFit: true
},
height: 100,
split: true,
region: 'north'
});
Thanks in advance.
Your thought was right. But...
First, you're overriding column model's isCellEditable method to prevent editing. But Grid doesn't calls that method. It only works on EditorGrid.
Second, Ext.ux.grid.CheckColumn doesn't handle any editable features, because it's not an editor, it's just a column.
So for my project i modified it to act as a editor and added the readOnly property to prevent editing on normal Grids. If you set readOnly to true, it'll not be clickable anymore.
Ext.ux.grid.CheckColumn = Ext.extend(Ext.grid.Column, {
processEvent : function(name, e, grid, rowIndex, colIndex) {
if ( !this.readOnly && name == 'mousedown' ) {
grid.stopEditing();
var record = grid.store.getAt(rowIndex);
var cm = grid.getColumnModel();
var edit_e = {
grid: grid,
record: record,
field: this.dataIndex,
value: record.data[this.dataIndex],
row: rowIndex,
column: colIndex,
cancel: false
};
if ( grid.fireEvent( 'beforeedit', edit_e ) !== false && !edit_e.cancel ) {
record.set( this.dataIndex, !record.data[this.dataIndex] );
edit_e.cancel = null;
grid.fireEvent( 'afteredit', edit_e );
}
return false;
} else {
return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
}
},
editable : false,
readOnly : false,
renderer : function(v, p, record){
p.css += ' x-grid3-check-col-td';
return String.format('<div class="x-grid3-check-col{0}"> </div>', v ? '-on' : '');
},
init: Ext.emptyFn
});
Ext.preg('checkcolumn', Ext.ux.grid.CheckColumn);
Ext.grid.CheckColumn = Ext.ux.grid.CheckColumn;
Ext.grid.Column.types.checkcolumn = Ext.ux.grid.CheckColumn;

ExtJS Filters Feature Error

I am a novice in ExtJS and I am trying to include filters in ExTJS grid but I am getting an error like failed loading file "feature.filters". Below is my function for creating Grid and I am invoking this function from another HTML page.
function ExtJSGrid(tableId,headerInfo,data){
Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', 'http://vmxplambardi:19086/teamworks/script/extjs/examples/ux');
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.ux.grid.FiltersFeature',
'Ext.toolbar.Paging'
]);
var tableId=tableId+"-div";
var fields=[],columns=[],dataIndex='cell';
var filters = {
ftype: 'filters',
local:true,
filters: [{
type: 'string',
dataIndex: 'cell1'
}, {
type: 'string',
dataIndex: 'cell2'
}, {
type: 'string',
dataIndex: 'cell3'
}]
};
document.getElementById(tableId).innerHTML='';
for(var i=1;i<=headerInfo.length;i++)
{
var cellObj={},columnObj={};
cellObj.name=dataIndex+i;
fields.push(cellObj);
columnObj.text=headerInfo[i-1];
columnObj.dataIndex=dataIndex+i;
columns.push(columnObj);
}
var store = Ext.create('Ext.data.ArrayStore', {
fields:fields,
data: data
});
var grid = Ext.create('Ext.grid.Panel', {
store: store,
columns:columns,
width:'100%',
forceFit:true,
features: [filters],
renderTo: tableId
});
}
Please let me know if I am missing anything?
Javascript has no block level scope, so variables defined in the for loop are actually defined at the top of the function (hoisted) and survive the loops. So you are always overwrite the vars.
I've got it working like this:
var filters = {
ftype: 'filters',
// encode and local configuration options defined previously for easier reuse
encode: false, // json encode the filter query
local: true, // defaults to false (remote filtering)
// Filters are most naturally placed in the column definition, but can also be
// added here.
filters: [
{
type: 'boolean',
dataIndex: 'visible' //Just an example
}
]
};
var myFilterGrid = new Ext.create('Ext.ux.LiveSearchGridPanel', {
title: 'someTitle',
selType: 'cellmodel',
store: myStore,
columns:[
{
header: "Column1",
width: 90,
sortable: true,
dataIndex: 'INDEX1',
filterable: true, //<---
filter:{ //<---
type:'string'
}
},
....
{
header: "Another Column",
width: 85,
sortable: true,
dataIndex: 'INDEX2'
}],
features: [filters] //<---
});
And be sure to include
'Ext.ux.grid.FiltersFeature'
Hope this helps!

how to bind json for extjs grid

I have a simple data in mysql and want to populate that data in a ExtJS grid
My code
Ext.onReady(function() {
var proxy = new Ext.data.HttpProxy({
url: 'connectextjs.php'
});
var reader = new Ext.data.JsonReader([{
name: 'Employee_ID',
mapping: 'Employee_ID'
}, {
name: 'Department_ID'
}, {
name: 'Name'
}, {
name: 'Email'
}])
var store = new Ext.data.Store({
proxy: proxy,
reader: reader
});
store.load();
// create the grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [{
header: "Employee_ID",
width: 90,
dataIndex: 'Employee_ID',
sortable: true
}, {
header: "Department_ID",
width: 90,
dataIndex: 'Department_ID',
sortable: true
}, {
header: "Name",
width: 90,
dataIndex: 'Name',
sortable: true
}, {
header: "Email",
width: 200,
dataIndex: 'Email',
sortable: true
}],
renderTo: 'example-grid',
width: 540,
height: 200
});
});
My problem is I can't load the data on the grid. Please help me I am new to ExtJS.
connectextjs.php should return the json formated data with Employee_ID,Deaprtment_ID ,Name and Email init. Namming Convention should be followed strictly.
You can set the data of the grid by using this method.
First, assign an id to your grid, like this:
itemId : 'myGrid';
Get the JSON loaded from your JSON call, like this:
Ext.Ajax.request({
url : 'connectextjs.php',
params : {
yourParam : 'yourParameters'
},
// --> success simply means your action has no errors
success : function (conn, response, options, eOpts){
var jsonResults = Ext.JSON.decode(conn.responseText);
// --> Now that you have your JsonResults Its time to set it to your grid
me.getView().down('#myGrid').setStore(jsonResults);
}
});

extjs grid: re-get data from server when click button

I am try to research Extjs- grid. I created a button to display grid when click it. My code like below:
function onDisplay() {
Ext.onReady(function () {
var proxy = new Ext.data.HttpProxy({
url: 'server.jsp'
});
var reader = new Ext.data.JsonReader({}, [{
name: 'bookId',
mapping: 'bookId'
}, {
name: 'bookName'
}])
var gridStore = new Ext.data.Store({
proxy: proxy,
reader: reader
});
gridStore.load();
cols = [{
header: "bookId",
width: 60,
dataIndex: 'bookId',
sortable: true
}, {
header: "bookName",
width: 60,
dataIndex: 'bookName',
sortable: true
}];
var firstGrid = new Ext.grid.GridPanel({
store: gridStore,
columns: cols,
renderTo: 'example-grid',
width: 540,
height: 200
});
});
}
But when i click button N times -> it is displayed N grids. I only want display one grid and after click button it will get data from server again.
Please help me.
Thank you
You might want to look at some of the ExtJS Grid examples. They have lots of information about rendering grids from a store, and creating toolbars (which may include refresh buttons, for example). After cleaning up your example code a bit, I've come up with this:
Ext.onReady(function(){
var proxy=new Ext.data.HttpProxy( {url:'server.jsp'});
var reader=new Ext.data.JsonReader({},[
{name: 'bookId', mapping: 'bookId'},
{name: 'bookName'}
])
var gridStore=new Ext.data.Store({
proxy:proxy,
reader:reader
autoLoad:true
});
cols= [
{header: "bookId", width: 60, dataIndex: 'bookId', sortable: true},
{header: "bookName", width: 60, dataIndex: 'bookName', sortable: true}
];
var firstGrid = new Ext.grid.GridPanel({
store : gridStore,
columns : cols,
renderTo :'example-grid',
width :540,
height :200
});
//this code should ensure that only the grid updates,
//rather than rendering a whole new grid each time
var button = Ext.Button({
renderTo: "ButtonContainerId",
listeners: {
'click': function() {
gridStore.load()
}
}
})
});

Resources