gfraser
01-04-2007, 10:28 AM
I recently had a developer ask for a re-usable custom dialog where they could give it some html and a set of buttons plus a few other params very easily and get a dialog. Although it's really easy to do this sort of thing in yui-ext, it was obvious that there are loads of places where a custom dialog would be needed so I decided to throw together a very re-usable custom dialog class (literally - my wife was shouting telling me dinner would go in the bin if I didn't stop immediately so excuse the grim code)...
First, dump this in to a js file:
var CustomDlg = function(config) {
// make sure config object exists
if (!config) config = {};
// private properties
var dialog;
var center, centerEl;
var x, buttons, b, btn;
// define template for content html
var template = new YAHOO.ext.Template(
'<div class="yunselectable">{html}</div>'
);
template.compile(); // probably overkill?
// create the dialog
dialog = new YAHOO.ext.LayoutDialog(YAHOO.util.Dom.generateId(),{
autoCreate: true,
closable: false,
syncHeightBeforeShow: true,
modal: true,
width: config.width || 300,
height: config.height || 220,
fixedcenter: true,
shadow: true,
resizable: false,
proxyDrag: true,
title: config.title || 'Adaptavist.com',
center: {autoScroll:false}
});
// default button handlers
if (!config.fn) config.fn = dialog.hide;
if (!config.obj) config.obj = dialog;
// add buttons
if (config.buttons) {
buttons = config.buttons; // shortcut to buttons array
x = buttons.length;
while (-1<--x) {
b = buttons[x];
btn = dialog.addButton(b.caption || '?', b.fn || config.fn, b.obj || config.obj);
if (buttons[x].isCancel) {
dialog.addKeyListener(27, (b.fn || config.fn).createDelegate(b.obj || config.obj, [btn]), b.obj || config.obj);
}
if (buttons[x].isDefault) {
dialog.setDefaultButton(btn); // set button as default
}
}
}
// set up content panel of dialog
var layout = dialog.getLayout();
layout.beginUpdate();
center = layout.add('center', new YAHOO.ext.ContentPanel(YAHOO.util.Dom.generateId(), {
autoCreate: true,
fitToFrame: true,
autoScroll: false
}));
layout.endUpdate();
centerEl = center.getEl();
// set panel content
if (!config.html) config.html = 'Adding some content would be useful ;)';
template.overwrite(centerEl.dom, config);
// add show mentod
this.show = function(pEl) {
dialog.show(pEl);
}
// add hide method
this.hide = function() {
dialog.hide();
}
return this;
}
Yeah, I know that should be using prototype and stuff, but dinner won ;)
Then in your HTML, put a named span in like this:
<span id="show-custdlg-button">let's get fishy...</span>
And then this code in script tags somewhere:
// example of a custom dialog
var custDlgExample = {
// click handler for buttons in the dialog
onDlgBtnClick: function(pBtn) {
if (!pBtn) return; // sometimes get "undefined" when dialog closes due to keyboard input (enter or escape)
// always hide dlg first..
custDlgExample.dlg.hide();
// pBtn.text is the caption of the clicked button
alert.defer(500,undefined,['The "'+pBtn.text+'" button was clicked :)']);
// anyone know how to do this after the animation finishes rather than using a timeout?
},
// a custom handler for the "No" button
notfish: function(pBtn) {
if (!pBtn) return;
// always hide dlg first..
custDlgExample.dlg.hide();
alert('I am not a fish!! I am the new Number 6!');
},
// "show custom dialog" button click handler
onClick: function(pBtn) {
if (!custDlgExample.dlg) {
// create the dlg
var dlgConfig = {
width:300,
height:200,
title:'Kipper',
fn:custDlgExample.onDlgBtnClick,
obj:custDlgExample,
buttons:[
{caption:'Yes' , isDefault:true },
{caption:'No' , fn:custDlgExample.notfish},
{caption:'Cancel', isCancel:true }
],
html: 'Are you a fish?'
}
// create a CustomDlg instance
custDlgExample.dlg = new CustomDlg(dlgConfig);
}
// show the dialog
custDlgExample.dlg.show(pBtn.getEl());
},
init: function() {
// display the "show dialog" button
new YAHOO.ext.Button('show-custdlg-button', {text: "Show Custom Dialog",handler: this.onClick});
}
}
YAHOO.ext.EventManager.onDocumentReady(custDlgExample.init, custDlgExample, true);
(Obviously you'll need to include the js file, the yui and yui-ext libraries and the usual css)
All the config options are optional and defaults will be used. Any comments welcome - I'd love to know how to clean up the code as I've not coded for almost 2 years and my coding skills are somewhat rusty!
First, dump this in to a js file:
var CustomDlg = function(config) {
// make sure config object exists
if (!config) config = {};
// private properties
var dialog;
var center, centerEl;
var x, buttons, b, btn;
// define template for content html
var template = new YAHOO.ext.Template(
'<div class="yunselectable">{html}</div>'
);
template.compile(); // probably overkill?
// create the dialog
dialog = new YAHOO.ext.LayoutDialog(YAHOO.util.Dom.generateId(),{
autoCreate: true,
closable: false,
syncHeightBeforeShow: true,
modal: true,
width: config.width || 300,
height: config.height || 220,
fixedcenter: true,
shadow: true,
resizable: false,
proxyDrag: true,
title: config.title || 'Adaptavist.com',
center: {autoScroll:false}
});
// default button handlers
if (!config.fn) config.fn = dialog.hide;
if (!config.obj) config.obj = dialog;
// add buttons
if (config.buttons) {
buttons = config.buttons; // shortcut to buttons array
x = buttons.length;
while (-1<--x) {
b = buttons[x];
btn = dialog.addButton(b.caption || '?', b.fn || config.fn, b.obj || config.obj);
if (buttons[x].isCancel) {
dialog.addKeyListener(27, (b.fn || config.fn).createDelegate(b.obj || config.obj, [btn]), b.obj || config.obj);
}
if (buttons[x].isDefault) {
dialog.setDefaultButton(btn); // set button as default
}
}
}
// set up content panel of dialog
var layout = dialog.getLayout();
layout.beginUpdate();
center = layout.add('center', new YAHOO.ext.ContentPanel(YAHOO.util.Dom.generateId(), {
autoCreate: true,
fitToFrame: true,
autoScroll: false
}));
layout.endUpdate();
centerEl = center.getEl();
// set panel content
if (!config.html) config.html = 'Adding some content would be useful ;)';
template.overwrite(centerEl.dom, config);
// add show mentod
this.show = function(pEl) {
dialog.show(pEl);
}
// add hide method
this.hide = function() {
dialog.hide();
}
return this;
}
Yeah, I know that should be using prototype and stuff, but dinner won ;)
Then in your HTML, put a named span in like this:
<span id="show-custdlg-button">let's get fishy...</span>
And then this code in script tags somewhere:
// example of a custom dialog
var custDlgExample = {
// click handler for buttons in the dialog
onDlgBtnClick: function(pBtn) {
if (!pBtn) return; // sometimes get "undefined" when dialog closes due to keyboard input (enter or escape)
// always hide dlg first..
custDlgExample.dlg.hide();
// pBtn.text is the caption of the clicked button
alert.defer(500,undefined,['The "'+pBtn.text+'" button was clicked :)']);
// anyone know how to do this after the animation finishes rather than using a timeout?
},
// a custom handler for the "No" button
notfish: function(pBtn) {
if (!pBtn) return;
// always hide dlg first..
custDlgExample.dlg.hide();
alert('I am not a fish!! I am the new Number 6!');
},
// "show custom dialog" button click handler
onClick: function(pBtn) {
if (!custDlgExample.dlg) {
// create the dlg
var dlgConfig = {
width:300,
height:200,
title:'Kipper',
fn:custDlgExample.onDlgBtnClick,
obj:custDlgExample,
buttons:[
{caption:'Yes' , isDefault:true },
{caption:'No' , fn:custDlgExample.notfish},
{caption:'Cancel', isCancel:true }
],
html: 'Are you a fish?'
}
// create a CustomDlg instance
custDlgExample.dlg = new CustomDlg(dlgConfig);
}
// show the dialog
custDlgExample.dlg.show(pBtn.getEl());
},
init: function() {
// display the "show dialog" button
new YAHOO.ext.Button('show-custdlg-button', {text: "Show Custom Dialog",handler: this.onClick});
}
}
YAHOO.ext.EventManager.onDocumentReady(custDlgExample.init, custDlgExample, true);
(Obviously you'll need to include the js file, the yui and yui-ext libraries and the usual css)
All the config options are optional and defaults will be used. Any comments welcome - I'd love to know how to clean up the code as I've not coded for almost 2 years and my coding skills are somewhat rusty!