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.
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
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.
jQuery 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
How to do this? Promises! To quote Martin Fowler (makes you look smart when you do that):
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
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
cancelButtonText. So by default, "Yes" and "No".
- If the user clicks the "OK" button then the promise is resolved with a value of
- 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.
It's very simple to move from using
confirmDialog. Take this example:
There's no more to it than that.
With the JSFiddle below you can create your own custom dialogs and see the result of clicking on either the "OK" or "Cancel" buttons.