PDA

View Full Version : New in SVN: MessageBox class



jack.slocum
31 Dec 2006, 7:38 AM
Making simple BasicDialogs is too verbose, enter MessageBox:

http://yui-ext.com/playpen/yui-ext.0.40/examples/dialog/msg-box.html

Any feedback appreciated.

moraes
31 Dec 2006, 8:05 AM
Here is a feedback: wow! :-D

This is something I needed and I would try my own solution soon. No more! They look cool as always and seem very easy to setup. I will start to use some right now. Stupendous.

jack.slocum
31 Dec 2006, 8:09 AM
The discussion we had last week when you said you needed SimpleDialog made me realize there was a need for something similar. Only, why not make it even easier and throw in a progress/loading dialog too. Also, all MessageBox calls share the same dialog instance instead of creating a new one. :)

So thank you for pointing out something that was needed and missing!

jon.whitcraft
31 Dec 2006, 8:20 AM
Jack,

This is great. As i was working last night i started developing one of these but now i guess i can stop as it's already done!

Thanks a lot!!

JeffHowden
1 Jan 2007, 12:49 AM
Here's some small changes to disable the mapping of the ESC key to closing the dialog if the dialog is marked as not closable.

To accomplish this, I changed line 69 from using the BasicDialog addKeyListener() method to using the KeyMap class and storing that in an ESC property of the dialog.


dlg.ESC = new Ext.KeyMap(dlg, { key: 27, fn: dlg.hide, scope: dlg});

Then, in the show() method, I added some logic to check whether the dialog is closable or not and enable or disable the ESC key mapping accordingly:


if(opt.closable == false) d.ESC.disable();
else if(!d.ESC.isEnabled()) d.ESC.enable();

Here's the whole JS file:


/*
* yui-ext 0.40
* Copyright(c) 2006, Jack Slocum.
*/

