Nested Grid IN EXTJS - extjs

HI
How to design Nested grids in ExtJS
Please provide some samples(How to use RowExpander in ExtJS GridPanel)

Try something like this:
//Create the Row Expander.
var expander = new Ext.ux.grid.RowExpander({
tpl : new Ext.Template('<div id="myrow-{Id}" ></div>')
});
//Define the function to be called when the row is expanded.
function expandedRow(obj, record, body, rowIndex){
//absId parameter for the http request to get the absence details.
var absId = record.get('Id');
var dynamicStore = //the new store for the nested grid.
//Use Id to give each grid a unique identifier. The Id is used in the row expander tpl.
//and in the grid.render("ID") method.
var row = "myrow-" + record.get("Id");
var id2 = "mygrid-" + record.get("Id");
//Create the nested grid.
var gridX = new Ext.grid.GridPanel({
store: dynamicStore,
stripeRows: true,
columns: [
//columns
],
height: 120,
id: id2
});
//Render the grid to the row expander template(tpl).
gridX.render(row);
gridX.getEl().swallowEvent([ 'mouseover', 'mousedown', 'click', 'dblclick' ]);
}
//Add an expand listener to the Row Expander.
expander.on('expand', expandedRow);
You can find more information on this Here

How to use RowExpander in grid? Here's an example: http://dev.sencha.com/deploy/dev/examples/grid/grid-plugins.html
More examples can be found from http://dev.sencha.com/deploy/dev/examples/

It is possible to do it as the others have mentioned, however I recommend against it.
Reasons:
Memory leaks due to the sub-grids not being destroyed properly.
Selection model doesn't work correctly
Events get messed up.

Related

Accessing toolbar from extjs Grid

I have a requirement where I have a number instances of a custom Grid (called PackageGrid).
This Grid has a default Toolbar with a couple of buttons. However for each instance of the Grid that I create, some additional widgets can be added to the toolbar using the insert method on the toolbar like so :
tBar.insert(0, {xtype:'button'})
My first approach was to define a custom toolbar and assign it to a variable, and then add that variable to my Grid, like so :
var tb = Ext.create('js.grid.Toolbar') //my custom toolbar
Ext.define('js.grid.PackageGrid', {
referenceToToolbar: tb,
extend: 'Ext.grid.Panel',
tbar: tb //this.toolbar
});
I hold a reference to the toolbar called referenceToToolbar. I then later grab this toolbar reference and add my widgets.
this.packageGrid = Ext.create('js.grid.PackageGrid')
var tBar = this.packageGrid.referenceToToolbar;
tBar.insert(0, {....})
The problem with this approach is that when I add widgets using tBar.insert(..) to my grid instances, ALL of my grids isntances get the same widgets... because, while the Grids are seperate instances, there is only one toolbar instance shared across all grids (tb).
I have tried playing around with the initComponent method to create an instance of the toolbar.
Basically I need ONE instance of a toolbar for ONE instance of my grid. And then be able to get a reference to that toolbar (before render time), and add some more widgets.
Can that be done?
You can pass additional toolbar item as configuration into grid. Then in grid's initComponent method you can create grid's tbar with merged items (shared and additional).
So your grid definition could be like this:
Ext.define('js.grid.PackageGrid', {
extend: 'Ext.grid.Panel',
initComponent: function() {
var me = this;
me.initTbar();
me.callParent();
},
initTbar: function() {
var me = this;
var tbarItems = [{
xtype: 'button',
text: 'Shared Button'
}];
if (me.aditionalTbarItems && me.aditionalTbarItems.length) {
tbarItems = me.aditionalTbarItems.concat(tbarItems);
}
me.tbar = tbarItems;
}
});
Then you can pass additional toolbar items in configuration when you are creating instance of your grid:
var grid1 = Ext.create('js.grid.PackageGrid', {
title: 'Grid 1',
aditionalTbarItems: [{
xtype: 'button',
text: 'Grid 1 Button'
}],
renderTo: Ext.getBody()
});
Fiddle with example: https://fiddle.sencha.com/#fiddle/70q

EXT JS 3.0 Grid , Show column when data is not empty

