Bootstrap: Open Another Modal in Modal
Asked Answered
H

24

124

So, I'm using this code to open another modal window in a current opened modal window:

<a onclick=\"$('#login').modal('hide');$('#lost').modal('show');\" href='#'>Click</a>

What happens is, that for like 500ms the scrollbar will duplicate. I guess because the current modal is still fading out. However it looks very un-smooth and stuttering.

I would appreciate any suggestions to solve this issue.

Also, is the way building this in an onclick-event unprofessional?

I'm working with the bootstrap version 3.0.

Edit: I guess it's neccesary to reduce the time of fading out a modal. How is this possible?

Hickey answered 22/10, 2013 at 20:54 Comment(3)
A working example can be found at bootply.com/lvKQA2AM28Forklift
@CrandellWS: when both modals are open you cannot close the second modal by clicking on the backdrop; both modals will hide but one backdrop stays visible and thus makes the page inaccessible.Thicken
@Thicken you are correct , in the example add to modalOneModal data-backdrop="static" Forklift
B
114

data-dismiss makes the current modal window force close

data-toggle opens up a new modal with the href content inside it

<a data-dismiss="modal" data-toggle="modal" href="#lost">Click</a>

or

<a data-dismiss="modal" onclick="call the new div here">Click</a>

do let us know if it works.

Barrus answered 23/10, 2013 at 4:3 Comment(9)
Thanks, it works and avoids using "onclick". But the animatiom still doubles the scrollbar for a second.Hickey
@user2829128 thats what data-dismiss does. It closes the current window and opens up a new one. Can you post your code in bootply or jsfiddle ?Barrus
The scrolling wouldn't work on the second modal if the height is long.Bulger
Same here with bootstrap v4. When I click on button on first mondal it is opens enother modal, the second modal shows with scroll of body. The problems is in class .modal-open for body. It removes when we click and dont added again.Bangka
@Bulger yeah thts correct.. what is the solution for prevent scrolling. when any modal open.. /?Tachyphylaxis
@Tachyphylaxis Haven't figured that one out myselfBulger
The solution to that question is to remove the .fade class from ALL the div modal that are using each other. So <div class="modal fade" id="modal-1" tabindex="-1" role="dialog" aria-hidden="true"> Becomes <div class="modal" id="modal-1" tabindex="-1" role="dialog" aria-hidden="true"> And all your problems with this scrollbar are gone! :P Hope it helps.Haight
old window closing but new window not openingRinger
.modal { overflow-y: auto } solves the BS4 scrolling problem.Inferior
P
100

My solution does not close the lower modal, but truly stacks on top of it. It preserves scrolling behavior correctly. Tested in Bootstrap 3. For modals to stack as expected, you need to have them ordered in your Html markup from lowest to highest.

$(document).on('hidden.bs.modal', function (event) {
  if ($('.modal:visible').length) {
    $('body').addClass('modal-open');
  }
});

UPDATE: When you have stacked modals, all the backdrops appear below the lowermost modal. You can fix that by adding the following CSS:

.modal-backdrop {
    visibility: hidden !important;
}
.modal.in {
    background-color: rgba(0,0,0,0.5);
}

This will give the appearance of a modal backdrop below the topmost visible modal. That way it grays out your lower modals underneath.

Prophets answered 16/6, 2015 at 19:28 Comment(5)
Why does the order of the modals matter in the HTML? I experienced this.Hambley
Items later in the page markup have a naturally higher z-index and will stack on top of items that appeared earlier in the markup. Unless you set an explicit z-index.Prophets
Javascript worked for Bootstrap 4, however, CSS did not. Instead I hid the backdrop and then added .modal:after { content: ""; display: block; background: rgba(0,0,0, .5); position: fixed; top: 0; bottom: 0; width: 100%; z-index: -1; }News
This is the only answer, combined with @JasonG.'s tip, that worked for me in Bootstrap 4. All the other answers disable scrolling on the 1st level modal when the 2nd level modal is closed.Voyeur
Bootstrap 4 CSS: .modal-backdrop:nth-child(2n-1) { opacity : 0; }Hypanthium
O
46