YAHOO.ext.MessageBox = function(){
var dlg, opt, mask;
var bodyEl, msgEl, textboxEl, textareaEl, progressEl, pp;
var buttons, activeTextEl, bwidth;

var handleButton = function(button){
if(typeof opt.fn == 'function'){
if(opt.fn.call(opt.scope||window, button, activeTextEl.dom.value) !== false){
dlg.hide();
}
}else{
dlg.hide();
}
};
var updateButtons = function(b){
var width = 0;
if(!b){
buttons['ok'].hide();
buttons['cancel'].hide();
buttons['yes'].hide();
buttons['no'].hide();
return width;
}
for(var k in buttons){
if(typeof buttons[k] != 'function'){
if(b[k]){
buttons[k].show();
buttons[k].setText(typeof b[k] == 'string' ? b[k] : YAHOO.ext.MessageBox.buttonText[k]);
width += buttons[k].el.getWidth()+15;
}else{
buttons[k].hide();
}
}
}
return width;
};

return {
getDialog : function(){
if(!dlg){
dlg = new YAHOO.ext.BasicDialog('mb-dlg', {
autoCreate : true,
shadow: true,
draggable: true,
resizable:false,
constraintoviewport:true,
fixedcenter:true,
shim:true,
modal: true,
width:400, height:100,
buttonAlign:'center',
closeClick : function(){
if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
handleButton('no');
}else{
handleButton('cancel');
}
}
});
dlg.closeClick = function(){
alert('wtf');
};
mask = dlg.mask;
dlg.ESC = new Ext.KeyMap(dlg, { key: 27, fn: dlg.hide, scope: dlg});
buttons = {};
buttons['ok'] = dlg.addButton(this.buttonText['ok'], handleButton.createCallback('ok'));
buttons['yes'] = dlg.addButton(this.buttonText['yes'], handleButton.createCallback('yes'));
buttons['no'] = dlg.addButton(this.buttonText['no'], handleButton.createCallback('no'));
buttons['cancel'] = dlg.addButton(this.buttonText['cancel'], handleButton.createCallback('cancel'));
bodyEl = dlg.body.createChild({
tag:'div',
html:'<span class="ext-mb-text" style="background-color: lime;"></span>
<input type="text" class="ext-mb-input"><textarea class="ext-mb-textarea"></textarea><div class="ext-mb-progress-wrap"><div class="ext-mb-progress"><div class="ext-mb-progress-bar"> </div></div></div>'
});
msgEl = bodyEl.dom.firstChild;
textboxEl = getEl(bodyEl.dom.childNodes[2]);
textboxEl.enableDisplayMode();
textboxEl.addKeyListener([10,13], function(){
if(dlg.isVisible() && opt && opt.buttons){
if(opt.buttons.ok){
handleButton('ok');
}else if(opt.buttons.yes){
handleButton('yes');
}
}
});
textareaEl = getEl(bodyEl.dom.childNodes[3]);
textareaEl.enableDisplayMode();
progressEl = getEl(bodyEl.dom.childNodes[4]);
progressEl.enableDisplayMode();
pp = getEl(progressEl.dom.firstChild.firstChild);
}
return dlg;
},

updateText : function(text){
if(!dlg.isVisible() && !opt.width){
dlg.resizeTo(this.maxWidth, 100); // resize first so content is never clipped from previous shows
}
msgEl.innerHTML = text;
var w = Math.max(Math.min(opt.width || msgEl.offsetWidth, this.maxWidth),
Math.max(opt.minWidth || this.minWidth, bwidth));
if(opt.prompt){
activeTextEl.setWidth(w);
}
dlg.setContentSize(w, bodyEl.getHeight());
},

updateProgress : function(value, text){
if(text){
this.updateText(text);
}
pp.setWidth(value*progressEl.dom.firstChild.offsetWidth);
},

hide : function(){
if(dlg){
dlg.hide();
}
},

show : function(options){
var d = this.getDialog();
opt = options;
d.setTitle(opt.title || ' ');
d.close.setDisplayed(opt.closable !== false);
if(opt.closable == false) d.ESC.disable();
else if(!d.ESC.isEnabled()) d.ESC.enable();
activeTextEl = textboxEl;
opt.prompt = opt.prompt || (opt.multiline ? true : false)
if(opt.prompt){
if(opt.multiline){
textboxEl.hide();
textareaEl.show();
textareaEl.setHeight(typeof opt.multiline == 'number' ?
opt.multiline : this.defaultTextHeight);
activeTextEl = textareaEl;
}else{
textboxEl.show();
textareaEl.hide();
}
}else{
textboxEl.hide();
textareaEl.hide();
}
progressEl.setDisplayed(opt.progress === true);
this.updateProgress(0);
activeTextEl.dom.value = opt.value || '';
if(opt.prompt){
dlg.setDefaultButton(activeTextEl);
}else{
var bs = opt.buttons;
var db = null;
if(bs && bs.ok){
db = buttons['ok'];
}else if(bs && bs.yes){
db = buttons['yes'];
}
dlg.setDefaultButton(db);
}
bwidth = updateButtons(opt.buttons);
this.updateText(opt.msg);
d.modal = opt.modal !== false;
d.mask = opt.modal !== false ? mask : false;
d.animateTarget = null;
d.show(options.animEl);
},

progress : function(title, msg){
this.show({
title : title,
msg : msg,
buttons: false,
progress:true,
closable:false
});
},

alert : function(title, msg, fn, scope){
this.show({
title : title,
msg : msg,
buttons: this.OK,
fn: fn,
scope : scope
});
},

confirm : function(title, msg, fn, scope){
this.show({
title : title,
msg : msg,
buttons: this.YESNO,
fn: fn,
scope : scope
});
},

prompt : function(title, msg, fn, scope, multiline){
this.show({
title : title,
msg : msg,
buttons: this.OKCANCEL,
fn: fn,
minWidth:250,
scope : scope,
prompt:true,
multiline: multiline
});
},

OK : {ok:true},
YESNO : {yes:true, no:true},
OKCANCEL : {ok:true, cancel:true},
YESNOCANCEL : {yes:true, no:true, cancel:true},

defaultTextHeight:75,
maxWidth : 500,
minWidth : 100,
buttonText : {
ok : 'OK',
cancel : 'Cancel',
yes : 'Yes',
no : 'No'
}
};
}();

YAHOO.ext.Msg = YAHOO.ext.MessageBox;

JeffHowden
1 Jan 2007, 1:39 AM
I also think that a messagebox should support an optional icon. I'm working on those adjustments now, but not entirely sure what direction makes the most sense to go with that.