Is there a way to show columns only when they have data in them?
var grid = new Ext.grid.GridPanel({
width:938,
height:auto,
store: store,
renderTo: 'Div',
// grid columns
columns:[
{coloum1},
{coloum2},
{coloum3},
{coloum4} ] }};
// Only show column when it has data
In the store config use the load event.
var myStore = new JsonStore({
.. config..
listener :
{
'load': function(){
/*
Code to check if the column data is empty - returns true/false
*/
if(isEmpty)
{
mygrid.getColumnModel().setHidden(colIndex,true);
}
}
});
Relevant API doc here
This is blind coding and written without testing. But it should work.

ExtJS extend grid RowEditor plugin (to edit array)

I've been using the ExtJS grid row editing plugin pretty liberally for CRUD operations in web applications. Now, I have a requirement to allow a database record to be edited along with a related collection/array (from another datastore) using this row editing plugin.
To do this I want to insert drag-n-drop grids inside of a row that has been selected for editing, one grid showing the available (unused) collection items on the left and another grid to hold the defined collection items on the right.
To illustrate what I am trying to do, here is the normal row editing plugin with a row selected for editing:
I am trying to do this (drag-n-drop grids inside of row editor div):
To do this I have been trying to simply run something like Ext.getCmp(???).add(myDnDGridPanel); but I haven't found the right thing to attach this to (what to put in the question marks).
It seems reasonable enough to use this plugin to edit the related collection/array along with the database record. Does anyone know a simple way to add items to this row editor div?
Or... will I have to hack/extend the plugin to accomplish this?
Below is example RowEditing plugin modification which allows to add additional components. In this demo this is only a button, but it should be easy to customize.
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false,
listeners: {
beforeedit: function(editor, e, eOpts) {
var body = this.editor.body;
var container = body.down('.container-for-extra-content');
if (!container) {
container = Ext.core.DomHelper.insertAfter(body.last(), '<div class="container-for-extra-content"></div>', true);
container.setWidth(this.editor.body.getWidth(true));
container.setHeight(this.extraHeight);
this.editor.getEl().setHeight(this.editor.getEl().getHeight() + this.extraHeight);
this.editor.body.setHeight(this.editor.body.getHeight() + this.extraHeight);
var panelConfig = {
renderTo: container,
items: [this.extraComponent]
};
Ext.create('Ext.Panel', panelConfig);
}
},
delay: 1
},
extraHeight: 100,
extraComponent: {
xtype: 'panel',
items: [
{ xtype: 'button', text: 'Aloha!' }
]
}
});
Here is working sample: http://jsfiddle.net/e2DzY/1/

Extjs Dynamic Grid

I'm trying to create a dynamic grid using ExtJS. The grid is built and displayed when a click event is fired then an ajax request is sent to the server to fetch the columns, records and records definition a.k.a store fields.
Each node could have different grid structure and that depends on the level of the node in the tree.
The only way I came up with so far is :
function showGrid(response, request) {
var jsonData = Ext.util.JSON.decode(response.responseText);
var grid = Ext.getCmp('contentGrid' + request.params.owner);
if (grid) {
grid.destroy();
}
var store = new Ext.data.ArrayStore({
id: 'arrayStore',
fields: jsonData.recordFields,
autoDestroy: true
});
grid = new Ext.grid.GridPanel({
defaults: {
sortable: true
},
id: 'contentGrid' + request.params.owner,
store: store,
columns: jsonData.columns,
//width:540,
//height:200,
loadMask: true
});
store.loadData(jsonData.records);
if (Ext.getCmp('tab-' + request.params.owner)) {
Ext.getCmp('tab-' + request.params.owner).show();
} else {
grid.render('grid-div');
Ext.getCmp('card-tabs-panel').add({
id: 'tab-' + request.params.owner,
title: request.params.text,
iconCls: 'silk-tab',
html: Ext.getDom('grid-div').innerHTML,
closable: true
}).show();
}
}
The function above is called when a click event is fired
'click': function(node) {
Ext.Ajax.request({
url: 'showCtn',
success: function(response, request) {
alert('Success');
showGrid(response, request);
},
failure: function(results, request) {
alert('Error');
},
params: Ext.urlDecode(node.attributes.options);
}
});
}
The problem I'm getting with this code is that a new grid is displayed each time the showGrid function is called. The end user sees the old grids and the new one. To mitigate this problem, I tried destroying the grid and also removing the grid element on each request, and that seems to solve the problem only that records never get displayed this time.
if (grid) {
grid.destroy(true);
}
The behaviour I'm looking for is to display the result of a grid within a tab and if that tab exists replaced the old grid.
Any help is appreciated.
When you are trying to add your grid to the tab like this:
html:Ext.getDom('grid-div').innerHTML,
Ext is not aware of it being a valid grid component. Instead, you are simply adding HTML markup that just happens to look like a grid, but the TabPanel will not be aware that it is a grid component.
Instead you should add the grid itself as the tab (a GridPanel is a Panel and does not need to be nested into a parent panel). You can do so and also apply the needed tab configs like this:
Ext.getCmp('card-tabs-panel').add({
Ext.apply(grid, {
id: 'tab-' + request.params.owner,
title: request.params.text,
iconCls: 'silk-tab',
closable: true
});
}).show();
BTW, constantly creating and destroying grids is not an ideal strategy if you can avoid it. It might be better to simply hide and re-show grids (and reload their data) based on which type of grid is needed if that's possible (assuming the set of grid types is finite).
A potential option is to use the metaData field on the JsonStore that allows dynamic reconfiguring of the grid columns as per new datasets.
From
One of the most helpful blog posts about this that Ive found is this one:
http://blog.nextlogic.net/2009/04/dynamic-columns-in-ext-js-grid.html and the original info is well documented at http://docs.sencha.com/ext-js/3-4/#!/api/Ext.data.JsonReader

