jmaia
23 Nov 2011, 10:29 AM
Hi there,
Just thought I'd share a component that I came up with on my application. It's mainly a button that has a window config object attached, and some other configuration parameters. When the button is clicked it displays the window.
The window position can be determined by the window itself or can be anchored to the button. There are 8 possible anchor positions and they can be something like:
'tl' - displayed on the top of the button, aligned to the left
'bl' - displayed on the bottom of the button, aligned to the left
'lt' - displayed on the left of the button, aligned to the top
etc.
It still has some room for improvement (for example I'm not dealing with the situations where the anchored window goes outside the boundaries of the browser window) but anyway, fee free to use it, if you need something like this.
/**
* A generic button, that opens up a popup window
*/
Ext.define('Ext.ux.button.WindowButton', {
extend: 'Ext.button.Button',
alias: 'widget.windowbutton',
/**
* @cfg {Object} windowConfig The config object for the window that is to be created. If an xtype is not
* provided in this config object then a plain Ext.window.Window will be used
*/
windowConfig: null,
/**
* @cfg {Boolean} closeOnClickOutside Defines whether the window will be closed automatically when the user
* clicks outside of it. Ignored if the window is modal.
*/
closeOnClickOutside: true,
/**
* @cfg {Boolean} closeOnClickTwice Defines whether the window will be closed automatically when the user
* clicks again on the button.
*/
closeOnClickTwice: true,
/**
* @cfg {String} position Defines where the window will be displayed. Can be either 'anchor', 'window'.
* If 'anchor' the window will be anchored to the button (see anchor config), if 'window' the window will be
* placed on its x and y coordinates. If no x and y are defined it will be centered.
*/
position: 'window',
/**
* @cfg {String} anchor Defines where the window will be anchored in relation to the button. Can be one of the
* following: 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb'
*/
anchor: 'tl',
listeners: {
click: function() {
var me = this;
if (! me.isWindowOpen) {
me.openWindow();
}
else {
if (me.closeOnClickTwice) {
me.closeWindow();
}
}
}
},
/**
* @private
*/
initComponent: function() {
var me = this;
me.callParent();
Ext.apply(me, me.initialConfig);
if (me.windowConfig && me.windowConfig.modal) {
me.closeOnClickOutside = false;
}
},
/**
* @private
*/
doWindowDestroy: function(wnd, options) {
var me = this;
me.isWindowOpen = false;
},
/**
* @private
*/
doDocMouseDown: function(evt, element, options) {
var me = this;
if (me.wnd) {
if (!evt.within(me.wnd.el.dom) && !evt.within(me.el.dom)) {
me.closeWindow();
}
}
},
/**
* @private
*/
getWindowXY: function(wnd) {
var me = this;
var xy = [0,0];
if (me.position === 'window') {
xy = [wnd.x, wnd.y];
}
else if (me.position === 'anchor')
{
var box = me.getEl().getBox();
switch (me.anchor) {
case 'rb':
xy[0] = (box.x + box.width + 5);
xy[1] = ((box.y + box.height) - wnd.height);
break;
case 'rt':
xy[0] = (box.x + box.width + 5);
xy[1] = box.y;
break;
case 'lb':
xy[0] = (box.x - wnd.width - 5);
xy[1] = ((box.y + box.height) - wnd.height);
break;
case 'lt':
xy[0] = (box.x - wnd.width - 5);
xy[1] = box.y;
break;
case 'br':
xy[0] = ((box.x + box.width) - wnd.width);
xy[1] = (box.y + box.height + 5);
break;
case 'bl':
xy[0] = box.x;
xy[1] = (box.y + box.height + 5);
break;
case 'tr':
xy[0] = ((box.x + box.width) - wnd.width);
xy[1] = (box.y - wnd.height - 5);
break;
case 'tl':
default:
xy[0] = box.x;
xy[1] = (box.y - wnd.height - 5);
}
}
return xy;
},
/**
* Creates the window object and shows the window
*/
openWindow: function() {
var me = this;
if (me.windowConfig) {
var wnd = Ext.ComponentManager.create(me.windowConfig, 'window');
if (wnd) {
var xy = me.getWindowXY(wnd);
Ext.apply(wnd, {
x: xy[0],
y: xy[1],
animateTarget: me.getEl()
}, {});
wnd.on('destroy', me.doWindowDestroy, me);
wnd.show();
me.isWindowOpen = true;
me.wnd = wnd;
if (me.closeOnClickOutside) {
me.mon(Ext.getDoc(), 'mousedown', me.doDocMouseDown, me);
}
}
}
},
/**
* Closes the window and destroys it's object
*/
closeWindow: function() {
var me = this;
if (me.wnd) {
me.wnd.close();
me.wnd = null;
}
if (me.closeOnClickOutside) {
me.mun(Ext.getDoc(), 'mousedown', me.doDocMouseDown, me);
}
}
});
To use just declare a button like:
{
xtype: 'windowbutton',
text: 'My button',
position: 'anchor',
anchor: 'bl',
windowConfig: {
title: 'My window',
resizable: false,
draggable: false,
layout: 'fit',
width: 300,
height: 205,
items: [{
xtype: 'panel',
html: 'this is my window',
border: false
}]
}
Any suggestions, criticisms, or general feedback will be appreciated.
Regards,
Joao Maia
Just thought I'd share a component that I came up with on my application. It's mainly a button that has a window config object attached, and some other configuration parameters. When the button is clicked it displays the window.
The window position can be determined by the window itself or can be anchored to the button. There are 8 possible anchor positions and they can be something like:
'tl' - displayed on the top of the button, aligned to the left
'bl' - displayed on the bottom of the button, aligned to the left
'lt' - displayed on the left of the button, aligned to the top
etc.
It still has some room for improvement (for example I'm not dealing with the situations where the anchored window goes outside the boundaries of the browser window) but anyway, fee free to use it, if you need something like this.
/**
* A generic button, that opens up a popup window
*/
Ext.define('Ext.ux.button.WindowButton', {
extend: 'Ext.button.Button',
alias: 'widget.windowbutton',
/**
* @cfg {Object} windowConfig The config object for the window that is to be created. If an xtype is not
* provided in this config object then a plain Ext.window.Window will be used
*/
windowConfig: null,
/**
* @cfg {Boolean} closeOnClickOutside Defines whether the window will be closed automatically when the user
* clicks outside of it. Ignored if the window is modal.
*/
closeOnClickOutside: true,
/**
* @cfg {Boolean} closeOnClickTwice Defines whether the window will be closed automatically when the user
* clicks again on the button.
*/
closeOnClickTwice: true,
/**
* @cfg {String} position Defines where the window will be displayed. Can be either 'anchor', 'window'.
* If 'anchor' the window will be anchored to the button (see anchor config), if 'window' the window will be
* placed on its x and y coordinates. If no x and y are defined it will be centered.
*/
position: 'window',
/**
* @cfg {String} anchor Defines where the window will be anchored in relation to the button. Can be one of the
* following: 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb'
*/
anchor: 'tl',
listeners: {
click: function() {
var me = this;
if (! me.isWindowOpen) {
me.openWindow();
}
else {
if (me.closeOnClickTwice) {
me.closeWindow();
}
}
}
},
/**
* @private
*/
initComponent: function() {
var me = this;
me.callParent();
Ext.apply(me, me.initialConfig);
if (me.windowConfig && me.windowConfig.modal) {
me.closeOnClickOutside = false;
}
},
/**
* @private
*/
doWindowDestroy: function(wnd, options) {
var me = this;
me.isWindowOpen = false;
},
/**
* @private
*/
doDocMouseDown: function(evt, element, options) {
var me = this;
if (me.wnd) {
if (!evt.within(me.wnd.el.dom) && !evt.within(me.el.dom)) {
me.closeWindow();
}
}
},
/**
* @private
*/
getWindowXY: function(wnd) {
var me = this;
var xy = [0,0];
if (me.position === 'window') {
xy = [wnd.x, wnd.y];
}
else if (me.position === 'anchor')
{
var box = me.getEl().getBox();
switch (me.anchor) {
case 'rb':
xy[0] = (box.x + box.width + 5);
xy[1] = ((box.y + box.height) - wnd.height);
break;
case 'rt':
xy[0] = (box.x + box.width + 5);
xy[1] = box.y;
break;
case 'lb':
xy[0] = (box.x - wnd.width - 5);
xy[1] = ((box.y + box.height) - wnd.height);
break;
case 'lt':
xy[0] = (box.x - wnd.width - 5);
xy[1] = box.y;
break;
case 'br':
xy[0] = ((box.x + box.width) - wnd.width);
xy[1] = (box.y + box.height + 5);
break;
case 'bl':
xy[0] = box.x;
xy[1] = (box.y + box.height + 5);
break;
case 'tr':
xy[0] = ((box.x + box.width) - wnd.width);
xy[1] = (box.y - wnd.height - 5);
break;
case 'tl':
default:
xy[0] = box.x;
xy[1] = (box.y - wnd.height - 5);
}
}
return xy;
},
/**
* Creates the window object and shows the window
*/
openWindow: function() {
var me = this;
if (me.windowConfig) {
var wnd = Ext.ComponentManager.create(me.windowConfig, 'window');
if (wnd) {
var xy = me.getWindowXY(wnd);
Ext.apply(wnd, {
x: xy[0],
y: xy[1],
animateTarget: me.getEl()
}, {});
wnd.on('destroy', me.doWindowDestroy, me);
wnd.show();
me.isWindowOpen = true;
me.wnd = wnd;
if (me.closeOnClickOutside) {
me.mon(Ext.getDoc(), 'mousedown', me.doDocMouseDown, me);
}
}
}
},
/**
* Closes the window and destroys it's object
*/
closeWindow: function() {
var me = this;
if (me.wnd) {
me.wnd.close();
me.wnd = null;
}
if (me.closeOnClickOutside) {
me.mun(Ext.getDoc(), 'mousedown', me.doDocMouseDown, me);
}
}
});
To use just declare a button like:
{
xtype: 'windowbutton',
text: 'My button',
position: 'anchor',
anchor: 'bl',
windowConfig: {
title: 'My window',
resizable: false,
draggable: false,
layout: 'fit',
width: 300,
height: 205,
items: [{
xtype: 'panel',
html: 'this is my window',
border: false
}]
}
Any suggestions, criticisms, or general feedback will be appreciated.
Regards,
Joao Maia