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.
Related
I am working on a switch from version 4.1.1 to 4.2.1 and finally I need to fix hopefully the last bug. We have a gridview with view being overriden by simple (?) Ext.XTemplate, as follows:
Ext.define('view.monitoring.Event',
{
extend: 'Ext.view.View',
alias: 'widget.default_monitoring_event',
itemSelector: '.monitoring-thumb-fumb',
tplWriteMode: 'overwrite',
autoWidth: true,
initComponent: function()
{
var tplPart1 = new Ext.XTemplate('<SOME HTML 1>');
var tplPart2 = new Ext.XTemplate('<SOME HTML 2>');
var tplPart3 = new Ext.XTemplate('<SOME HTML 3>');
var tplPart4 = new Ext.XTemplate('<SOME HTML 4>');
this.tpl = new Ext.Template('<BUNCH OF HTML AND TPL and TPL INSIDE TPL',
callFunc1: function(data) { /* do something with tplPart1 */ },
callFunc2: function(data) { /* do something with tplPart2 */ },
callFunc3: function(data) { /* do something with tplPart3 */ },
callFunc4: function(data) { /* do something with tplPart4 */ },
);
this.callParent(arguments;
}
}
This view is set for the grid in this way:
Ext.define('view.monitoring.WeeklyOverview',
{
extend: 'Ext.grid.Panel',
alias: 'widget.default_monitoring_weeklyoverview',
layout: 'border',
title: Lang.translate('event_monitoring_title'),
overflowX: 'hidden',
overflowY: 'auto',
initComponent: function()
{
//...
this.view = Ext.widget('default_monitoring_event', {
store: Ext.create('store.monitoring.Rows')
});
//...
}
}
Then in controller onRender the stores gets populated (the store of the grid is AJAX, loads the data and passes them to a memory store of the view). In ExtJS 4.1.1 this is working properly, data are loaded and the template is parsed and HTML is displayed containing the data.
But after the switch to 4.2.1 the HTML is no longer filled with the data and nothing is displayed but an empty HTML table (which appears as like nothing would be rendered). As there is at least some part of HTML but no data, I guess the problem might be with the data being applied for the template.
Does anybody know what might be/went wrong?
UPDATE: After debugging and the custom view template simplification I have found out, that even the custom view has set it's own store with it's own root for the data returned, it ignores that setting and simply loads the data for the store of the Ext.grid.Panel component. The AJAX response looks like:
{
user: {},
data: [
0: { ... },
1: { ... },
...
],
rows: [
0: { ... },
1: { ... },
...
]
}
Here the data should be used for Ext.grid.Panel component and the rows should be then populated by the custom view (configured with Ext.XTemplate). Seems like for the children views always the parent's store's root element is returned. Any way how to workaround this behaviour and make the custom view to use it's own store???
Finally found a solution.
The problem was that after the main grid.Panel loaded the data it distributed them also to it's (sub)view. After that even I had manually loaded the right data into this custom XTemplate, it needed to also manually override previously rendered view.
In my controller (init -> render) I needed to do this:
var me = this;
this.getMainView().store.load({
params: params || {},
callback: function(records, operation, success) {
// this line was already there, working properly for ExtJS 4.1.1, probably is now useless for ExtJS 4.2.1 with the next line
me.getCustomView().store.loadRawData(this.proxy.reader.rawData);
// I had to add this line for ExtJS 4.2.1...
me.getCustomView().tpl.overwrite(me.getCustomView().el, this.proxy.reader.rawData.rows);
}
});
This is kinda strange as I thought that with a definition within a custom view (see my question above)
tplWriteMode: 'overwrite',
it should just automatically overwrite it's view...
Hi i have a grid with values ,
when i click a the row in the grid i need to
open a window with all the values in that row.
I have done till loading a grid and populating values in the grid. I am working in ext js for the last two weeks can any one tell me how to proceed further
My Code:
function loadcolleaguesVal(jsonContent){
var localJson = Ext.util.JSON.decode(jsonContent);
colleagueGridJS=Ext.util.JSON.decode(localJson.ColleagueInfo);
colleagueGridDataJS=Ext.util.JSON.decode(localJson.colData);
var caseReGridData= new Ext.data.JsonStore({
autoLoad :true,
fields: ["NAME",
"TOTAL_CASES_ALLOWED",
"TOTAL_OPEN_CASES",
"CLIENT_TEAM_CASES_ALLOWED",
"CLIENT_TEAM_TOTAL_CASES",
"PAY_AUTH_MAX",
"DAYS_MAX",
"LUMP_SUM_MAX",
"DENIAL_ADMIN",
"DENIAL_CLINICAL"],
storeId :'ColleagueInfo',
data : colleagueGridDataJS,
root : 'data',
listeners : {
load : colleagueGridListerner
}
});
}
function colleagueGridListerner(){
nucleus.tools.master(colleagueGridJS,"NonEditableGrid","colleagueGrid",caseReGridData,"twoFields");
panelForPage.addButton({
text:'Add new colleague',
type:'Submit',
name:'btnGo',
handler:function()
{
showColleagueSetup();
}
});
Ext.getCmp('colleagueCenter').add(panelForPage);
Ext.getCmp('colleagueGrid_Grid').setHeight(145);
Ext.getCmp('colleagueGrid_Grid').doLayout();
tabPanel.doLayout();
Ext.getCmp("colleagueGrid_Grid").collapse();
}
I can't see grid into your code but you can add selection model into grid:
var grid = new Ext.grid.GridPanel({
.
.
.
sm:new Ext.grid.RowSelectionModel({singleSelect:true}),
.
.
});
and add event:
grid.getSelectionModel().on('rowselect', function (selModel, rowIndex, record ) {
//Your row selected data is:
var data = record.data;
//Open window code
...
});
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.
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
Am trying to set 'seriesstyles' to piechart dynamically from the JSON data. When the 'oneWeekStore' loads the JSON data, I wish to iterate through the 'color' of each record and setSeriesStyles dynamically to PieChart. Below is the snippet.
var oneWeekStore = new Ext.data.JsonStore({
id:'jsonStore',
fields: ['appCount','appName'],
autoLoad: true,
root: 'rows',
proxy:storeProxy,
baseParams:{
'interval':'oneWeek',
'fromDate':frmDt.getValue()
},
listeners: {load: {
fn:function(store,records,options) {
/*I wish iterate through each record,fetch 'color'
and setSeriesStyles. I tried passing sample arrays
as paramater to setSeriesStyles like
**colors= new Array('0x08E3FE','0x448991','0x054D56');
Ext.getCmp('test12').setSeriesStyles(colors)**
But FF throws error "this.swf is undefined". Could
you please let me know the right format to pass as
parameter. */
}
});
var panel = new Ext.Panel{
id: '1week', title:'1 week',
items : [
{ id:'test12',
xtype : 'piechart',
store : oneWeekStore,
dataField : 'appCount',
categoryField : 'appName',
extraStyle : {
legend:{
display : 'right',
padding : 5,
spacing: 2, font :color:0x000000,family:
'Arial', size:9},
border:{size :1,color :0x999999},
background:{color: 0xd6e1cc}
} } } ] }
My JSON data looks below:
{"success":true,"rows":[{"appCount":"9693814","appName":"GED","color":"0xFB5D0D"},{"appCount":"5731","appName":"SGEF"","color":"0xFFFF6B"}]}
Your guidance is highly appreciated
You have a classic race condition there - your setting an event in motion that relies on a Component who's status is unknown.
The event your setting off is the loading of the data Store, when that has finished loading it is trying to interact with the Panel, but at that point we don't know if the Panel has been rendered yet.
Your best bet is to make one of those things happen in reaction to the other, for example:
1 ) load the store
2 ) on load event fired, create the panel
var oneWeekStore = new Ext.data.JsonStore({
id:'jsonStore',
...,
listeners: {
load:function(store,records,options) {
var panel = new Ext.Panel({
...,
seriesStyles: colors,
...
});
}
}
});
or
1 ) create the panel (chart)
2 ) on render event of the panel, load the store (remove autoLoad:true)
var panel = new Ext.Panel({
id: '1week',
...,
listeners: {
render: function(pnl){
oneWeekStore.load();
}
}
});
Hope that helps.