4

I am attempting to make a Calculator in JavaScript. I'm almost at the end, so I added a modal through Bootstrap, which contains an instruction list(somewhat like a manual). While the modal works perfectly on my local machine, it works only halfway through in CodePen.

The issue appears to be that a click on the button brings up the modal but it does not go away if you click on the "Close" button or even the "cross" icon on the modal. It looks like the modal is disabled when it opens up, and the only way to get everything working again is to refresh the codepen link.

As I'm making this calculator for an online tutorial exercise, I need to submit it via CodePen only. So I've got to make this work.

Here's the relevant HTML -

<div id="instructions">
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-primary btn-large" data-toggle="modal" data-target="#myModal">
      Launch Instructions
    </button>

    <!-- Modal -->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
      <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" id="myModalLabel">Instructions</h4>
          </div>
          <div class="modal-body">
            <ul class="list-group">
              <li class="list-group-item">Click on the AC button before beginning each new calculation.</li>
              <li class="list-group-item">For square root of a number, first press the number then press the square root button.</li>
              <li class="list-group-item">An operation that results in a number too large to fit on the screen will display zero instead.</li>
              <li class="list-group-item">If a number has too many digits after the decimal point to fit on screen, some of the digits will be truncated.</li>
              <li class="list-group-item">Some operations like divide by zero, and square root of negative integers are not permitted.</li>
            </ul>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

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

  </div>

In CodePen, I've added BootStrap through CSS quickadd, and for JS, I added jQuery and then Bootstrap(in that order), so I'm not sure why it doesn't work. I have followed the same order in my local files, where the modal works perfectly-

<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

<script type="text/javascript" src="4.js"></script>

Here's the CodePen link for my calculator. Interestingly though, I made another Pen here where I was testing just the modal bit, and it works just fine here.

Manish Giri
  • 3,562
  • 8
  • 45
  • 81
  • If I visit your calculator on `codePen`, the modal show and close correctly. So I can not see what's wrong with it. I use FF 42 – Franco Dec 26 '15 at 01:22
  • 1
    I have just opened it with chrome and there is not working. The problem is the overlay which stay on top of your modal not allowing you to click on it. – Franco Dec 26 '15 at 01:25
  • I took two screenshots, one of the codepen [pen](https://dl.dropbox.com/s/xdvgf5q8x9tz6l7/modal1.png?dl=0) and the other one of my local browser [chrome](https://dl.dropbox.com/s/y2oifavm8h9abcm/modal2.png?dl=0). I'm not sure if you can tell, but in the first one, the modal is greyed out, like disabled, and in the second one, it looks very much active. – Manish Giri Dec 26 '15 at 01:27
  • As I sad, the bootstrap modal has an overlay. This works good in FF but not in Chrome. That's is what you see as 'greyed out'. This is the `overlay` and it is on top of your modal. You are not able to click on it. A simple fix could be to change the `z-index` of your modal to an higher value, to push him on top of the overlay. – Franco Dec 26 '15 at 01:32
  • Changing the z-index does not fix the issue. – Sahil Dec 26 '15 at 01:40
  • @Sahil, I saw that now, when I was trying on `codePen` – Franco Dec 26 '15 at 01:44
  • @Franco was reading [this](http://stackoverflow.com/a/1384650/3863146), never tried out keeping a fixed element inside a fixed one until today. – Sahil Dec 26 '15 at 01:48
  • You can see the explanation of different behaviour of modal window when kept inside a fixed parent [here](http://stackoverflow.com/a/34468174/3863146). – Sahil Dec 26 '15 at 03:46

2 Answers2

1

It is happening because you have made position of instructions fixed.

As you had made #instructions fixed, which is the parent of modal, the modal was relatively above its parent(#instructions), but the parent(#instructions) itself was below the backdrop(<div class="modal-backdrop fade in"></div>) as it's(#instructions) z-index was not set which gets created when you open a modal window.

If I remove position fixed from the div instructions your modal works fine. Instead of fixing the div to the bottom you can directly apply the CSS on the button.

#instructions button {
    position: fixed;
    left: 44%;
    bottom: 0;
}

Or else you could just move the #instructions above the backdrop div.

#instructions{
  z-index: 1049;/*keeping z-index above 1040*/
  position: fixed;
  left: 44%;
  bottom: 0;
}

A small demo of the same issue, where one cannot click on close buttons inside the modal in Chrome whereas the buttons are clickable in FF. Here the modal is placed inside another container whose position is fixed.

Try getting the z-index of modal's parent in FF and Chrome. In this demo $('.parent').css('z-index');

Chrome z-index is set to 0

FF z-index is set to 'auto'

This explains the above issue.

$(function(){
  $('.modal-body > span').html($('.parent').css('z-index'));
});
.parent{
      position: fixed;
    }
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<div class="parent">
      <!-- Button trigger modal -->
      <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Launch demo modal
      </button>

      <!-- Modal -->
      <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <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" id="myModalLabel">Modal testing</h4>
            </div>
            <div class="modal-body">
              z-index: <span></span>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
              <button type="button" class="btn btn-primary">Save changes</button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
Sahil
  • 3,338
  • 1
  • 21
  • 43
  • I'm not sure I understand the reason entirely. What does `position:fixed` of the `instructions` div have to do with the modal not appearing correctly? I thought the modal body(the overlay) is independent of how it's placed in the HTML. Also, if this is solely the reason, why does the modal work correctly(as-is) in Chrome (outside of Codepen)? And secondly, how did you get the `z-index` as `1040` in your second method? – Manish Giri Dec 26 '15 at 01:50
  • 1
    No, keeping a fixed element inside another fixed element makes it relative to its parent, which is why you were facing this issue. – Sahil Dec 26 '15 at 01:57
  • 1040 is the z-index of **modal-backdrop** which is defined in bootstrap. Some browser environment assume default values if you do not specify them. For e.g. in Firefox if you position an element with just `top` and get the desired result (firefox will not set any value for `left`), but chrome will set it's `left` value to 0 if not specified, which is why it is best to define the CSS properties completely and not to rely on the browser defaults. This is what I have noticed till now when building cross browser compatible websites. – Sahil Dec 26 '15 at 02:11
  • The buttons in the demo are clickable in FF, where as it doesnt work in Chrome, the reason is here: Try getting the z-index of modal's parent in FF and Chrome. `$('.parent').css('z-index');` In Chrome z-index is set to 0, where as in FF it is set to 'auto'. – Sahil Dec 26 '15 at 02:33
0

I had this problem too. Problem is comming from html, created by bootstrap js:

<div class="modal-backdrop fade in"></div>

This line is created directly before end of element. This cause "z-index stacked element problem." I believe that bootstrap .js do creation of this element wrong. If you have in mvc layout page, this script will cause still the same problem. Beter js idea cut be to get target modal id and inject this line to html before...

this.$backdrop = $(document.createElement('div'))
    .addClass('modal-backdrop ' + animate)
    .appendTo(this.$body)

SO SOLUTION IS repair bootstrap.js - part of modal:

.appendTo(this.$body)  
//REPLACE TO THIS:
 .insertBefore(this.$element) 

SOLUTION 2: add to your page this script:

$('.modal').appendTo("body")

Solution3:
Add to css:

.modal-backdrop{display:none;}
Miroslav Siska
  • 401
  • 4
  • 15