PDA

View Full Version : Fix for the new dialog autocreate



jbowman
30 Nov 2006, 8:47 PM
Hi Jack, I figured out my problems with the autoCreate feature of the dialog widget. If you update your version to this, it works fine.



YAHOO.ext.BasicDialog = function(el, config){
if(!getEl(el) && config && config.autoCreate){
var dh = YAHOO.ext.DomHelper;
if(typeof config.autoCreate == 'object'){
if(!config.autoCreate.id){
config.autoCreate.id = el;
}
el = dh.append(document.body,
config.autoCreate, true);
}else{
el = dh.append(document.body,
{tag: 'div', id: el}, true);
}
} else {
el = getEl(el);
}
this.el = el;
this.el.setDisplayed(true);
this.el.hide = this.hideAction;
this.id = this.el.id;



Also, I've found that using updatemanager and such to create dialog contents, I'm often having to call syncBodyHeight() before a show... so I added it to show. If for performance reasons (or other reasons) you feel you don't want to add this, could you let me know, and I'll figure out a solution for my code?



show : function(animateTarget){
if (this.fireEvent('beforeshow', this) === false)
return;

this.syncBodyHeight();
this.animateTarget = animateTarget || this.animateTarget;
if(!this.el.isVisible()){
this.beforeShow();
if(this.animateTarget){
this.animShow();
}else{
this.showEl();
}
}
return this;
},

jack.slocum
1 Dec 2006, 5:34 AM
Sorry, I ran into the same problem with BasicDialog and should have given you my fix:


this.el = getEl(el);
var dh = YAHOO.ext.DomHelper;
if(!this.el && config && config.autoCreate){
if(typeof config.autoCreate == 'object'){
if(!config.autoCreate.id){
config.autoCreate.id = el;
}
this.el = dh.append(document.body,
config.autoCreate, true);
}else{
this.el = dh.append(document.body,
{tag: 'div', id: el}, true);
}
}
this.el.setDisplayed(true);

As for the sync height when it's shown, I added:


show : function(animateTarget){
if (this.fireEvent('beforeshow', this) === false){
return;
}
if(this.syncHeightBeforeShow){
this.syncBodyHeight();
}
this.animateTarget = animateTarget || this.animateTarget;
if(!this.el.isVisible()){
this.beforeShow();
if(this.animateTarget){
this.animShow();
}else{
this.showEl();
}
}
return this;
}

If you want to set syncHeightBeforeShow globally, you can include:

YAHOO.ext.BasicDialog.prototype.syncHeightBeforeShow = true;

jbowman
1 Dec 2006, 6:41 AM
you code is always so clean :)

Another thought I've had with dialog, is perhaps the footer should be created, even if it's left empty, on dialog creation? The reason being is if you go through the docs it mentions that the properties header, body, and footer are in the object, and really, there is nothing suggested that it's only created when you add the first button. I ran into this myself, but admittedly it only took me a couple seconds to realize how and when the footer was being created. Just a thought.

Edit Is there going to be an svn update soon which will include the autocreate fix? Just browsed the source in my browser and noticed the old version is still there. I'd like to undo my changes and get synced back up with yui-ext current if possible :)

jack.slocum
1 Dec 2006, 8:31 AM
I haven't updated svn yet because I have some experimental code in my code base that needs cleanup.

I just did a commit and didn't include my experimental code. Let me know if you have problems building it.

jbowman
1 Dec 2006, 8:59 AM
I won't be able to get to that until tonight (us eastern time) so if anyone else wants to give it a go before me, please do.

I have another idea for the syncbodyheight that I'll play with when I get some time. I'm thinking you really only need to do that when you use update to change something. So if dilalog.body had an onUpdate event that called syncBodyHeight, you wouldn't need to include it in the show event. I'll try to work on that this weekend and let you know what I come up with. You got some paid donations stuff to work on with that tree :)

jbowman
1 Dec 2006, 4:01 PM
Hey Jack, you still had references in your BasicDialog to "el", rather than "this.el". "el" is only the object passed, which often time is a string, whereas the yui.ext.Element object you're trying to use is actually "this.el".

