About Me

Curriculum Vitae

A brief list of my current skill set

Bloggybits

And the Fastworks.js framework is Born!
Wednesday, 22nd August 2012, 16:23

Well I'm excited, even if you aren't

Libxmljs Update on CentOS 3.8 throws an SELinux Wobbley Fit
Monday, 20th August 2012, 15:40

The right way to fix this sort of issue

TV Land Doesn't Understand Technology
Friday, 17th August 2012, 17:09

Or maybe it does and thinks we don't?

Yet More Benchmarking - Function Chains vs Object Chains
Wednesday, 15th August 2012, 13:34

Working towards a faster Node.js framework

More Benchmarking in Node.js and V8
Tuesday, 14th August 2012, 12:19

Working out the fastest way to route

MinnaHTML.js Benchmarking for Speed in Node.js
Monday, 13th August 2012, 17:55

Don't believe it, test it

Playing Around With HTML5's Canvas
Friday, 10th August 2012, 16:19

Speccy loading screens in a browser!

Scripting in Node.js AKA How to Watch for Olympic Tickets Using a Script
Tuesday, 7th August 2012, 23:37

Let Node refresh the webpage so you don't have to!

A Javascript Confirm/Alert Replacement jQuery Plugin
Monday, 6th August 2012, 23:06

Much prettier than the horrible alert and confirm dialogs

A Few Node.js Essential Modules
Friday, 3rd August 2012, 14:40

As essential as they can be anyway

Retro Coding Corner: Loading ZX Spectrum Snapshots off Microdrives - Part 2
Tuesday, 31st July 2012, 18:20

It's like juggling 8 balls with one hand behind your back

One Layout To Rule Them All
Monday, 30th July 2012, 16:03

Designing a layout to fit every screen

Retro Coding Corner: Loading ZX Spectrum Snapshots off Microdrives - Part 1
Thursday, 26th July 2012, 16:57

From emulation to super fast tape

Upgrading Libxml2 on CentOS 5.8 fixes Libxmljs
Wednesday, 25th July 2012, 11:33

Fixes strange compile errors and everyfin

Installing Node.js 0.8.x under CentOS 5.8
Tuesday, 24th July 2012, 14:13

It's just an upgrade of Python away

Projects and Sillyness

MAME Cabinet Diary

How I built my own arcade cabinet

Loading Screen Simulator

I don't miss the ZX Spectrum, I still use it!

The Little Guy Chat Room

It's a Pitfall inspired chat room

GPMad MP3

A fully featured MP3 player what I wrote

GP Space Invaders

My first little emulator

GP32 Development Page

Some info and links about this cute little handheld

Disney Nasties

Uncensored images, you must be 18 to view them

Diary of a Hamster

Learn about how hamsters think, first hand

Utilities

Time Calculator

A simple little online utility for working out how many hours to bill a client

A Few Links

A Javascript Confirm/Alert Replacement jQuery Plugin
Monday, 6th August 2012, 23:06

No messing, straight to the point! The built in Javascript functions alert() and confirm() are useful, but ugly. So I decided to knock up a quick almost-drop-in-replacement jQuery plugin that does the same job. And then extend it a bit to add some more useful features, like configuring the title, number of buttons, etc.

Since this is really basic stuff, I'll just post the code and a quick guide on how to use it afterwards. If you want a DEMO, yes I put that in caps to attract the wandering eye, put any old thing in the Username box in the comments section and no password, it will pop up the dialog for you to see without having to submit anything.

First up, this is the jQuery plugin itself:

// Custom modal dialog box jQuery plugin
(function( $ ){
var ModalDialog = function(args)
{
var self = this;

if (args.template == "ok")
{
this.title = "Information";
this.message = "Click the Okay button to continue";
this.buttons = [ { text: "Okay", value: true, class: "default" } ];
}
else
{
this.title = "Are you sure?";
this.message = "Do you really want to do this?";
this.buttons = [ { text: "Okay", value: true }, { text: "Cancel", value: false, class: "default" } ];
}
this.modalclass = "modaldialog";
this.blackoutclass = "blackout";
this.buttonclass = "buttons";
this.body = $("body");
this.window = $(window);
this.fadespeed = 300;
this.inoffsetx = -200;
this.inoffsety = 0;
this.outoffsetx = 200;
this.outoffsety = 0;
this.opacity = 0.7;

for (key in args)
this[key] = args[key];

this.createModal();
this.showModal();
};

ModalDialog.prototype.createModal = function()
{
this.hdTitle = $("<h4>" + this.title + "</h4>");
this.paMesage = $("<p>" + this.message + "</p>");
this.dvButtons = $("<div></div>");

this.arrButtons = new Array();
for (var u = 0; u < this.buttons.length; u++)
{
var btButton = $("<button value=\"" + this.buttons[u].value + "\" type=\"button\">" + this.buttons[u].text + "</button>");
if (this.buttons[u].class)
btButton.addClass(this.buttons[u].class);
this.arrButtons.push(btButton);
if (u > 0)
this.dvButtons.append("&nbsp;");
this.dvButtons.append(btButton);
}

this.dvModal = $("<div></div>");
this.dvModal.append(this.hdTitle, this.paMesage, this.dvButtons);
this.dvBlackout = $("<div></div>");

if (this.buttonclass)
this.dvButtons.addClass(this.buttonclass);
if (this.modalclass)
this.dvModal.addClass(this.modalclass);
if (this.blackoutclass)
this.dvBlackout.addClass(this.blackoutclass);

this.body.append(this.dvBlackout);
this.body.append(this.dvModal);

if (this.height)
this.dvModal.height(this.height);
if (this.width)
this.dvModal.width(this.width);
};

ModalDialog.prototype.showModal = function()
{
var self = this;

this.dvBlackout.fadeTo(this.fadespeed, this.opacity);
this.dvModal.fadeTo(this.fadespeed, 1);

this.centerModal();

// Better than using offset() because that doesn't account for padding/borders/etc
var top = parseInt(this.dvModal.css("top"), 10);
var left = parseInt(this.dvModal.css("left"), 10);

this.dvModal.css("top", (top + this.inoffsety) + "px");
this.dvModal.css("left", (left + this.inoffsetx) + "px");

this.dvModal.stop();
this.dvModal.animate({ opacity: 1, top: top, left: left }, this.fadespeed, function() {
for (var u = 0; u < self.arrButtons.length; u++)
self.arrButtons[u].click(function() {
var value = $(this).val();

switch (value.toLowerCase())
{
case "true":
value = true;
break;
case "false":
value = false;
break;
}

if (self.callback)
self.callback(value);
self.hideModal();
});
});

this.window.scroll(function() {
self.centerModal();
});
this.window.resize(function() {
self.centerModal();
});
};

ModalDialog.prototype.centerModal = function()
{
var offset = { left: 0, top: this.window.scrollTop() };

this.dvBlackout.offset(offset);
this.dvBlackout.width(this.window.outerWidth());
this.dvBlackout.height(this.window.outerHeight());

offset.left += Math.floor((this.window.width() - parseInt(this.body.css("marginLeft"), 10) - parseInt(this.body.css("marginRight"), 10)- this.dvModal.outerWidth()) / 2);
offset.top = Math.floor((this.window.height() - parseInt(this.body.css("marginTop"), 10) - parseInt(this.body.css("marginBottom"), 10) - this.dvModal.outerHeight()) / 2) + this.window.scrollTop();

this.dvModal.offset(offset);
};

ModalDialog.prototype.hideModal = function()
{
var self = this;

this.dvBlackout.fadeOut(this.fadespeed, function() {
self.dvBlackout.remove();
});

var top = parseInt(this.dvModal.css("top"), 10) + this.outoffsety;
var left = parseInt(this.dvModal.css("left"), 10) + this.outoffsetx;

this.dvModal.animate({ opacity: 0, top: top, left: left }, this.fadespeed, function() {
self.dvModal.remove();
delete self;
});
};

$.modaldialog = function(args) {
new ModalDialog(args);
};
})( jQuery );