Bootstrap 5 (beta) - update 2021

The default z-index for modals has changed to 1060. Therefore, to override the modals and backdrop use..

.modal:nth-of-type(even) {
    z-index: 1062 !important;
}
.modal-backdrop.show:nth-of-type(even) {
    z-index: 1061 !important;
}

Bootstrap 5 multiple modals


Bootstrap 4 - update 2019

I found most of the answers seem to have a lot of unnecessary jQuery. To open a modal from another modal can be done simply by using the events that Bootstrap provides such as show.bs.modal. You may also want some CSS to handle the backdrop overlays. Here are 3 "multiple modals" scenarios...

Open modal from another modal (keep 1st modal open)

<a data-toggle="modal" href="#myModal" class="btn btn-primary">Launch modal</a>

<div class="modal" id="myModal">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <h4 class="modal-title">Modal title</h4>    
              <button type="button" class="close" data-dismiss="modal">×</button>
            </div><div class="container"></div>
            <div class="modal-body">
              ...
              <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Open modal2</a>
            </div>
            <div class="modal-footer">
              <a href="#" data-dismiss="modal" class="btn">Close</a>
            </div>
          </div>
        </div>
</div>
<div class="modal" id="myModal2" data-backdrop="static">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <h4 class="modal-title">2nd Modal title</h4>
              <button type="button" class="close" data-dismiss="modal">×</button>
            </div><div class="container"></div>
            <div class="modal-body">
              ..
            </div>
            <div class="modal-footer">
              <a href="#" data-dismiss="modal" class="btn">Close</a>
              <a href="#" class="btn btn-primary">Save changes</a>
            </div>
          </div>
        </div>
</div>

A potential issue in this case is that the backdrop from the 2nd modal hides the 1st modal. To prevent this, make the 2nd modal data-backdrop="static", and add some CSS to fix the z-indexes of the backdrops...

/* modal backdrop fix */
.modal:nth-of-type(even) {
    z-index: 1052 !important;
}
.modal-backdrop.show:nth-of-type(even) {
    z-index: 1051 !important;
}

https://codeply.com/go/NiFzSCukVl


Open modal from another modal (close 1st modal)

This is similar to the above scenario, but since we are closing the 1st modal when the 2nd is opened, there is no need for the backdrop CSS fix. A simple function that handles the 2nd modals show.bs.modal event closes the 1st modal.

$("#myModal2").on('show.bs.modal', function (e) {
    $("#myModal1").modal("hide");
});

https://codeply.com/go/ejaUJ4YANz


Open modal inside another modal

The last multiple modals scenario is opening the 2nd modal inside the 1st modal. In this case the markup for the 2nd is placed inside the 1st. No extra CSS or jQuery is needed.

<div class="modal" id="myModal1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal title</h4>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            </div>
            <div class="container"></div>
            <div class="modal-body">
                ...
                <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal 2</a>
            </div>
            <div class="modal-footer">
                <a href="#" data-dismiss="modal" class="btn">Close</a>
            </div>
        </div>
    </div>

    <div class="modal" id="myModal2">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">2nd Modal title</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                </div>
                <div class="container"></div>
                <div class="modal-body">
                    ...
                </div>
                <div class="modal-footer">
                    <a href="#" data-dismiss="modal" class="btn">Close</a>
                    <a href="#" class="btn btn-primary">Save changes</a>
                </div>
            </div>
        </div>
    </div>
</div>

https://codeply.com/go/iSbjqubiyn

