PDA

View Full Version : Double boxWrapping



MD
9 Aug 2009, 9:42 PM
I'm having some trouble wrapping my head around doing a double-boxWrap(). I got a point in the right direction from Condor and evant in this thread (http://extjs.com/forum/showthread.php?p=342978#post342978):
You can't just boxWrap a component in a layout and expect the layout to still be able to function properly!

You need to tell the layout that the component is contained in a new element, e.g.

this.positionEl = this.el.boxWrap();
That works perfectly fine when I'm only doing a single boxWrap(), but in the cases where I need to double-boxWrap() a few things, it errors out and the layout goes all to hell. I'm failing to understand how to properly use positionEl when I have it doubled.

A basic test case:
Ext.onReady(function(){
new Ext.Viewport({
items: [{
xtype: 'container',
width: 600,
style: {textAlign: 'center', margin: '0 auto'},
items: [{
xtype: 'container',
items: [{
xtype: 'toolbar',
listeners: {
render: {
fn: function(){
this.positionEl = this.el.boxWrap().addClass('custom-boxwrap-inner');
this.container.boxWrap().addClass('custom-boxwrap-outer');
}
}
},
items: [{
xtype:'splitbutton', text: 'A', menu: [{text: 'Submenu Item'}]
},{
xtype:'splitbutton', text: 'B', menu: [{text: 'Submenu Item'}]
},{
xtype:'splitbutton', text: 'C', menu: [{text: 'Submenu Item'}]
},'->','-',{
xtype:'splitbutton', text: 'D', menu: [{text: 'Submenu Item'}]
},{
text: 'E'
}]
}]
}]
}]
});
});

And why am I doing double-boxWrap()'s? To achieve the following types of things:

Animal
9 Aug 2009, 11:25 PM
I'm having some trouble wrapping my head around doing a double-boxWrap(). I got a point in the right direction from Condor and evant in this thread (http://extjs.com/forum/showthread.php?p=342978#post342978):
That works perfectly fine when I'm only doing a single boxWrap(), but in the cases where I need to double-boxWrap() a few things, it errors out and the layout goes all to hell. I'm failing to understand how to properly use positionEl when I have it doubled.

A basic test case:
Ext.onReady(function(){
new Ext.Viewport({
items: [{
xtype: 'container',
width: 600,
style: {textAlign: 'center', margin: '0 auto'},
items: [{
xtype: 'container',
items: [{
xtype: 'toolbar',
listeners: {
render: {
fn: function(){
this.positionEl = this.el.boxWrap().addClass('custom-boxwrap-inner');
this.container.boxWrap().addClass('custom-boxwrap-outer');
}
}
},
items: [{
xtype:'splitbutton', text: 'A', menu: [{text: 'Submenu Item'}]
},{
xtype:'splitbutton', text: 'B', menu: [{text: 'Submenu Item'}]
},{
xtype:'splitbutton', text: 'C', menu: [{text: 'Submenu Item'}]
},'->','-',{
xtype:'splitbutton', text: 'D', menu: [{text: 'Submenu Item'}]
},{
text: 'E'
}]
}]
}]
}]
});
});

And why am I doing double-boxWrap()'s? To achieve the following types of things:

So you are wrapping the Toolbar, AND the Container?

Won't that look weird?

I suggest writing a plugin whcih boxWraps its client Component. Then we have a class to work on.

MD
10 Aug 2009, 5:42 AM
Yes, that's right. You think the two images I attached look weird? That's the effect I'm able to achieve by using two custom wraps.

Thank you for the suggestion -- I'll take a look at doing a plugin. I'd really like to at least understand though how positionEl would work in this case, having those two calls to boxWrap in succession, and if it's indeed possible to do it this way, however less-than-ideal it may be.


So you are wrapping the Toolbar, AND the Container?

Won't that look weird?

I suggest writing a plugin whcih boxWraps its client Component. Then we have a class to work on.

Animal
10 Aug 2009, 5:46 AM
For a Component, its positionEl must be the element upon which its owning layout manager operates to move that Component around.

So if you wrap any Component with some Element, then that outer Element becomes the positionEl

MD
10 Aug 2009, 12:06 PM
Thanks, Animal -- makes a lot more sense to me now. As you suggested, I created a little plugin. It works, but I'd appreciate any suggestions on improving it.


Ext.ns('Ext.ux.plugin');

Ext.ux.plugin.ContainerBoxWrapper = Ext.extend(Ext.Container, {
init: function(container){
var cls = (this.cls || '');
Ext.apply(container, {
onRender: function(container){
Ext.Container.superclass.onRender.call(this, container);
this.positionEl = this.el.boxWrap().addClass(cls);
}
});
}
});

Ext.preg('boxwrap', Ext.ux.plugin.ContainerBoxWrapper);

And instead of setting it up in the render listener, I can now call it like:


...
items: [{
xtype: 'container',
width: 600,
style: {textAlign: 'center', margin: '0 auto'},
items: [{
xtype: 'container',
plugins: {ptype: 'boxwrap', cls: 'custom-boxwrap-outer'},
items: [{
xtype: 'toolbar',
plugins: {ptype: 'boxwrap', cls: 'custom-boxwrap-inner'},
...

Animal
10 Aug 2009, 1:32 PM
Looks great.

To save resources, I try to use {single: true} on one-off listeners like render listeners. It removes itself as soon as it's fired.

MD
10 Aug 2009, 1:56 PM
Thanks! \:D/

You mean {single: true} as part of the Ext.apply() like this, or?:


Ext.apply(container, {
onRender: function(container){
Ext.Container.superclass.onRender.call(this, container);
this.positionEl = this.el.boxWrap().addClass(cls);
}
}, {single: true});

Animal
10 Aug 2009, 9:41 PM
Maybe you've been around so long that you haven't revisited the bits of the manual you used when you were a beginner.

It's worth going back there from time to time: http://extjs.com/deploy/dev/docs/?class=Ext.Component&member=addListener

Options is the 4th param, not the 3rd

MD
11 Aug 2009, 9:12 AM
Thanks, Animal. I took a look back at the docs, but I don't see how that applies now because I'm no longer setting up listeners in the way I had originally -- neither in 'listeners: {}' form, nor as '.on()'s. I dropped the original 'listeners: {}' in favour of doing both boxWrap()'s via the plugin. Or am I just being a dunce? :-?

Animal
11 Aug 2009, 9:14 AM
Ah, yes, if you are hooking into the Component lifecycle template methods directly, then there are no listeners to add or remove. It is more efficient that way.