There are many instances I come across where the requirement is for something more than the default JavaScript confirm dialog. While there are many libraries out there that provide this, many of them are over-engineered to do more than the simple requirement of displaying a confirmation dialog with an Ok/Cancel button. Another requirement is how to make the dialog work like the Confirm dialog so that a return value can be tested for the user interaction. This article will show how to build a simple popup dialog using a few lines of jQuery. As part of creating the dialog we will make use of JavaScript promises to handle the click events on the dialog buttons.
The first step is to create the template. This involves HTML and CSS only. We want a dialog that is centered (horizontally), is a reasonable distance from the top of the page and is responsive so that it scales to different screen sizes
<div class="popup">
<p>This is the message</p>
<div class="text-right">
<button class="btn btn-cancel">Cancel</button>
<button class="btn btn-primary">Ok</button>
</div>
</div>
That should cover the basics.
.popup {
width: 33.333333%;
padding: 15px;
left: 0;
margin-left: 33.333333%;
border: 1px solid #ccc;
border-radius: 10px;
background: white;
position: absolute;
top: 15%;
box-shadow: 5px 5px 5px #000;
z-index: 10001;
}
That should give us something that looks like this
So far so good. We have a dialog that takes up 33.33% of the screen, is centered horizontally and has border, rounded corners and drop shadow.
You will note the buttons are Bootstrap buttons - for this example I am using Bootstrap to do some of the styling.
A modal dialog is not truly modal if you can see and interact with the page that it is overlaying. To complete this we need to create an overlay that will be semi opaque and sit between the Confirmation dialog and the page.
<div class="overlay">
<div class="popup">
<p>This is the message</p>
<div class="text-right">
<button class="btn btn-cancel">Cancel</button>
<button class="btn btn-primary">Ok</button>
</div>
</div>
</div>
The CSS for the overlay would look something like this
.overlay {
position: fixed;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,.85);
z-index: 10000;
}
One final CSS change to make. We need some media queries to change the width of the modal at smaller screen sizes.
Here is an example of how we can do this
@media (min-width: 768px) {
.popup {
width: 66.66666666%;
margin-left: 16.666666%;
}
}
@media (min-width: 992px) {
.popup {
width: 50%;
margin-left: 25%;
}
}
@media (min-width: 1200px) {
.popup {
width: 33.33333%;
margin-left: 33.33333%;
}
}
One final change. Lets add something to make the loading of the dialog a little more impressive. We can take a leaf out of Bootstrap's book and animate the modal into view from the top of the page. To do this we first need to change our popup style to move the dialog above the top of the screen.
top: -100%;
Now we add a little bit of jQuery to activate the modal on a mouse click
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(function() {
$(window).click(function() {
$('.popup').animate({top: '15%'}, 1000);
});
});
</script>
That gives us our HTML and CSS. Now for the jQuery.
We have two options for creating the markup for the popup
For this example we are going to go with option 2. To achieve this we need to convert the overlay and popup markup into jQuery calls to create the elements required.
We define a function showPrompt() that takes a parameter msg that contain the message we want to display to the user
<script>
function showPrompt(msg)
{
// CREATE THE popup AND APPEND THE msg
var dialog = $('<div/>', {class: 'popup'})
.append(
$('<p/>').html(msg)
)
// CREATE THE BUTTONS
.append(
$('<div/>', {class: 'text-right'})
.append($('<button/>', {class: 'btn btn-cancel'}).html('Cancel'))
.append($('<button/>', {class: 'btn btn-primary'}).html('Ok'))
);
// CREATE THE overlay AND APPEND THE dialog
var overlay = $('<div/>', {class: 'overlay'})
.append(dialog);
// ADD THE overlay AND dialog TO THE PAGE
$('body').append(overlay);
// ANIMATE dialog INTO VIEW
$(dialog).animate({top: '15%'}, 1000);
}
</script>
That should do it. Lets change the click above to rather show a prompt dynamically. Note we are using the jQuery .one() function because we want to test the buttons and with our current code, the button clicks will keep triggering the animation which we don't want
<script src="http://code.jquery.com/jquery.js"></script>
<script>
function showPrompt(msg)
{
// CREATE THE popup AND APPEND THE msg
var dialog = $('<div/>', {class: 'popup'})
.append(
$('<p/>').html(msg)
)
// CREATE THE BUTTONS
.append(
$('<div/>', {class: 'text-right'})
.append($('<button/>', {class: 'btn btn-cancel'}).html('Cancel'))
.append($('<button/>', {class: 'btn btn-primary'}).html('Ok'))
);
// CREATE THE overlay
var overlay = $('<div/>', {class: 'overlay'})
.append(dialog);
// ADD THE overlay AND dialog TO THE PAGE
$('body').append(overlay);
// ANIMATE dialog INTO VIEW
$(dialog).animate({top: '15%'}, 1000);
}
$(function() {
$(window).one('click',function() {
showPrompt('Do you like our confirmation?');
});
});
</script>
We are mostly done. There are only two things remaining.
The click handlers can be added like this
// CREATE THE BUTTONS
.append(
$('<div/>', {class: 'text-right'})
.append($('<button/>', {class: 'btn btn-cancel'}).html('Cancel').on('click', function() {
$('.overlay').remove();
}))
.append($('<button/>', {class: 'btn btn-primary'}).html('Ok').on('click', function() {
$('.overlay').remove();
}))
);
Notice that all we are doing on a button click is to remove the .overlay element. Because .popup is a child of .overlay when we remove the latter it removes both.
Almost done - all we need is some way to get the user response. We could pass in a callback function but the use of callbacks is being phased out in favour of Promises so for this example we are going to wrap the creation of our dialog in a Promise and return the promise to our calling code. In our button click we are going to resolve the Promise to either true or false depending on the button clicked.
Here is the showPrompt() function wrapped in a promise
function showPrompt(msg)
{
// CREATE A Promise TO RETURN
var p = new Promise(function(resolve, reject) {
var dialog = $('<div/>', {class: 'popup'})
.append(
$('<p/>').html(msg)
)
.append(
$('<div/>', {class: 'text-right'})
.append($('<button/>', {class: 'btn btn-cancel'}).html('Cancel').on('click', function() {
$('.overlay').remove();
// RESOLVE Promise TO false
resolve(false);
}))
.append($('<button/>', {class: 'btn btn-primary'}).html('Ok').on('click', function() {
$('.overlay').remove();
// RESOLVE Promise TO true
resolve(true);
}))
);
var overlay = $('<div/>', {class: 'overlay'})
.append(dialog);
$('body').append(overlay);
$(dialog).animate({top: '15%'}, 1000);
});
// RETURN THE Promise
return p;
}
We just need to modify our jQuery to call this so we can respond to the user click
In the code below we have changed the click to be bound to an <a/> element, and the .one() changed to on() so that we can open the dialog multiple times.
$(function() {
// HANDLE open-dialog CLICK
$('.open-dialog').on('click',function(e) {
// PREVENT DEFAULT BEHAVIOUR FOR <a/>
e.preventDefault();
// SAVE PROMISE RETURN
var res = showPrompt('Do you like our confirmation?');
res.then(function(ret) {
// SHOW AN ALERT BASED ON WHICH BUTTON WAS CLICKED
ret ? alert('Ok clicked') : alert('Cancel clicked');
})
});
});
That's it - we have a confirmation dialog that works on promises.
Full listing below, working sample here
<!doctype html>
<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<style type="text/css">
.overlay {
position: fixed;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,.85);
z-index: 10000;
}
.popup {
width: 98%;
padding: 15px;
left: 0;
margin-left: 1%;
border: 1px solid #ccc;
border-radius: 10px;
background: white;
position: absolute;
top: -100%;
box-shadow: 5px 5px 5px #000;
z-index: 10001;
}
@media (min-width: 768px) {
.popup {
width: 66.66666666%;
margin-left: 16.666666%;
}
}
@media (min-width: 992px) {
.popup {
width: 50%;
margin-left: 25%;
}
}
@media (min-width: 1200px) {
.popup {
width: 33.33333%;
margin-left: 33.33333%;
}
}
</style>
</head>
<body>
<h1>Hello World</h1>
<p><a href="#" class="open-dialog">Open Dialog</a></p>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
function showPrompt(msg)
{
// CREATE A Promise TO RETURN
var p = new Promise(function(resolve, reject) {
var dialog = $('<div/>', {class: 'popup'})
.append(
$('<p/>').html(msg)
)
.append(
$('<div/>', {class: 'text-right'})
.append($('<button/>', {class: 'btn btn-cancel'}).html('Cancel').on('click', function() {
$('.overlay').remove();
// RESOLVE Promise TO false
resolve(false);
}))
.append($('<button/>', {class: 'btn btn-primary'}).html('Ok').on('click', function() {
$('.overlay').remove();
// RESOLVE Promise TO true
resolve(true);
}))
);
var overlay = $('<div/>', {class: 'overlay'})
.append(dialog);
$('body').append(overlay);
$(dialog).animate({top: '15%'}, 1000);
});
// RETURN THE Promise
return p;
}
$(function() {
// HANDLE open-dialog CLICK
$('.open-dialog').on('click',function(e) {
// PREVENT DEFAULT BEHAVIOUR FOR <a/>
e.preventDefault();
// SAVE PROMISE RETURN
var res = showPrompt('Do you like our confirmation?');
res.then(function(ret) {
ret ? alert('Ok clicked') : alert('Cancel clicked');
})
});
});
</script>
</body>
</html>
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (3)
Commented:
Commented:
Commented: