ExtJS4 - Extending Ext.tab.Panel to prevent setting of height values - extjs

I am migrating an application from ExtJS 3.x to v4 and have been having some troubles with the TabPanel's now that the "autoHeight" property has been removed. I know that if you do not explicitly define a height for the panel it is assumed to be "auto height", but that is only true to a degree.
In ExtJS4, a tab panel with no height set will still have inline css height values set on the tab panel's containing divs, and those heights are calculated from the initial height of each tab item's content. And yes, if you update the height of any child components of the tab items, the height of the tab will be recalculated to fit it, or if the tab contains raw HTML and the tab's update() method is used to change that content, its height again, will be adjusted to fit.
Where the issue is, in my application anyway, is that I update the raw HTML content of those tab's using methods other than those in ExtJS's framework, such as jQuery.html(). Since the tab panel is not being notified of this change to the content, it does not recalculate the height value of the tab.
To get around this all I want to do is ensure that the tab panel's containing elements always are set to height:auto when rendered, re-rendered, or anything else. I'm assuming to accomplish this I would need to extend the TabPanel, but i don not know where to start as far as what methods to override, ect. Any thoughts?

This is what I ended up doing. It's definitely not ideal, pretty hacky but it seems to work ok. Maybe someone will better see what I'm try to accomplish now, and can come up with a better implementation :-)
Ext.define('Ext.tab.AutoHeightPanel', {
extend: 'Ext.tab.Panel',
alias: 'widget.autoheighttabs',
constructor: function(cnfg){
this.callParent(arguments);
this.initConfig(cnfg);
this.on('afterlayout', this.forceAutoHeight, this);
this.on('afterrender', this.forceAutoHeight, this);
this.on('resize', this.forceAutoHeight, this);
},
forceAutoHeight: function(){
this.getEl().applyStyles({height : 'auto', overflow : 'visible'});
this.items.each(function(item, idx, len) {
if(Ext.isDefined(item.getEl())) item.getEl().applyStyles({height : 'auto', overflow : 'visible'});
});
}
});
You may want to add a 'margin-bottom' value to the style config of your tab panel to prevent content from butting up against the bottom of the panel.

The catchy part is making ExtJS aware that the component is updated. You need to basically, recalculate the component layout. You can use the method doLayout( ) available with the Panel class. By calling this, you are forcefully asking to the layout to be recalculated and refreshed. I think this should help you out.

Related

Extjs Gridpanel buffered renderer scroll not reseting

I have been trying to implement a buffered grid panel using the buffered store and "bufferedrenderer" plugin with ExtJs 5.1.1. When I load lesser content than the previously loaded content, the scroll is not reseting. I still have to scroll long way down to find my content on the panel. The height of the content area remains as the previous content's height. It would be really grateful if somebody can give me a suggestion.
Thank you in advance.
We experienced the same when switching from a grid with many elements (+ some scrolling done ) to the same grid with no element.
We solved this by overriding Ext.data.Store to throw a clear event when clearData() is called. The clear event triggers a call to onStoreClear() of
Ext.grid.plugin.BufferedRenderer. This solved the problem for us.
Ext.define('Ext.data.Store', {
override: 'Ext.data.Store',
config: {
forceClearEventOnLoad: false
},
clearData: function(isLoad, data) {
if(this.forceClearEventOnLoad && isLoad) {
this.fireEvent('clear', this, data);
}
this.callParent(arguments);
}
});
Dont forget to set forceClearEventOnLoad:true in your store config.

ExtJS Repositioning/resizing toolbar on window resize

I have a toolbar inside a simple container. They get rendered on a window's div. When I resize the window the toolbar remains stationary. If the window gets smaller the toolbar starts disappearing (overflowing outside). If the window gets bigger the toolbar stays in its position instead of trying to remain to the far right where it started. I've tried the resize and enable overflow configs but nothing seems to work. I'm thinking that its positioning through the div might be the problem but I'm not sure how to test or fix that. Any ideas?
Some sample code:
var toolbar = Ext.create('MyToolbar');
var toolbarContainer = Ext.create('widget.contaienr', {renderTo: 'myDiv', items: [toolbar]});
.
.
.
<div id='myDiv'></div>
Check this function in the EXtJs docs
onWindowResize( fn, scope, [options] )
Adds a listener to be notified when the browser window is resized and provides resize event buffering (100 milliseconds), passes new viewport width and height to handlers.
Example code looks like the below(I guess you have to write it in your afterRender .(You have to add this event and then fire it.))
Adding the event in the init component looks like below
this.addEvents('setInboxTileSource');
Firing the event in the afterRender looks like below
Ext.EventManager.onWindowResize(function (w, h) {
this.fireEvent('BROWSER_WINDOW_RESIZE')
}, this, {buffer: 150});
You have to listen the event and set your width and height for your toolbar.
listeners: {
BROWSER_WINDOW_RESIZE: this.handleResize,
scope: this
}
handleResize:function(){
this.setHeight(Ext.getBody().getViewSize().height - 270);
this.setWidth(Ext.getBody().getViewSize().width- 100);
}
Hope this helps you...
Toolbars should not be configured that way. If you have a window, it should be configured this way:
Ext.create('Ext.window.Window',{
title:'some title'
,width:400
,height:300
,tbar:[{
// here come toolbar items
}]
});
For more examples see http://docs.sencha.com/extjs/4.2.2/extjs-build/examples/menu/menus.html and other toolbar examples.

Creating an "auto height" TabPanel in ExtJS 4 that is rendered to non-extjs HTML?