MrKurt
1 Jan 2007, 1:45 PM
Jeff - generally if you submit changes as a diff, it makes it much easier to try them out and commit them.

JeffHowden
1 Jan 2007, 2:46 PM
I'd be happy to but I'm not entirely sure how to "submit changes as a diff".

MrKurt
1 Jan 2007, 7:43 PM
Doh, meant to type more.

If you're on Windows, just install Tortoise SVN and check the code out from subversion. Make your changes, right click on the folder and select "create diff". This gives you a text file other people can apply to their checked out copies.

It's conceptually the same on any other platform, I'm just not entirely sure how to do it using only a command line client.

JeffHowden
1 Jan 2007, 7:56 PM
Index: MessageBox.js
===================================================================
--- MessageBox.js (revision 116)
+++ MessageBox.js (working copy)
@@ -1,3 +1,8 @@
+/*
+ * yui-ext 0.40
+ * Copyright(c) 2006, Jack Slocum.
+ */
+
YAHOO.ext.MessageBox = function(){
var dlg, opt, mask;
var bodyEl, msgEl, textboxEl, textareaEl, progressEl, pp;
@@ -61,7 +66,7 @@
alert('wtf');
};
mask = dlg.mask;
- dlg.addKeyListener(27, dlg.hide, dlg);
+ dlg.ESC = new Ext.KeyMap(dlg, { key: 27, fn: dlg.hide, scope: dlg});
buttons = {};
buttons['ok'] = dlg.addButton(this.buttonText['ok'], handleButton.createCallback('ok'));
buttons['yes'] = dlg.addButton(this.buttonText['yes'], handleButton.createCallback('yes'));
@@ -69,7 +74,7 @@
buttons['cancel'] = dlg.addButton(this.buttonText['cancel'], handleButton.createCallback('cancel'));
bodyEl = dlg.body.createChild({
tag:'div',
- html:'<span class="ext-mb-text"></span>
<input type="text" class="ext-mb-input"><textarea class="ext-mb-textarea"></textarea><div class="ext-mb-progress-wrap"><div class="ext-mb-progress"><div class="ext-mb-progress-bar"> </div></div></div>'
+ html:'<span class="ext-mb-text"></span>
<input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea><div class="ext-mb-progress-wrap"><div class="ext-mb-progress"><div class="ext-mb-progress-bar"> </div></div></div>'
});
msgEl = bodyEl.dom.firstChild;
textboxEl = getEl(bodyEl.dom.childNodes[2]);
@@ -112,12 +117,8 @@
pp.setWidth(value*progressEl.dom.firstChild.offsetWidth);
},

- isVisible : function(){
- return dlg && dlg.isVisible();
- },
-
hide : function(){
- if(this.isVisible()){
+ if(dlg){
dlg.hide();
}
},
@@ -127,6 +128,8 @@
opt = options;
d.setTitle(opt.title || ' ');
d.close.setDisplayed(opt.closable !== false);
+ if(opt.closable == false) d.ESC.disable();
+ else if(!d.ESC.isEnabled()) d.ESC.enable();
activeTextEl = textboxEl;
opt.prompt = opt.prompt || (opt.multiline ? true : false)
if(opt.prompt){
@@ -227,4 +230,4 @@
};
}();

-YAHOO.ext.Msg = YAHOO.ext.MessageBox;
\ No newline at end of file
+YAHOO.ext.Msg = YAHOO.ext.MessageBox;

sjivan
1 Jan 2007, 11:40 PM
Looks great but I think the progressbar image could be better. Its okay, but not up to par with the high yui-ext standards. Looks a little blurred presently.

Also is it possible to have the bottom right corner of the shadow to be slightly rounded as well?

simon_price
2 Jan 2007, 4:14 AM
Works fine on Mac Safari 2.0.4. Mostly works fine on Mac Firefox 2.0.0.1 too, but the prompt dialogs lose the caret immediately after the dialog displays and it never comes back (although typing in text does work). I suspect this may be a FF bug but just thought I'd let you know.

manugoel2003
2 Jan 2007, 5:34 AM
Amazing stuff man!!! ..... Just when I start to think "how much better can this get", you throw in something interesting


Appreciated

jack.slocum
2 Jan 2007, 6:16 AM
Thanks for the feedback guys. After I am done with my GridView rewrite (from scratch!) I will jump back on the MessageBox.