Osbourn answered 31/8, 2018 at 11:37 Comment(9)
It doesn't work in Bootstrap 4. When you close the 2nd modal, the 1st one no longer can scroll.Voyeur
@Voyeur - I don't see a specific scenario that demonstrates this, and since scrolling is outside the scope of the original question. I suggest you seek for or ask another question specific to the scrolling issue.Osbourn
nth-of-type didn't work for me because it doesn't look at class. I got it working with: .modal-backdrop.show + .modal.show { z-index: 1052 !important; } .modal-backdrop.show + .modal.show + .modal-backdrop.show { z-index: 1051 !important; }Wet
I removed fade calss i.e instead of <div class="modal fade" I used <div class="modal", it solve my issue.Checky
@Zim Using BS5, opening the modals on top of each other, for some reason I must use :nth-of-type(odd) to make this work (on Chrome), no idea why, as the second backdrop is actually placed after the first one... and should therefore be selected with "even"...Nursling
@Zim I figured it out, as another user said before me, the nth-of-type selector just selects elements (in this case it will count the div elements of the page, ignoring the class selectors). To fix it, you can use .modal-backdrop.show~.modal-backdrop.showNursling
it doesn't work for the latest Bootstrap version i.e. v5.1.3Traveller
Not working with Bootstrap v5.1.3. You can open a second modal, but it appears behind the first modal. When you close the first modal, the second modal can be made visible, but you can not select it.Adrieneadrienne
Just test working well with Bootstrap 3Sauerkraut
F
31

To open another modal window in a current opened modal window,
you can use bootstrap-modal

bootstrap-modal DEMO

Fremantle answered 18/3, 2014 at 4:12 Comment(2)
Using this bootstrap-modal shifts the background content to the right.Ribose
@Ribose - see here: #46339563Greenburg
T
22

try this

<!DOCTYPE html>
<html lang="en">
<head>
  <title></title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>

  <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#test1">Open Modal 1 </button>



<div id="test1" class="modal fade" role="dialog" style="z-index: 1400;">
  <div class="modal-dialog">
    <!-- Modal content-->
    <div class="modal-content">
      
      <div class="modal-body">
      	<button type="button" class="btn btn-info btn-lg" data-toggle="modal"      data-target="#test2">Open Modal 2</button>
      	
      </div>      
    </div>
  </div>
</div>

<div id="test2" class="modal fade" role="dialog" style="z-index: 1600;">
  <div class="modal-dialog">
    <!-- Modal content-->
    <div class="modal-content">
      
      <div class="modal-body">
      	
        content
      	
      </div>      
    </div>
  </div>
</div>
  

</body>
</html>
Tabloid answered 10/9, 2015 at 23:34 Comment(2)
fail for me.. =( the modal works but if the 1st modal is long that a scroll for the 1st modal appears and when you open the 2nd modal and close it the first modal scroll fails to work.Jeromejeromy
Thank you very much, it was a great help :)Colis
B
19

You can actually detect when the old modal closes by calling the hidden.bs.modal event:

    $('.yourButton').click(function(e){
        e.preventDefault();

        $('#yourFirstModal')
            .modal('hide')
            .on('hidden.bs.modal', function (e) {
                $('#yourSecondModal').modal('show');

                $(this).off('hidden.bs.modal'); // Remove the 'on' event binding
            });

    });

For more info: http://getbootstrap.com/javascript/#modals-events

Bulger answered 15/5, 2015 at 3:2 Comment(0)
A
19

Modals in Modal:

$('.modal-child').on('show.bs.modal', function () {
    var modalParent = $(this).attr('data-modal-parent');
    $(modalParent).css('opacity', 0);
});
 
