PDA

View Full Version : Very basic custom dialog



gfraser
4 Jan 2007, 7: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!

tryanDLS
4 Jan 2007, 9:24 AM
The .40 dev code has a new object called MesageBox which may accomplish a lot of what you're trying to do. It's still considered 'dev', but there's a page of examples here
http://yui-ext.com/playpen/yui-ext.0.40/examples/dialog/msg-box.html

jay@moduscreate.com
4 Jan 2007, 9:43 AM
( . ) ( . )

!!!!

gfraser
4 Jan 2007, 9:45 AM
Those message boxes are awesome! Will you be making a version that has customisible buttons?

tryanDLS
4 Jan 2007, 10:02 AM
Not sure how far Jack's gonna take it for this release, but I would imagine that it will be pretty easy to extend :)

jack.slocum
5 Jan 2007, 10:04 AM
There is a buttons config option you pass in. It accepts either true to show the button or a string to show the button and set the buttons text. There are 4 available buttons (ok, cancel, yes, no). You can globally modify the button text on MessageBox class.

e.g. using the power "show()" method:


Ext.MessageBox.show({
title: 'My Dialog',
msg: 'Here's my message',
buttons: {
ok:true, cancel: 'Close', yes: 'Si Senor'
}
});

mdissel
5 Jan 2007, 11:03 AM
Really nice!

feature request:
- add icons for the various dialogtypes (warning, information, error, etc.) like in Windows.

Thanks

Marco

jay@moduscreate.com
5 Jan 2007, 12:50 PM
^^^ Please? :P

jack.slocum
6 Jan 2007, 6:35 AM
I just added in something to allow this. A "cls" show option that will apply a particular css class to the dialog. Using the css class, one could apply padding and a css background image to ext-mb-text and boom, the icon is there. I will whip up some predefined classes.

gfraser
8 Jan 2007, 3:37 PM
Awesome! Can't wait for the stable .4 release :D