musium
musium

Reputation: 3072

Bootstrap 3 nested modals – backdrop z-index and close modal on click

I’m working on a web application (Asp.Net MVC 5) where the user has to crate many data records with mappings to other records. The user must be able to create a mapping to an existing or newly created record.

A typical case would be the creation of an address:

The selection is implemented using bootstrap modals. Pressing on a select button (like select city) shows a modal containing a table showing all the selectable records in a table. The modal with the table contains an add new button to add new entities, which opens another modal.

To be able to reuse the views I’ve split the code in partial views like this:

…and so on

I’ve two problems:

I’ve tried to set the z-index of the backdrops on modal show, to make sure they hide the other modals but this didn’t work => the backdrops get displayed above the current modal.

Here is a fiddle showing the problem: jsFiffle

SO does not let me link to a JSFiddle without adding the code to the question, so here is the code:

HTML:

<!-- Create Address -->
<div id="CreateAddress" class="modal fade fullScreen" tabindex="-1" role="dialog">
    <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>
                <h4 class="modal-title">Create Address</h4>
            </div>
            <div class="modal-body">
                <div class="alert alert-info">
                              <strong>Placeholder</strong> Here is the form to create an address
                    <button class="btn btn-default" id="selectCityButton">select city</button>
                        </div>
                <button class="btn btn-primary">OK (not implemented)</button>
                <button class="btn btn-default modalCloseButton"
                        data-modalid="CreateAddress">Cancel</button>
            </div>
        </div>
    </div>
</div>

<!-- Select City -->
<div id="SelectCity" class="modal fade fullScreen" tabindex="-1" role="dialog">
    <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>
                <h4 class="modal-title">Select a City</h4>
            </div>
            <div class="modal-body">
                <div class="alert alert-info">
                              <strong>Placeholder</strong> Here is a table to select an existing city
                        </div>
                <button class="btn btn-success btn-block" id="createCityButton">Create new city</button>
                <button class="btn btn-primary">OK (not implemented)</button>
                <button class="btn btn-default modalCloseButton"
                        data-modalid="SelectCity">Cancel</button>
            </div>
        </div>
    </div>
</div>

<!-- Create City -->
<div id="CreateCity" class="modal fade fullScreen" tabindex="-1" role="dialog">
    <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>
                <h4 class="modal-title">Create City</h4>
            </div>
            <div class="modal-body">
                <div class="alert alert-info">
                              <strong>Placeholder</strong> Here is the form to create a city
                    <button class="btn btn-default" id="selectCountryButton">select country of city</button>
                        </div>
                <button class="btn btn-primary">OK (not implemented)</button>
                <button class="btn btn-default modalCloseButton"
                        data-modalid="CreateCity">Cancel</button>              
              <!-- Select Country -->
              <div id="SelectCountry" class="modal fade fullScreen" tabindex="-1" role="dialog">
                  <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>
                              <h4 class="modal-title">Select a Country</h4>
                          </div>
                          <div class="modal-body">
                              <div class="alert alert-info">
                                  <strong>Placeholder</strong> Here is a table to select an existing country
                              </div>
                              <button class="btn btn-success btn-block" id="createCountryButton">Create new country</button>
                              <button class="btn btn-primary">OK (not implemented)</button>
                              <button class="btn btn-default modalCloseButton"
                                      data-modalid="SelectCountry">Cancel</button>
                          </div>
                      </div>
                  </div>
              </div>
              <!-- Select Country END -->
              <!-- Create Country -->
              <div id="CreateCountry" class="modal fade fullScreen" tabindex="-1" role="dialog">
                  <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>
                              <h4 class="modal-title">Create Country</h4>
                          </div>
                          <div class="modal-body">
                              <div class="alert alert-info">
                                  <strong>Placeholder</strong> Here is the form to create a country
                              </div>
                              <button class="btn btn-primary">OK (not implemented)</button>
                              <button class="btn btn-default modalCloseButton"
                                      data-modalid="CreateCountry">Cancel</button>
                          </div>
                      </div>
                  </div>
              </div>
              <!-- Create Country END -->

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

<button class="btn btn-primary btn-block" id="openModal">Open Modal</button>

JS:

var zIndex = 10000;
    // Displys the given modal on top of everything else
    // modal: The modal to display as jQuery object
    // Does not work => remove thw first two lines to see the problem
    function displayModalOnTop(modal) {
    // remove me
    modal.modal('show');
    return;
    // end remove
        zIndex += 2;
        modal.css('z-index', zIndex);
        modal.modal('show');
        setTimeout(function () {
            $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
        }, 0);
    }

$(function(){
  $('#openModal').on('click', function(){
      displayModalOnTop($('#CreateAddress'));
  });

  // generic close modal handler
  $('.modalCloseButton').on('click', function(){
      var $this = $(this);
      var modalId = $this.attr('data-modalid');
      $('#' + modalId).modal('hide');
  })

  // Select city click
  $('#selectCityButton').on('click', function(){
      displayModalOnTop($('#SelectCity'));
  });

  // Create city click
  $('#createCityButton').on('click', function(){
      displayModalOnTop($('#CreateCity'));
  });

  // Select country click  
  $('#selectCountryButton').on('click', function(){
      displayModalOnTop($('#SelectCountry'));
  });

  // Create country click
  $('#createCountryButton').on('click', function(){
      displayModalOnTop($('#CreateCountry'));
  });
});