$('.modal-child').on('hidden.bs.modal', function () {
    var modalParent = $(this).attr('data-modal-parent');
    $(modalParent).css('opacity', 1);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<a href="#myModal" role="button" class="btn btn-primary" data-toggle="modal">Modals in Modal</a>


<div id="myModal" class="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
             
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header</h4>
            </div>
            <div class="modal-body">
                <a href="#myModal1" role="button" class="btn btn-primary" data-toggle="modal">Launch other modal 1</a>
                <a href="#myModal2" role="button" class="btn btn-primary" data-toggle="modal">Launch other modal 2</a>
            </div>

        </div>
    </div>
</div>

<div id="myModal1" class="modal modal-child" data-backdrop-limit="1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-modal-parent="#myModal">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header 1</h4>
            </div>
            <div class="modal-body">
                <p>Two modal body…1</p>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" data-dismiss="modal" data-dismiss="modal" aria-hidden="true">Cancel</button>
            </div>

        </div>
    </div>
</div>

<div id="myModal2" class="modal modal-child" data-backdrop-limit="1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-modal-parent="#myModal">
    <div class="modal-dialog">
        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header">
                
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header 2</h4>
            </div>
            <div class="modal-body">
                <p>Modal body…2</p>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" data-dismiss="modal" data-dismiss="modal" aria-hidden="true">Cancel</button>
            </div>

        </div>
    </div>
</div>
Alwin answered 27/8, 2016 at 7:52 Comment(5)
fail for me.. =( the modal works but if the 1st modal is long that a scroll for the 1st modal appears and when you open the 2nd modal and close it the first modal scroll fails to work.Jeromejeromy
Example above spawns modal in place of the first modal not on top neither in (first one is no longer visible).Saltwater
Very nice effect.Beebread
How is it possible to use your solution in Semantic UI?Tintometer
I applied this solution in my project but my entire window becoming blur when i close modals which prevent clicking on anythingPortfire
A
10

Working on a project that has a lot of modals calling other modals and a few HTML guys that might not know to initiate it everytime for each button. Came to a similar conclusion as @gmaggio, begrudgingly after going the long way around first.

EDIT: Now supports modals called via javascript.

EDIT: Opening a scrolling modal from another modal now works.

$(document).on('show.bs.modal', function (event) {
    if (!event.relatedTarget) {
        $('.modal').not(event.target).modal('hide');
    };
    if ($(event.relatedTarget).parents('.modal').length > 0) {
        $(event.relatedTarget).parents('.modal').modal('hide');
    };
});

$(document).on('shown.bs.modal', function (event) {
    if ($('body').hasClass('modal-open') == false) {
        $('body').addClass('modal-open');
    };
});

Just place the modal calling button in as normal, and if it is picked up to be inside a modal, it will close the current one first before opening the one specified in data-target. Note that relatedTarget is provided by Bootstrap.

I also added the following to smooth out the fading a bit: I am sure more can be done though.

.modal-backdrop.fade + .modal-backdrop.fade {
    transition: opacity 0.40s linear 0s;
}
Armandinaarmando answered 20/5, 2015 at 23:58 Comment(1)
Not 100% your problem but the shown.bs.modal hook is kinda handy. Management of body.modal-open class seems to be buggy in BS v.3.3.5, after closing one modal and opening another it is missing and therefore the background is scrolling instead of the (second) modal. Your Hook can fix that behaviour.Motorbus
A
9

For bootstrap 4, to expand on @helloroy's answer I used the following;-

var modal_lv = 0 ;
$('body').on('shown.bs.modal', function(e) {
    if ( modal_lv > 0 )
    {
        $('.modal-backdrop:last').css('zIndex',1050+modal_lv) ;
        $(e.target).css('zIndex',1051+modal_lv) ;
    }
    modal_lv++ ;
}).on('hidden.bs.modal', function() {
    if ( modal_lv > 0 )
        modal_lv-- ;
});

The advantage of the above is that it won't have any effect when there is only one modal, it only kicks in for multiples. Secondly, it delegates the handling to the body to ensure future modals which are not currently generated are still catered for.

Update

Moving to a js/css combined solution improves the look - the fade animation continues to work on the backdrop;-

var modal_lv = 0 ;
$('body').on('show.bs.modal', function(e) {
    if ( modal_lv > 0 )
        $(e.target).css('zIndex',1051+modal_lv) ;
    modal_lv++ ;
}).on('hidden.bs.modal', function() {
    if ( modal_lv > 0 )
        modal_lv-- ;
});

combined with the following css;-

.modal-backdrop ~ .modal-backdrop
{
    z-index : 1051 ;
}
.modal-backdrop ~ .modal-backdrop ~ .modal-backdrop
{
    z-index : 1052 ;
}
.modal-backdrop ~ .modal-backdrop ~ .modal-backdrop ~ .modal-backdrop
{
    z-index : 1053 ;
}

This will handle modals nested up to 4 deep which is more than I need.

Abib answered 14/12, 2017 at 15:50 Comment(2)
It doesn't work in Bootstrap 4. When you close the 2nd modal, the 1st one no longer can scroll.Voyeur
Brilliant! I am using Bootsfaces 1.5.0, and was able to get away with only using the CSS, along with adding a z-index of 1060 to the b:modal element.Harwill
F
8

Twitter docs says custom code is required...

This works with no extra JavaScript, though, custom CSS would be highly recommended...

<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Button trigger modal -->
    <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#modalOneModal">
      Launch demo modal
    </button> 
            <!-- Modal -->
            <div class="modal fade bg-info" id="modalOneModal" tabindex="-1" role="dialog" aria-labelledby="modalOneLabel" aria-hidden="true">
    
              <div class="modal-dialog">
          
                <div class="modal-content  bg-info">
                  <div class="modal-header btn-info">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                    <h4 class="modal-title" id="modalOneLabel">modalOne</h4>
                  </div>
                  <div id="thismodalOne" class="modal-body bg-info">
                
                
              <!-- Button trigger modal -->
    <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#twoModalsExample">
      Launch demo modal
    </button>
             
                    <div class="modal fade bg-info" id="twoModalsExample" style="overflow:auto" tabindex="-1" role="dialog" aria-hidden="true">
                <h3>EXAMPLE</h3>
            </div>
                  </div>
                  <div class="modal-footer btn-info" id="woModalFoot">
                    <button type="button" class="btn btn-info" data-dismiss="modal">Close</button>
                  </div>
                </div>
              </div>
            </div>
    <!-- End Form Modals -->
Forklift answered 22/10, 2013 at 20:54 Comment(4)
Here's another example with the 2nd modal being properly formatted bootply.com/qRsvPSrcO5Osbourn
@Skelly changing the z-index as you did in the css is a good idea... z-index: 1080 !important;Forklift
If you open the 2nd modal and click outside it will be bugged. (Chrome, latest)Fein
maybe I am wrong but I believe the docs say not to put a modal in a modal so that is kinda not surprisingForklift
M
5

Try this:

// Hide the login modal
$('#login').modal('hide');

// Show the next modal after the fade effect is finished
setTimeout(function(){ $('#lost').modal('show'); }, 500);

This simple hack works for me.

Mesdames answered 20/10, 2015 at 12:10 Comment(0)
F
5

For someone who use bootstrap 4 https://jsfiddle.net/helloroy/tmm9juoh/

var modal_lv = 0;
$('.modal').on('shown.bs.modal', function (e) {
    $('.modal-backdrop:last').css('zIndex',1051+modal_lv);
    $(e.currentTarget).css('zIndex',1052+modal_lv);
    modal_lv++
});

$('.modal').on('hidden.bs.modal', function (e) {
    modal_lv--
});
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-a">
  Launch demo modal a
</button>

<div class="modal fade" id="modal-a" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-b">
  Launch another demo modal b
</button>
<p class="my-3">
Not good for fade In.
</p>
<p class="my-3">
who help to improve?
</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

<div class="modal fade" id="modal-b" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-c">
  Launch another demo modal c
</button>
<p class="my-3">
But good enough for static modal
</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>


<div class="modal" id="modal-c" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
<p class="my-3">That's all.</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
Fung answered 15/5, 2017 at 7:13 Comment(1)
This is great, the only issue left is to prevent the re-appearance of the scroll-bar when the topmost modal is closedIrrecoverable
H
4

I went kind of a different route all together, I decided to "De-Nest" them. Maybe someone will find this handy...

var $m1 = $('#Modal1');
var $innermodal = $m1.find(".modal");     //get reference to nested modal
$m1.after($innermodal);                  // snatch it out of inner modal and put it after.
Hazlett answered 24/8, 2016 at 17:0 Comment(1)
Thank you very muchLuralurch
B
4

you can use this code to use even more than 2 modal(this sample use 3 modal):

    $('.modal').on('shown.bs.modal', function (e) {
        $('.modal.show').each(function (index) {
            $(this).css('z-index', 1101 + index*2);
        });
        $('.modal-backdrop').each(function (index) {
            $(this).css('z-index', 1101 + index*2-1);
        });
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"  crossorigin="anonymous"></script>



<a data-toggle="modal" href="#myModal1" class="btn btn-primary">Launch modal</a>

<div class="modal" id="myModal1">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal 1</h4>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            </div>
            <div class="container"></div>
            <div class="modal-body">
                <p>
                    Content 1.
                </p>
                <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal 2</a>
            </div>
            <div class="modal-footer">
                <a href="#" data-dismiss="modal" class="btn">Close</a>
            </div>
        </div>
    </div>

</div>

    <div class="modal" id="myModal2">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">modal 2</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                </div>
                <div class="container"></div>
                <div class="modal-body">
                    <p>
                    modal 2
                    </p>
                </div>
                <div class="modal-footer">
                    <a href="#" data-dismiss="modal" class="btn">Close</a>
                    <a href="#" class="btn btn-primary">Save changes</a>
       <a data-toggle="modal" href="#myModal3" class="btn btn-primary">Launch modal3</a>
                </div>
            </div>
        </div>
    </div>

<div class="modal" id="myModal3">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">Modal 3</h4>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            </div>
            <div class="container"></div>
            <div class="modal-body">
                <p>
                    modal 3
                </p>
            </div>
            <div class="modal-footer">
                <a href="#" data-dismiss="modal" class="btn">Close</a>
            </div>
        </div>
    </div>
Blighter answered 28/6, 2021 at 6:46 Comment(0)
J
3

I also had some trouble with my scrollable modals, so I did something like this:

  $('.modal').on('shown.bs.modal', function () {
    $('body').addClass('modal-open');
    // BS adds some padding-right to acomodate the scrollbar at right
    $('body').removeAttr('style');
  })

  $(".modal [data-toggle='modal']").click(function(){
    $(this).closest(".modal").modal('hide');
  });

It will serve for any modal whithin a modal that comes to appear. Note that the first its closed so the second can appear. No changes in the Bootstrap structure.

Jotter answered 14/9, 2015 at 22:5 Comment(0)
M
3

Why not just change the content of the modal body?

    window.switchContent = function(myFile){
        $('.modal-body').load(myFile);
    };

In the modal just put a link or a button

    <a href="Javascript: switchContent('myFile.html'); return false;">
     click here to load another file</a>

If you just want to switch beetween 2 modals:

    window.switchModal = function(){
        $('#myModal-1').modal('hide');
        setTimeout(function(){ $('#myModal-2').modal(); }, 500);
        // the setTimeout avoid all problems with scrollbars
    };

In the modal just put a link or a button

    <a href="Javascript: switchModal(); return false;">
     click here to switch to the second modal</a>
Minerva answered 10/11, 2018 at 4:12 Comment(1)
That's more like an UX related answer, because I needed this to display an error message regarding Modal #1. So Modal #2 had the error message. But it's been ages now since I asked this question and I'm doing this kind of things differently now.Hickey
E
2

My code works well using data-dismiss.

<li class="step1">
    <a href="#" class="button-popup" data-dismiss="modal" data-toggle="modal" data-target="#lightbox1">
        <p class="text-label">Step 1</p>
        <p class="text-text">Plan your Regime</p>
    </a>

</li>
<li class="step2">
    <a href="#" class="button-popup" data-dismiss="modal" data-toggle="modal" data-target="#lightbox2">
        <p class="text-label">Step 2</p>
        <p class="text-text">Plan your menu</p>
    </a>
</li>
<li class="step3 active">
    <a href="#" class="button-popup" data-toggle="modal" data-dismiss="modal" data-target="#lightbox3">
        <p class="text-label">Step 3</p>
        <p class="text-text">This Step is Undone.</p>
    </a>
</li>
Electroluminescence answered 26/5, 2014 at 10:2 Comment(0)
F
1

Close the first Bootstrap modal and open the new modal dynamically.

$('#Modal_One').modal('hide');
setTimeout(function () {
  $('#Modal_New').modal({
    backdrop: 'dynamic',
    keyboard: true
  });
}, 500);
Forster answered 29/6, 2016 at 8:19 Comment(0)
D
1

try this:

$('.modal').on('hidden.bs.modal', function () {
//If there are any visible
  if($(".modal:visible").length > 0) {
      //Slap the class on it (wait a moment for things to settle)
      setTimeout(function() {
          $('body').addClass('modal-open');
      },100)
  }
});
Drabble answered 12/8, 2019 at 21:5 Comment(0)
P
1

This thread is old, but for those who come from google, Ive come with a solutions that is hybrid from all the answers Ive found on the net.

This will make sure level class is being added:

$(document).on('show.bs.modal', '.modal', function (event) {
  $(this).addClass(`modal-level-${$('.modal:visible').length}`);
});

Inside my SCSS Ive wrote a rule that supports main modal and 10 on top (10 because from z-index: 1060 popover takes place), you can add levels count inside _variables.scss if you want:

@for $level from 0 through 10 {
  .modal-level-#{$level} {
    z-index: $zindex-modal + $level;

    & + .modal-backdrop {
      z-index: $zindex-modal + $level - 1;
    }
  }
}

Do not forget that you cannot have modal inside modal as their controls will be messed up. In my case all my modals were at the end of body.

And finally as members below also mentions this, after closing one modal, you need to keep modal-open class on body:

$(document).on('hidden.bs.modal', function (e) {
  if ($('.modal:visible').length > 0) {
    $('body').addClass('modal-open');
  }
});
Pestiferous answered 26/11, 2020 at 8:10 Comment(0)
M
0

The answer given by H Dog is great, but this approach was actually giving me some modal flicker in Internet Explorer 11. Bootstrap will first hide the modal removing the 'modal-open' class, and then (using H Dogs solution) we add the 'modal-open' class again. I suspect this is somehow causing the flicker I was seeing, maybe due to some slow HTML/CSS rendering.

Another solution is to prevent bootstrap in removing the 'modal-open' class from the body element in the first place. Using Bootstrap 3.3.7, this override of the internal hideModal function works perfectly for me.

$.fn.modal.Constructor.prototype.hideModal = function () {
    var that = this
    this.$element.hide()
    this.backdrop(function () {
        if ($(".modal:visible").length === 0) {
            that.$body.removeClass('modal-open')
        }
        that.resetAdjustments()
        that.resetScrollbar()
        that.$element.trigger('hidden.bs.modal')
    })
}

In this override, the 'modal-open' class is only removed when there are no visible modals on the screen. And you prevent one frame of removing and adding a class to the body element.

Just include the override after bootstrap have been loaded.

Microreader answered 23/10, 2018 at 10:22 Comment(0)
R
0

There will be a scrolling glitch if you don't close the 1st modal properly. Here is an example using Bootstrap 4

HTML:

<div class="modal fade" id="modal-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <button onclick="goToModal2">
        Go To Modal 2
      </button>
    </div>
  </div>
</div>

<div class="modal fade" id="modal-2">
<div class="modal-dialog">
    <div class="modal-content">
      <button onclick="goToModal1">
        Go To Modal 1
      </button>
    </div>
  </div>
</div>

Javascript:

function goToModal2(){
  $("#modal-1").modal("hide");
  $("#modal-1").on("hidden.bs.modal", () => {
    $("#modal-2").modal("show");
    $("#modal-1").unbind("hidden.bs.modal");
  });
}

function goToModal1(){
  $("#modal-2").modal("hide");
  $("#modal-2").on("hidden.bs.modal", () => {
    $("#modal-1").modal("show");
    $("#modal-2").unbind("hidden.bs.modal");
  });
}

Though it's not the best way to do it. But it worked perfectly for me.

Rogan answered 31/3, 2021 at 14:51 Comment(0)
T
0

Maybe, not bad:

<style>
#modal2 .modal-content{
box-shadow: 0 0 50px 10px #999 !important;
}
</style>
Tramroad answered 7/7, 2022 at 10:3 Comment(0)
S
-4

$(document).on('hidden.bs.modal', function (event) {
  if ($('.modal:visible').length) {
    $('body').addClass('modal-open');
  }
});
Skuld answered 30/5, 2017 at 16:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.