-
9 Jan 2012 9:26 AM #1
Grid HeaderCt resize problem
Grid HeaderCt resize problem
Hello,
If you look at the infinite grid, or I assume any grid in this case, do the following:
Ext.ComponentQuery.query('grid')[0].headerCt.setHeight(70)
After setting the height, when you resize a column header, the underlying column does not change its size. This is new in 4.1 because I was using it fine it 4.0. I need to resize the columns because we put filters in the headers. Any Thoughts?
Thanks.
-
9 Jan 2012 9:41 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,714
- Vote Rating
- 436
I'm seeing pretty much the same behavior as in 4.0.7 except in 4.1.0 it moves the rows down correctly.
Not sure if you know but you can pass a header config object to the panel:
The columns are still small but the header container is sized. The header container uses the gridcolumn layout which is an extension of HBox. The layout is hardcoded in the header container to use align : 'stretchmax' but since you can pass a header container config you can pass in the layout. Here is an edited example:Code:columns : { border : true, height : 100, items : [....] //array of columns }
This works in 4.1.0 beta 1Code:Ext.onReady(function() { Ext.QuickTips.init(); // sample static data for the store var myData = [ ['3m Co', 71.72, 0.02, 0.03, '9/1 12:00am'], ['Alcoa Inc', 29.01, 0.42, 1.47, '9/1 12:00am'], ['Altria Group Inc', 83.81, 0.28, 0.34, '9/1 12:00am'], ['American Express Company', 52.55, 0.01, 0.02, '9/1 12:00am'], ['American International Group, Inc.', 64.13, 0.31, 0.49, '9/1 12:00am'], ['AT&T Inc.', 31.61, -0.48, -1.54, '9/1 12:00am'], ['Boeing Co.', 75.43, 0.53, 0.71, '9/1 12:00am'], ['Caterpillar Inc.', 67.27, 0.92, 1.39, '9/1 12:00am'], ['Citigroup, Inc.', 49.37, 0.02, 0.04, '9/1 12:00am'], ['E.I. du Pont de Nemours and Company', 40.48, 0.51, 1.28, '9/1 12:00am'], ['Exxon Mobil Corp', 68.1, -0.43, -0.64, '9/1 12:00am'], ['General Electric Company', 34.14, -0.08, -0.23, '9/1 12:00am'], ['General Motors Corporation', 30.27, 1.09, 3.74, '9/1 12:00am'], ['Hewlett-Packard Co.', 36.53, -0.03, -0.08, '9/1 12:00am'], ['Honeywell Intl Inc', 38.77, 0.05, 0.13, '9/1 12:00am'], ['Intel Corporation', 19.88, 0.31, 1.58, '9/1 12:00am'], ['International Business Machines', 81.41, 0.44, 0.54, '9/1 12:00am'], ['Johnson & Johnson', 64.72, 0.06, 0.09, '9/1 12:00am'], ['JP Morgan & Chase & Co', 45.73, 0.07, 0.15, '9/1 12:00am'], ['McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am'], ['Merck & Co., Inc.', 40.96, 0.41, 1.01, '9/1 12:00am'], ['Microsoft Corporation', 25.84, 0.14, 0.54, '9/1 12:00am'], ['Pfizer Inc', 27.96, 0.4, 1.45, '9/1 12:00am'], ['The Coca-Cola Company', 45.07, 0.26, 0.58, '9/1 12:00am'], ['The Home Depot, Inc.', 34.64, 0.35, 1.02, '9/1 12:00am'], ['The Procter & Gamble Company', 61.91, 0.01, 0.02, '9/1 12:00am'], ['United Technologies Corporation', 63.26, 0.55, 0.88, '9/1 12:00am'], ['Verizon Communications', 35.57, 0.39, 1.11, '9/1 12:00am'], ['Wal-Mart Stores, Inc.', 45.45, 0.73, 1.63, '9/1 12:00am'] ]; /** * Custom function used for column renderer * @param {Object} val */ function change(val) { if (val > 0) { return '<span style="color:green;">' + val + '</span>'; } else if (val < 0) { return '<span style="color:red;">' + val + '</span>'; } return val; } /** * Custom function used for column renderer * @param {Object} val */ function pctChange(val) { if (val > 0) { return '<span style="color:green;">' + val + '%</span>'; } else if (val < 0) { return '<span style="color:red;">' + val + '%</span>'; } return val; } // create the data store var store = Ext.create('Ext.data.ArrayStore', { fields: [ {name: 'company'}, {name: 'price', type: 'float'}, {name: 'change', type: 'float'}, {name: 'pctChange', type: 'float'}, {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'} ], data: myData }); // create the Grid var grid = Ext.create('Ext.grid.Panel', { store: store, columns: { border : true, height : 100, layout : { type : 'gridcolumn', availableSpaceOffset : 0, align : 'stretch', resetStretch : true }, items : [ { text : 'Company', flex : 1, sortable : false, dataIndex: 'company' }, { text : 'Price', width : 75, sortable : true, renderer : 'usMoney', dataIndex: 'price' }, { text : 'Change', width : 75, sortable : true, renderer : change, dataIndex: 'change' }, { text : '% Change', width : 75, sortable : true, renderer : pctChange, dataIndex: 'pctChange' }, { text : 'Last Updated', width : 85, sortable : true, renderer : Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange' }, { xtype: 'actioncolumn', width: 50, items: [{ icon : '../shared/icons/fam/delete.gif', // Use a URL in the icon config tooltip: 'Sell stock', handler: function(grid, rowIndex, colIndex) { var rec = store.getAt(rowIndex); alert("Sell " + rec.get('company')); } }, { getClass: function(v, meta, rec) { // Or return a class from a function if (rec.get('change') < 0) { this.items[1].tooltip = 'Hold stock'; return 'alert-col'; } else { this.items[1].tooltip = 'Buy stock'; return 'buy-col'; } }, handler: function(grid, rowIndex, colIndex) { var rec = store.getAt(rowIndex); alert((rec.get('change') < 0 ? "Hold " : "Buy ") + rec.get('company')); } }] } ] }, height: 350, width: 600, title: 'Array Grid', renderTo: Ext.getBody(), viewConfig: { stripeRows: true } }); });Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
9 Jan 2012 11:43 AM #3
did you do grid.headerCt.setHeight(100), then drag and try and resize the header and you should see that the columns are no longer aligned with the header.
-
9 Jan 2012 11:53 AM #4Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,714
- Vote Rating
- 436
In my code it works with resizing columns
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
9 Jan 2012 11:59 AM #5
On an unrelated note, how'd you drop fields into your column headers?
-
9 Jan 2012 12:13 PM #6
Fields in header container
Fields in header container
This is a few step process, so bear with me.
In your columnModel, lets define the coupon column, as seen in the picture above. It has a min-max column filter.
Then the fun begins. Go back to your grid instance, and add the following. Please note that the grid is given a internalGridId in the config. The min max column filter is created with the createMinMaxColumnFilters method.Code:{ text : '<br/>Coupon', dataIndex : 'coupon', width : 85, align: 'right', sortable: true, hideable: true, filter:{ filterType: 'minmax' } }
Code:internalGridId:1, filterInit: function() { Ext.log('FilterInit Started for ' + this.id); var grid = this; this.setUpColumFilters(grid); grid.headerCt.doLayout(); Ext.select('.Filters'+grid.internalGridId).on('click', function(ev, target) { ev.stopEvent(); // ev.stopPropagation(); if (!target.classList.contains('x-form-date-trigger')) target.select(); }); this.filtersCreated=true; }, setUpColumFilters : function(bondlist) { var me = this; Ext.each(bondlist.columns,function(column){ if (column.isGroupHeader){ Ext.each(column.items.items,function(column){ me.createFilter(column,bondlist.internalGridId); }); }else{ me.createFilter(column,bondlist.internalGridId); } }); }, createFilter: function(column,gridId){ var me = this; if (column.filter && !column.isCheckerHd){ var filterId = "Filter"+Ext.String.capitalize(column.dataIndex)+gridId; if (column.filter.filterType=='single'){ me.createSingleColumnFilter(filterId, column.dataIndex, column.width-22, column.filter.maxLength,gridId); }else if (column.filter.filterType=='minmax'){ me.createMinMaxColumnFilters(filterId, "min"+Ext.String.capitalize(column.dataIndex), "max"+Ext.String.capitalize(column.dataIndex),false,gridId); }else if (column.filter.filterType=='begend'){ me.createDateFromToColumnFilters(filterId, "beg"+Ext.String.capitalize(column.dataIndex), "end"+Ext.String.capitalize(column.dataIndex),gridId); } } this.createDateFromToColumnFilters('FilterFirstSettleDate', 'begFirstSettleDate', 'endFirstSettleDate'); }, /** * Creates two textfields where the user specifies them to renderTo. Used in the headerCt of a grid to filter. * @param renderTo div to render textfields to. * @param minName Filters name for Min Value * @param maxName Filters name for Max Value * @param vertical {Boolean} Specifies if the filters are stacked vertically(true) */ createMinMaxColumnFilters : function(renderTo, minName, maxName, vertical,gridId) { if (Ext.fly(renderTo) == null) return false; var minTextField = Ext.create('Ext.form.field.Text', { name : minName, type:'FilterTextBox', emptyText : 'Min', cls : 'Filters'+gridId, width : 30 }); minTextField.on('change', this.fieldChange, this, { buffer : 400 }); var maxTextField = Ext.create('Ext.form.field.Text', { name : maxName, emptyText : 'Max', type:'FilterTextBox', cls : 'Filters'+gridId, width : 30 }); if (vertical == true) { layout = ''; } else { layout = { type : 'hbox' }; } maxTextField.on('change', this.fieldChange, this, { buffer : 400 }); Ext.create('Ext.container.Container', { layout : layout, renderTo : renderTo, items : [ minTextField, { xtype : 'label', text : ' -', cls : 'FilterSeperators'+gridId }, maxTextField ] }); }
Finally, the fields are given a fieldChange function on their change event as you can see above. This will reload the store with the passed in filter.
Code:fieldChangeRemove : function(store, field) { store.filters.each(function(item, index, length) { var newField = ""; newField = field.name; if (newField == item.property) { store.filters.removeAt(index); return false; } }); }, /** * Adds a filter to the store of the grid when user triggers this event. * reloads the store after with the new filter. * @param field * @param newValue * @param oldValue */ fieldChange : function(field, newValue, oldValue) { if (field.validate()){ var store = this.store; // Ext.log('FieldChange Event Started'); this.fieldChangeRemove(store, field); if (newValue != null && newValue != "") { //For rating scores pass in the correct data index store.filters.add({ property : field.name, value : newValue }); } store.load(); } }
-
9 Jan 2012 12:59 PM #7
Where are you creating the div in the column header that you'll be rendering the fields to?
-
9 Jan 2012 1:10 PM #8
Sorry, Cant they make the code section a bit wider? I dont know how anyone can interpret it. Anyways, our column model is generated in getColumnModel(gridId), where gridId is just something to append to the end of the div ID that it will create. We put all of this in a static class.
Code:getColumnModel:function(gridId){ var retVal = [{ text : '<br/>Coupon', dataIndex : 'coupon', width : 85, align: 'right', sortable: true, hideable: true, filter:{ filterType: 'minmax' }]; return this.addFilterDivs(retVal,gridId); }Code:addFilterDivs: function(columns,gridId){ var me = this; Ext.each(columns,function(column){ if (column.columns){ Ext.each(column.columns,function(column){ me.modifyColumnText(column,gridId); }); }else{ me.modifyColumnText(column,gridId); } }); return columns; }, modifyColumnText: function(column,gridId){ if (column.filter && !column.isCheckerHd){ var filterId = "Filter"+Ext.String.capitalize(column.dataIndex)+gridId; var newText = column.text+" <div id="+filterId+"></div>"; column.text = newText; } }
-
9 Jan 2012 1:14 PM #9
an unrelated note back at you
an unrelated note back at you
How do you apply the loadmask on a store load/prefetch in 4.1 beta?
-
9 Jan 2012 1:52 PM #10
That works. Thx for the tips / code. I might see if I can drop that into a plugin.
I should probably defer the loadmask to someone smarter than me, but in case no one else pipes up:
relay the beforeload and load events to the component being loaded by the store and in the listener do setLoading() perhaps?


Reply With Quote