This was pretty easy to do in 3.x, simply by setting the "autoHeight" property of the TabPanel and the same for its children items via the "defaults" config. However it I have yet to seen a way to accomplish this in 4.x. The tabs do size to fit the initial height of their contents, however if the height of that content changes for any reason after init, the tab content is hidden/scrolled.
I did some searching already and in sencha's official forums about this subject the most commonly suggested solution was to configure the tabpanel's parent container's layout as "fit", setting align to "stretch, ect. However in my case, the TabPanel is not a child of another Ext component, it is "renderTo"'ed a straight non-ext generated that sits somewhere in the body of my page, so these solutions wouldn't apply.
Any ideas?
This was my solution in case any one was interested: It's definitely not ideal, pretty hacky but it seems to work ok. Maybe someone will better see what I'm try to accomplish now, and can come up with a better implementation :-)
Ext.define('Ext.tab.AutoHeightPanel', {
extend: 'Ext.tab.Panel',
alias: 'widget.autoheighttabs',
constructor: function(cnfg){
this.callParent(arguments);
this.initConfig(cnfg);
this.on('afterlayout', this.forceAutoHeight, this);
this.on('afterrender', this.forceAutoHeight, this);
this.on('resize', this.forceAutoHeight, this);
},
forceAutoHeight: function(){
this.getEl().applyStyles({height : 'auto', overflow : 'visible'});
this.items.each(function(item, idx, len) {
if(Ext.isDefined(item.getEl())) item.getEl().applyStyles({height : 'auto', overflow : 'visible'});
});
}
});
You may want to add a 'margin-bottom' value to the style config of your tab panel to prevent content from butting up against the bottom of the panel.
I had the same problem, and my solution is not great, but I knew when my content was updated, so it was all just a matter of calling doComponentLayout() on the panel when necessary.

How to refresh a panel after data is loaded?

I have a extjs panel rendered inside a div like this:
panel = new Ext.Panel({
layout : 'fit',
renderTo: 'my_div',
monitorResize: true, // relay on browser resize
height: 500,
autoWidth: true,
items : [
centerPanel
],
plain : true
});
After the page has loaded the panel is empty, but when I resize the browser the contents appears by magic!
I think the data has not finished loading when the panel is rendered the first time.
How can I get the contents to show without resizing the browser?
I suspect the issue is that you need to explicitly cause the panel to be rendered. After creating the panel, make the following call:
panel.doLayout();
Sencha documentation says "A call to this function is required after adding a new component to an already rendered container, or possibly after changing sizing/position properties of child components."
Any reason why you're nesting a panel within a panel? Seems like centerPanel could be directly rendered to your containing div. Also, the issue is most likely how you have centerPanel configured, or how you're loading it, neither of which you're showing here. You should not need to call doLayout() manually in this case, it's probably an issue with how your components are configured.
bmoeskau is right, also my guess is you have an async server request that loads your data (store.load, ajax, etc) -you could call the layout after that store loads by regestering a callback function (see sencha docs)
tedder suggestion helped me, but in itself did not solve a similar problem I had: adding one Ext.draw.Component I got a blank panel.
The curious part is, the panel looked white, but the DOM components were all there and I could inspect them using e.g. Chrome developer tools.
I got it working by using a workaround. I added those 2 instructions after the call to this.add(component):
this.setVisible(false);
this.setVisible(true);
Hiding the panel and then making it visible again, in some obscure way, does the job.

vertical scrollbar in ExtJS GridPanel

I'm working on a project where I have a single GridPanel on a page. The panel can display any number of rows and I have the autoHeight property set, which causes the GridPanel to expand to fit the number of rows. I now want a horizontal scrollbar because on some resolutions not all columns get displayed (and I cannot reduce the number of columns).
If I set the autoHeight I have no horizontal scrollbar, if I do not set it and set a fixed height I have a horizontal scrollbar but the GridPanel obviously does not fit the number of rows....
Is there anything I can do to fix this? I can't seem to find a property that would achieve the result I need.
You will find that putting a parent container (Ext.panel.Panel or any container really) around your grid panel to be successful. If you hard code the height, width and layout (to 'fit') on the parent container, the child item (Ext.grid.Panel) will expand to fill the entire space available from it's parent container.
See pages 80 and 81 of Ext JS 4 Web Application Development Cookbook.
You can use the lazy instantiation notation for 'Ext.grid.Panel'. Meaning use 'grid' for your child container (item) xtype property.
Ext.create('Ext.panel.Panel', {
title: 'parent container',
width: 800,
height: 600,
layout: 'fit',
items: {
xtype: 'grid',
title: 'child container',
... define your grid here
},
renderTo: 'grand parent container'
});
My thought would be to set autoScroll: true on the panel.Panel that contained the grid.
This seems like an issue with your layout settings as opposed to the object properties.
Try setting the layout property of the parent container to 'fit'- can you also provide a code excerpt?
As Ergo said, this is more likely a layout problem - the GridPanel is probably higher than the panel containing it, high enough not to need a scrollbar but not fully visible, obviously. Put the GridPanel into a container with a proper layout, i.e. border layout, fit layout or card layout. Getting layout managers right is generally one of the hardest part of ExtJS-Fu.
adding
viewConfig = {
scroll:false,
style:{overflow: 'auto',overflowX: 'hidden'}
}
sometimes causes a bug with displaying 2 scrollbars. To prevent it in my case I added a listener. And then works fine.
this.on('scrollershow',function(scroller,orientation,eOpts){
if (orientation=='vertical'){
scroller.hide();
}
},this);

Resources