<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Create a responsive confirmation popup using HTML, CSS, jQuery and Promises

Published on
14,746 Points
11,346 Views
4 Endorsements
Last Modified:
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises

Overview

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 Template

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

The HTML


<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.

The CSS


.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

insert1.jpgSo 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

  1. We can simply put it into the document
  2. We can create the markup dynamically with jQuery

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.


  1. We need to attach click handlers to the buttons
  2. We need to capture the user response

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>

 

4
2 Comments

Expert Comment

by:Carine Lawson
Great. I'm going to try this now.THanks so much. I had a hard time googling for what I wanted specifically. This was it. Here goes....
0

Expert Comment

by:Alouani Younes
Great and simple solution. The styling is basic and therefore simple to customize.
0

Featured Post

Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month