You'll need to make yourself some CSS to go with it. This is in LESS format, and obviously is entirely based on a predefined variable @colour-background. You should be able to work out what needs changing even if you don't know how LESS works:

div.modaldialog
{
position: absolute;
top: 50px;
left: 50px;
width: 295px;
overflow: auto;
z-index: 1000;
display: none;
text-align: left;

padding: 10px;

background-color: @colour-background;
color: @colour-body;
border: 2px solid lighten(@colour-background, 20%);
.border-radius(7px);

div.buttons
{
text-align: center;
}

button
{
border-top: 2px solid lighten(@colour-background, 40%);
border-left: 2px solid lighten(@colour-background, 40%);
border-right: 2px solid lighten(@colour-background, 10%);
border-bottom: 2px solid lighten(@colour-background, 10%);

&.default
{
border-top: 2px solid lighten(@colour-background, 50%);
border-left: 2px solid lighten(@colour-background, 50%);
border-right: 2px solid lighten(@colour-background, 30%);
border-bottom: 2px solid lighten(@colour-background, 30%);
}

.border-radius(5px);

padding: 2px 5px;
background-color: lighten(@colour-background, 20%);
color: white;
text-shadow: 2px 2px black;

font-family: @font-body;
font-size: 1em;

cursor: pointer;

&:active
{
border-right: 2px solid lighten(@colour-background, 20%);
border-bottom: 2px solid lighten(@colour-background, 20%);
border-top: 2px solid lighten(@colour-background, 10%);
border-left: 2px solid lighten(@colour-background, 10%);
}

&:hover
{
text-decoration: underline;
}
}

p
{
margin-top: 5px;
}

h4
{
text-align: center;
margin-bottom: 10px;
font-weight: bold;
}
}

And finally, you use it as follows:

// Format of the jQuery plugin command is as follows
// $.modaldialog(object, function);
//
// Where object contains optional arguments, and function is an optional callback function for a resulting button click

// As a replacement for alert():
$.modaldialog({ template: "ok", message: "This is just to alert you of something!" });

// As a replacement for confirm():
$.modaldialog({ message: "Can I do something?", callback: function(result) {
if (result)
console.log("I'm doing something, look!");
} });

A few notes on what you can pass as arguments...

title
string: er, well, um, the title of the modal dialog! defaults to "Information" or "Are You Sure?" depending on the template

message
string: the message that appears in the modal dialog. defaults to two silly things that really you don't want. If you set nothing at all, at least make sure you set this other wise it is all a bit pointless!

template
string: sets defaults based on a template, of which there is only really two. One if you specify "ok" as the template, which is pretty much like alert(), not specifying anything results in defaults for a confirm() style dialog

buttons
array of objects: specify like the following: { text: "Cancel", value: false, class: "default" } , where text is the words you want to appear on the button, value is the result you wish the dialog to return to your callback function upon clicking, and class is the optional class you wish the button to have. Note that value is returned as a text string, unless it is "true" or "false" in which case it returns the boolean values.

modalclass
string: class given to the modal dialog DIV itself, defaults to "modaldialog"

blackoutclass
string: class given to the background DIV that appears behind the modal dialog, defaults to "blackout"

buttonclass
string: class given to the DIV that contains the row of buttons, defaults to "buttons"

fadespeed
integer: speed in milliseconds of fade in/out animations, defaults to 300

inoffsetx
integer: animation offset on the X axis of the dialog when fading in, defaults to -200 (appear 200 pixels from the left)

inoffsety
integer: animation offset on the Y axis of the dialog when fading in, defaults to 0

outoffsetx
integer: animation offset on the X axis of the dialog when fading out, defaults to 200 (disappear 200 pixels to the right)

outoffsety
integer: animation offset on the Y axis of the dialog when fading out, defaults to 0

opacity
float: opacity between 0 and 1 for the background DIV, defaults to 0.7

Enjoy! And please post a nice comment if you use it, and report any bugs...

Comments

Add Your Own Comment