how to show/ hide column in a extjs 3 grid panel

I have a grid panel i need to show / hide columns in a grid panel depending on the value of a checkbox. If the checkbox is checked i need to display column in the grid and if it is unchecked i need to hide the column in the grid.
Here is my code
var chkEnableDisplayResponsibilityForAction = '<%=Session["chkEnableDisplayResponsibilityForAction"]%>';
var flags = Boolean.parse(chkEnableDisplayResponsibilityForAction);
var flags1 = !Boolean.parse(chkEnableDisplayResponsibilityForAction)
var colModel = new Ext.grid.ColumnModel([
{ header: "PricePlanID", width: 100, sortable: true, dataIndex: 'PricePlanID', hidden: flags, hideable: flags1 },
]);
when i refresh the page i am not able to toggle the columns depending on the value of the checkbox. But when i login and log out i am able to see the changes in the grid panel. Can anyone help me in refreshing the column values in the grid panel?
if take a look at the ExtJS API, particulary the ColumModel there is a setHidden method, it would hide/show a column in a GridPanel.
myGrid.getColumnModel().setHidden(0, true);
you should also hook the onchange event of your check box so you can show or hide the column
In Ext JS 4.1, to hide a column, you use:
grid.columns[0].setVisible(false);
Looks like getColumnModel() with its setHidden() method is no longer part of the grid:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.Panel
You can show/hide columns using column header menu - you can choose which column you want to have shown. Anyway, if you want to show/hide a column, try this
myGrid.getColumnModel().setHidden(0, true);
In ExtJS 4 gain access to your grid panel, and then access the columns attribute which is an array of Column objects.
From there you can use the array iterator methods ( http://www.diveintojavascript.com/core-javascript-reference/the-array-object ) to perform an action.
In the below example I hide and show a few of the columns based on their header names, but you can obviously perform action based on any Column attribute.
var grid = Ext.getCmp( 'my_grid_panel' );
grid.columns.forEach( function( col ) {
if( ( col.text == "Foo" ) || ( col.text == "Bar" ) ) {
col.setVisible( true );
} else if( col.text == "Baz" ) {
col.setVisible( false );
}
});
The answers above I think are pretty good.
But let me give you a advice.
1) In ExtJS 4.x it is recommended to use Ext.ComponentQuery`s methods instead of Ext.getCmp()
2) To hide/show columns of the grid you can use following code
Ext.ComponentQuery.query('grid gridcolumn[dataIndex^="service"]')[0].hide()
or to show
Ext.ComponentQuery.query('grid gridcolumn[dataIndex^="service"]')[0].show()
It should resolve hiding/showing any column in a grid.
Here grid is your grid , it maybe id or xtype etc.
setVisibleColumn : function(name, flag) {
name = Ext.Array.from(name);
var column;
for (var i = 0; i < name.length; i++) {
column = this.getColumn(name[i]);
if (column) {
flag ? column.show() : column.hide();
}
}
}

Resources