6

I have found this an issue with smartphones and it can relate to desktops. We have 'modded' our bootstrap modal to be responsive, however when displayed on a smartphone it is in full screen, the user assumes the modal is a page and clicks back to 'close' it. We have included the in the top right X but would also like the back button to close the modal. Anyone have any ideas?

Thanks

Barmar
  • 741,623
  • 53
  • 500
  • 612
steve0nz
  • 906
  • 5
  • 16
  • 35
  • We faced the exact same problem with Bootstrap 3.0 Modal in Mobile App. We were also using AngularJS 1.4.7. We fixed this issue as mentioned here, http://stackoverflow.com/a/34351827/1069893. Mentioned answer is relevant only if you are using AngularJS though. – Gaurang Patel Dec 20 '15 at 18:15

5 Answers5

17

A better way i found thanks to http://www.mylearning.in/2015/06/close-modal-pop-up-on-back-button.html

    $('#myModal').on('show.bs.modal', function(e) {
        window.location.hash = "modal";
    });

    $(window).on('hashchange', function (event) {
        if(window.location.hash != "#modal") {
            $('#myModal').modal('hide');
        }
    });
Raymond Ativie
  • 1,747
  • 2
  • 26
  • 50
3

Easiest way is to make user feel that its pop-up or model not a new page, by using some margins or making it span10 offset1 kind of.

Another way around is Open and Close method which is described here

And the best method is

<SCRIPT type="text/javascript">
   window.history.forward();
   function noBack() { window.history.forward(); }
</SCRIPT>
</HEAD>
<BODY onload="noBack();"onpageshow="if (event.persisted) noBack();" onunload="">

Described here

for controlling back button from iFrame, try this may help (not tested)

<SCRIPT type="text/javascript">
   window.parent.history.forward();
   function noBack() { window.parent.forward(); }
</SCRIPT>
</HEAD>

Gaurav Gandhi
  • 3,041
  • 2
  • 27
  • 40
  • Thanks, kind of worked but messed with the Modal, I will have to have a deeper look. Cheers. – steve0nz Jun 01 '13 at 22:28
  • thanks @SlimGG - I have been looking at this and it works for the parent page. However I am using an iFrame and have tried putting the code in the iframe head content but it does does not work. I guess I am looking for a function that disables the back button only if the modal is open. – steve0nz Jun 01 '13 at 23:25
  • U can access parent window using window.parent.document. More info at http://stackoverflow.com/a/726866/923426 – Gaurav Gandhi Jun 03 '13 at 11:38
2

You can do that by writing a few lines of code however you'll need a better method in order to achieve a consistent result in which pressing the browser/mobile back button AND hiding modal using [x] button or clicking outside the modal work identical.

I consider the following method a better solution in that sense. it works on modern browsers (HTML5 Javascript ES6) with Bootstrap 4.0 or higher but you'd be able to adapt it for older browser support.

1- Assign a data-hash="#some-hash" attribute to all of the modals that you want to close via browser back button.

2- the block responsible for appending hash to the url

// Add hash to the URL on open modal event
$('.modal').on('shown.bs.modal', function() {
    if (typeof(this.dataset.hash) !== 'undefined') {
        history.pushState(null, null, this.dataset.hash)
    }
})

3- listen to hide.bs.modal event and determine if the back button is pressed or not

// trigger browser back button when the modal is dismissed (using x button etc...)
$('.modal').on('hide.bs.modal', function(event) {
    if (this.dataset.pushback !== 'true') {
        event.preventDefault()
        history.back()
    }
    this.dataset.pushback = ''
})

4- the block responsible to handle browser back button. we add the pushback attribute as a flag to indicate back button press event.

// Close current open modal (if any) on browser back event
window.onpopstate = function() {
    let open_modal = document.querySelector('.modal.show')
    if (open_modal) {
        open_modal.dataset.pushback = 'true';
        $(open_modal).modal('hide')
    }
}
Amin Hemati Nik
  • 477
  • 6
  • 15
1

I use this code, which also works on multiple modals in a single page:

$('#myModal').on('show.bs.modal', function (e) {
   window.history.pushState('#myModal', "Modal title", document.location+'#myModal');
}).on('hide.bs.modal', function (e) {
   if ( window.history.state === '#myModal' ) {
   history.go(-1);
   }
})

and then attach a "hashchange" event listener to hide the modal on back button:

window.addEventListener("hashchange", function(e) {
    $('#myModal').modal('hide');
})
0

Here is how I got it to work with BootstrapDialog plugin... 3 one-liners per popup (this allows multiple popups, and only the most recent is closed on back)

//Within the BootstrapDialog INIT...
ContactInfosDialog = BootstrapDialog.show({
    data: ...
//Add to history so Back button closes popup instead of going back.
 onshown: function() {location.hash +=          '-popContactInfos';},
//Go back on history when closing popup, so Back button works for page next time
onhidden: function() {if (location.hash.indexOf('-popContactInfos') > -1)
                       {history.back();}
                     },
   title: ...
     etc: ...
                                         });

//Anywhere outside the BootstrapDialog INIT...
//Back button will just move back history on first click,
//below will make it also close the popup.
$(window).on('hashchange', function() 
                     {if (location.hash.indexOf('-popContactInfos')===-1)
                       {ContactInfosDialog.close();}
                     }
            ); 

/*
HOW IT WORKS:
1) Setting location.hash will add a hashtag #name to the URL.
I use += to add to the hash name, so multiple popups would be url#-pop1-pop2
2) When the popup is closed, history.back will back up one step to url#-pop1
3) hashchange lets you look at the url#{popups-list} when the url  changes,  
and if your popup name isn't in the list we know to close it.
*/