Rolling your own confirm mechanism using Promises and jQuery UI
It is said that a picture speaks a thousand words. So here's two:
That's right, we're here to talk about the confirm dialog. Or, more specifically, how we can make our own confirm dialog.
JavaScript in the browser has had the window.confirm
method for the longest time. This method takes a string as an argument and displays it in the form of a dialog, giving the user the option to click on either an "OK" or a "Cancel" button. If the user clicks "OK" the method returns true
, if the user clicks "Cancel" the method returns false
.
window.confirm
is wonderful in one way - it has a simple API which is easy to grok. But regardless of the browser, window.confirm
is always as ugly as sin. Look at the first picture in this blog post; hideous. Or, put more dispassionately, it's not terribly configurable; want to change the button text? You can't. Want to change the styling of the dialog? You can't. You get the picture.
#
Making confirm 2.0jQuery UI's dialog has been around for a long time. I've been using it for a long time. But, if you look at the API, you'll see it works in a very different way to window.confirm
- basically it's all about the callbacks. My intention was to create a mechanism which allowed me to prompt the user with jQuery UI's tried and tested dialog, but to expose it in a way that embraced the simplicity of the window.confirm
API.
How to do this? Promises! To quote Martin Fowler (makes you look smart when you do that):
"In Javascript, promises are objects which represent the pending result of an asynchronous operation. You can use these to schedule further activity after the asynchronous operation has completed by supplying a callback."
When we show our dialog we are in asynchronous land; waiting for the user to click "OK" or "Cancel". When they do, we need to act on their response. So if our custom confirm dialog returns a promise of a boolean (true
when the users click "OK", false
otherwise) then that should be exactly what we need. I'm going to use Q for promises. (Nothing particularly special about Q - it's one of many Promises / A+ compliant implementations available.)
Here's my custom confirm dialog:
What's happening here? Well first of all, if okButtonText
, cancelButtonText
or title
have false-y values then they are initialised to defaults. Next, we create a deferred object with Q. Then we create our modal dialog using jQuery UI. There's a few things worth noting about this:
- We're not dependent on the dialog markup being in our HTML from the off. We create a brand new element which gets added to the DOM when the dialog is created. (I draw attention to this as the jQuery UI dialog documentation doesn't mention that you can use this approach - and frankly I prefer it.)
- The "OK" and "Cancel" buttons are initialised with the string values stored in
okButtonText
andcancelButtonText
. So by default, "Yes" and "No". - If the user clicks the "OK" button then the promise is resolved with a value of
true
. - If the dialog closes and the promise has not been resolved then the promise is resolved with a value of
false
. This covers people clicking on the "Cancel" button as well as closing the dialog through other means.
Finally we return the promise from our deferred object.
window.confirm
to confirmDialog
#
Going from It's very simple to move from using window.confirm
to confirmDialog
. Take this example:
Becomes:
There's no more to it than that.
#
And finally a demo...With the JSFiddle below you can create your own custom dialogs and see the result of clicking on either the "OK" or "Cancel" buttons.