6

Okay, I've spent whole day reading Q&A but still couldn't get it done. I needed to create a customized confirm() wherein instead of the default dialog, I use bootstrap modal to return true if user clicks Yes, return false for No.

Example:

<a href="remove.php?id=3" onclick="return custom_confirm('Are you sure you want to remove this?');" />

and my custom confirm function is:

function custom_confirm(message) {
  //  put message into the body of modal
  $('#modal-custom-confirmation').on('show.bs.modal', function (event) {
  //  store current modal reference
    var modal = $(this);

    //  update modal body help text
    modal.find('.modal-body #modal-help-text').text(message);
  });

  //  show modal ringer custom confirmation
  $('#modal-custom-confirmation').modal('show');

  //  if Yes button is clicked, return true
  //  if No  button is clicked,  return false
  //  logic here...
}

My modal is here:

<!--  modal: custom confirmation  -->
<div class="modal fade text-left" id="modal-custom-confirmation" tabindex="-1" role="dialog" aria-labelledby="modal-help-title">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <strong class="modal-title" id="modal-help-title">Confirm</strong>
      </div><!--  /.modal-header  -->
      <div class="modal-body">
        <p id="modal-help-text"></p>
      </div><!--  /.modal-body  -->
      <div class="modal-footer">
        <button type="button" class="btn btn-success">Yes</button>
        <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
      </div><!--  /.modal-footer  -->
    </div><!--  /.modal-content  -->
  </div><!--  /.modal-dialog  -->
</div><!--  /.modal  -->
Colin
  • 1,112
  • 1
  • 16
  • 27
Lynnell Neri
  • 473
  • 1
  • 9
  • 21
  • 1
    The same thing happened to me in the past, and finally I had to use a library outside http://bootboxjs.com/. – Tran Audi Aug 03 '17 at 09:50
  • @TranAudi, thank you! You nailed it here: http://bootboxjs.com/examples.html#also-applies-to-alert-prompt-customwith-alternate-button-tex – Lynnell Neri Aug 03 '17 at 10:04

2 Answers2

5

Click event is inherently non blocking and async. Unlike native confirm. So you can't return true or false. You have to somehow handle the async nature of user interaction.

The most straight forward way would be to pass a callback

function custom_confirm(message, callback) {
  //  put message into the body of modal
  $('#modal-custom-confirmation').on('show.bs.modal', function (event) {
  //  store current modal reference
    var modal = $(this);

    //  update modal body help text
    modal.find('.modal-body #modal-help-text').text(message);
  });

  //  show modal ringer custom confirmation
  $('#modal-custom-confirmation').modal('show');

  $('#modal-custom-confirmation button.ok').off().on('click', function() {
     // close window
     $('#modal-custom-confirmation').modal('hide');

     // and callback
     callback(true);
  });

  $('#modal-custom-confirmation button.cancel').off().on('click', function() {
     // close window
     $('#modal-custom-confirmation').modal('hide');
     // callback
     callback(false);
  });
}

And in HTML

...
<div class="modal-footer">
        <button type="button" class="btn btn-success ok">Yes</button>
        <button type="button" class="btn btn-default cancel">No</button>
      </div>
...

If you want to actually return something you could return a Promise that would resolve to either true or false. But still async code remains async.

Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
2

Thanks for the answers and comment everyone. I've finally solved it. As suggested, I used a library called Bootbox.js and use a customized confirm with alternate button text (no need to reinvent the wheel, just tweak it to suit the need)

Then I incorporated the answers of: Nuno Reis, Fabien Ménager, and Ryan McGeary, to create the solution. Here's what I did:

  1. Add class as identifier for links to use this custom confirmation. In my code, I used custom-confirm-link.

  2. Put confirmation message into data bind data-confirmation.

    So my link now looks like this:

    <a href="remove.php?id=3" class="custom-confirm-link" data-confirmation="Are you sure you want to remove this?" />
    
  3. In footer, I added click event listener to links with class custom-confirm-link. Inside:

    • I retrieved the link triggered, its href and its confirmation message through data bind data-confirmation
    • I did preventDefault() to the event
    • popped a bootbox.js confirm with custom label for confirm (yes) and cancel (no),
    • and utilized its callback to process the result
    • Only when confirm button yes is clicked will I simulate the clicking of link through window.location.href.

That's it. Here's the click event listener code:

<script type="text/javascript">
    //  click event listener to links that requires custom confirm
    $('.custom-confirm-link').click(function(e){

        //  get link and its confirmation message
        var link                = $(this);
        var confirmationmessage = link.data('confirmation');
        var address             = link.attr('href');

        e.preventDefault();

        bootbox.confirm({
            title   : 'Confirm',
            message : confirmationmessage,
            buttons : {
                confirm : {
                    label : 'Yes',
                    className: 'btn-success'
                },
                cancel : {
                    label : 'No',
                    className : 'btn-danger'
                }
            },
            callback : function (result) {
                if (result)
                {
                    //  simulate click the link
                    window.location.href = address;
                }
            }
        });
    });
</script>
Lynnell Neri
  • 473
  • 1
  • 9
  • 21