Here's a patch for the BasicDialog that fixes the problems caused by that, where I've gone through and turned the appropriate references to "el" to "this.el"



YAHOO.ext.BasicDialog = function(el, config){
this.el = getEl(el);
var dh = YAHOO.ext.DomHelper;
if(!this.el && config && config.autoCreate){
if(typeof config.autoCreate == 'object'){
if(!config.autoCreate.id){
config.autoCreate.id = el;
}
this.el = dh.append(document.body,
config.autoCreate, true);
}else{
this.el = dh.append(document.body,
{tag: 'div', id: el}, true);
}
}
this.el.setDisplayed(true);
this.el.hide = this.hideAction;
this.id = this.el.id;
this.el.addClass('ydlg');
this.shadowOffset = 3;
this.minHeight = 80;
this.minWidth = 200;
this.minButtonWidth = 75;
this.defaultButton = null;

YAHOO.ext.util.Config.apply(this, config);

this.proxy = this.el.createProxy('ydlg-proxy');
this.proxy.hide = this.hideAction;
this.proxy.setOpacity(.5);
this.proxy.hide();

if(config.width){
this.el.setWidth(config.width);
}
if(config.height){
this.el.setHeight(config.height);
}
this.size = this.el.getSize();
if(typeof config.x != 'undefined' && typeof config.y != 'undefined'){
this.xy = [config.x,config.y];
}else{
this.xy = this.el.getCenterXY(true);
}
// find the header, body and footer
var cn = this.el.dom.childNodes;
for(var i = 0, len = cn.length; i < len; i++) {
var node = cn[i];
if(node && node.nodeType == 1){
if(YAHOO.util.Dom.hasClass(node, 'ydlg-hd')){
this.header = getEl(node, true);
}else if(YAHOO.util.Dom.hasClass(node, 'ydlg-bd')){
this.body = getEl(node, true);
}else if(YAHOO.util.Dom.hasClass(node, 'ydlg-ft')){
/**
* The footer element
* @type YAHOO.ext.Element
*/
this.footer = getEl(node, true);
}
}
}

if(!this.header){
/**
* The header element
* @type YAHOO.ext.Element
*/
this.header = dh.append(this.el.dom, {tag: 'div', cls:'ydlg-hd'}, true);
}
if(this.title){
this.header.update(this.title);
}
if(!this.body){
/**
* The body element
* @type YAHOO.ext.Element
*/
this.body = dh.append(this.el.dom, {tag: 'div', cls:'ydlg-bd'}, true);
}
// wrap the header for special rendering
var hl = dh.insertBefore(this.header.dom, {tag: 'div', cls:'ydlg-hd-left'});
var hr = dh.append(hl, {tag: 'div', cls:'ydlg-hd-right'});
hr.appendChild(this.header.dom);

// wrap the body and footer for special rendering
this.bwrap = dh.insertBefore(this.body.dom, {tag: 'div', cls:'ydlg-dlg-body'}, true);
this.bwrap.dom.appendChild(this.body.dom);
if(this.footer) this.bwrap.dom.appendChild(this.footer.dom);

if(this.autoScroll !== false && !this.autoTabs){
this.body.setStyle('overflow', 'auto');
}
if(this.closable !== false){
this.el.addClass('ydlg-closable');
this.close = dh.append(this.el.dom, {tag: 'div', cls:'ydlg-close'}, true);
this.close.mon('click', function(){
this.hide();
}, this, true);
}
if(this.resizable !== false){
this.el.addClass('ydlg-resizable');
this.resizer = new YAHOO.ext.Resizable(this.el, {
minWidth: this.minWidth || 80,
minHeight:this.minHeight || 80,
handles: 'all',
pinned: true
});
this.resizer.on('beforeresize', this.beforeResize, this, true);
this.resizer.on('resize', this.onResize, this, true);
}
if(this.draggable !== false){
this.el.addClass('ydlg-draggable');
if (!this.proxyDrag) {
var dd = new YAHOO.util.DD(this.el.dom.id, 'WindowDrag');
}
else {
var dd = new YAHOO.util.DDProxy(this.el.dom.id, 'WindowDrag', {dragElId: this.proxy.id});
}
dd.setHandleElId(this.header.id);
dd.endDrag = this.endMove.createDelegate(this);
dd.startDrag = this.startMove.createDelegate(this);
dd.onDrag = this.onDrag.createDelegate(this);
this.dd = dd;
}
if(this.modal){
this.mask = dh.append(document.body, {tag: 'div', cls:'ydlg-mask'}, true);
this.mask.enableDisplayMode('block');
this.mask.hide();
}
if(this.shadow){
this.shadow = this.el.createProxy({tag: 'div', cls:'ydlg-shadow'});
this.shadow.setOpacity(.3);
this.shadow.setVisibilityMode(YAHOO.ext.Element.VISIBILITY);
this.shadow.setDisplayed('block');
this.shadow.hide = this.hideAction;
this.shadow.hide();
}else{
this.shadowOffset = 0;
}
if(this.shim){
this.shim = this.el.createShim();
this.shim.hide = this.hideAction;
this.shim.hide();
}
if(this.autoTabs){
var tabEls = YAHOO.util.Dom.getElementsByClassName('ydlg-tab', this.tabTag || 'div', this.el.dom);
if(tabEls.length > 0){
this.body.addClass(this.tabPosition == 'bottom' ? 'ytabs-bottom' : 'ytabs-top');
this.tabs = new YAHOO.ext.TabPanel(this.body.dom, this.tabPosition == 'bottom');
for(var i = 0, len = tabEls.length; i < len; i++) {
var tabEl = tabEls[i];
this.tabs.addTab(YAHOO.util.Dom.generateId(tabEl), tabEl.title);
tabEl.title = '';
}
this.tabs.activate(tabEls[0].id);
}
}
this.syncBodyHeight();
this.events = {
/**
* @event keydown
* Fires when a key is pressed
* @param {YAHOO.ext.BasicDialog} this
* @param {YAHOO.ext.EventObject} e
*/
'keydown' : new YAHOO.util.CustomEvent('keydown'),
/**
* @event move
* Fires when this dialog is moved by the user.
* @param {YAHOO.ext.BasicDialog} this
* @param {Number} x The new page X
* @param {Number} y The new page Y
*/
'move' : new YAHOO.util.CustomEvent('move'),
/**
* @event resize
* Fires when this dialog is resized by the user.
* @param {YAHOO.ext.BasicDialog} this
* @param {Number} width The new width
* @param {Number} height The new height
*/
'resize' : new YAHOO.util.CustomEvent('resize'),
/**
* @event beforehide
* Fires before this dialog is hidden.
* @param {YAHOO.ext.BasicDialog} this
*/
'beforehide' : new YAHOO.util.CustomEvent('beforehide'),
/**
* @event hide
* Fires when this dialog is hidden.
* @param {YAHOO.ext.BasicDialog} this
*/
'hide' : new YAHOO.util.CustomEvent('hide'),
/**
* @event beforeshow
* Fires before this dialog is shown.
* @param {YAHOO.ext.BasicDialog} this
*/
'beforeshow' : new YAHOO.util.CustomEvent('beforeshow'),
/**
* @event show
* Fires when this dialog is shown.
* @param {YAHOO.ext.BasicDialog} this
*/
'show' : new YAHOO.util.CustomEvent('show')
};
this.el.mon('keydown', this.onKeyDown, this, true);
this.el.mon("mousedown", this.toFront, this, true);

YAHOO.ext.EventManager.onWindowResize(this.adjustViewport, this, true);
this.el.hide();
YAHOO.ext.DialogManager.register(this);
};

jack.slocum
1 Dec 2006, 4:48 PM
Check the SVN, I did a little different. :)

jbowman
1 Dec 2006, 4:51 PM
:)

Just out of curiosity, is there a reason you want to use two references to the same object throughout that?

jack.slocum
2 Dec 2006, 4:56 AM
It's always better to create a local variable if you will be using it more than once or twice.