CSS:

.modal.fullScreen {
  padding-left: 0 !important;
  padding-right: 0 !important;
  margin-top: 48px;
}
.modal.fullScreen .modal-content {
  height: auto;
  min-height: 100%;
  border-radius: 0;
}
.modal.fullScreen .modal-body.noPadding {
  padding: 0;
}
.modal.fullScreen .modal-dialog {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}
.modal.fullScreen .modal-header {
  background-color: #3276b1;
  color: #fff;
}
.modal.fullScreen .modal-header .close {
  color: #FFF;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.4;
  font-size: 30px;
}
.modal.fullScreen .modal-header .close:hover {
  opacity: 1 !important;
}

Upvotes: 1

Views: 4641

Answers (2)

Shalin Patel
Shalin Patel

Reputation: 1099

Rather then writing this much of code on your own and maintaining everything by your self what you can do is simply given in below snippet.

function simpleSHow(title)
			{
				var msg=$('#simple-div');
				
				BootstrapDialog.show({
					title : title,
					message: $('#simple-div'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
			
			function complexSHow(title)
			{
				var msg=$('#complex-div');
				
				BootstrapDialog.show({
					title : title,
					message: $('#complex-div'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
			
			function showDiv1(div_id)
			{
				var msg=$('#lavel-2_div-1');
				BootstrapDialog.show({
					title : 'Level 2 Title',
					message: $('#lavel-2_div-1'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
			
			function showDiv2(div_id)
			{
				var msg=$('#lavel-2_div-2');
				BootstrapDialog.show({
					title : 'Level 2 Title',
					message: $('#lavel-2_div-2'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
			
			function showDiv3(div_id)
			{
				var msg=$('#lavel-2_div-3');
				BootstrapDialog.show({
					title : 'Level 2 Title',
					message: $('#lavel-2_div-3'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
			
			function showDiv4(div_id)
			{
				var msg=$('#lavel-2_div-4');
				BootstrapDialog.show({
					title : 'Level 2 Title',
					message: $('#lavel-2_div-4'),
					onhide : function(){
						$('#hidden-div').append(msg);
					}
				});
			}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap3-dialog/1.35.3/css/bootstrap-dialog.min.css" rel="stylesheet">


<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap3-dialog/1.35.3/js/bootstrap-dialog.min.js"></script>



<!--  This is a container Div which contains all the div to show when bootstrap dialog opens -->
<div style="display : none" id="hidden-div">
  <div id="simple-div">
    <h1>This is H1 Heading</h1>
    This is most simple coding
    <br>
    <button type="button" class="btn btn-primary" onclick="showDiv1()">Lavel-2 div-1</button>
    <button type="button" class="btn btn-primary" onclick="showDiv2()">Lavel-2 div-2</button>
  </div>

  <div id="lavel-2_div-1">
    <h3>This is Level 2 Header</h3>
    <span style="color : blue;">This is Level 2 Message 1</span>
  </div>

  <div id="lavel-2_div-2">
    <h3>This is Level 2 Header</h3>
    <span style="color : greenyellow;">This is Level 2 Message 2</span>
  </div>

  <div id="lavel-2_div-3">
    <h3>This is Level 2 Header</h3>
    <span style="color : pink;">This is Level 2 Message 3</span>
  </div>
  <div id="lavel-2_div-4">
    <h3>This is Level 2 Header</h3>
    <span style="color : green;">This is Level 2 Message 4</span>
  </div>

  <div class="container-fluid" id="complex-div">

    <button type="button" class="btn btn-primary" onclick="showDiv3()">Lavel-2 div-3</button>
    <button type="button" class="btn btn-primary" onclick="showDiv4()">Lavel-2 div-4</button>
    <h2>Panels with Contextual Classes</h2>
    <div class="panel-group">
      <div class="panel panel-default">
        <div class="panel-heading">Panel with panel-default class</div>
        <div class="panel-body">Panel Content</div>
      </div>

      <div class="panel panel-primary">
        <div class="panel-heading">Panel with panel-primary class</div>
        <div class="panel-body">Panel Content</div>
      </div>

      <div class="panel panel-success">
        <div class="panel-heading">Panel with panel-success class</div>
        <div class="panel-body">Panel Content</div>
      </div>

      <div class="panel panel-info">
        <div class="panel-heading">Panel with panel-info class</div>
        <div class="panel-body">Panel Content</div>
      </div>

      <div class="panel panel-warning">
        <div class="panel-heading">Panel with panel-warning class</div>
        <div class="panel-body">Panel Content</div>
      </div>

      <div class="panel panel-danger">
        <div class="panel-heading">Panel with panel-danger class</div>
        <div class="panel-body">Panel Content</div>
      </div>
    </div>
  </div>

</div>

&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;
<button type="button" class="btn btn-primary" onclick="simpleSHow('Hello 1234')">Simple Div Show</button>
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;
<button type="button" class="btn btn-primary" onclick="complexSHow('Complex 1234')">Complex Div Show</button>

Upvotes: 0

musium
musium

Reputation: 3072

The problem was that the modal covered the hole screen. The backdrop was visible due to the margin of the modal but was not clickable because it was totally covered by the modal. Removing the margin from the modal and adding it to the modal dialog fixed the problem.

Upvotes: 1

Related Questions