Opened 6 years ago

Closed 6 years ago

#10569 closed bug (duplicate)

Incorrect z-index position of Datepicker in some cases

Reported by: yauheni Owned by:
Priority: minor Milestone: none
Component: ui.datepicker Version: 1.11.1
Keywords: Cc:
Blocked by: Blocking:

Description

Hello.

This bug is related to modal windows, when I use Bootstrap Modal v2.2.5 library https://github.com/jschr/bootstrap-modal.

Bootstrap Modal v2.2.5 extends Twitter Bootstrap's (http://getbootstrap.com) native modals (http://getbootstrap.com/javascript/#modals) to provide additional functionality.

I've got this bug on:
OS: Windows Vista Home Basic 32 bit, browser - Opera Next version 23.0.1522.75
OS: Windows 7 Enterprise 64 bit, browser - Mozilla Firefox version 31.0

I assign Datepicker widget for simple input in modal window and when I try to show Datepicker, it displays behind modal window:

http://www.fotohost.by/pic_b/14/08/28/f75203b5e545ebaa9f734de071854299.jpg

Source code of this example (or see on jsFiddle http://jsfiddle.net/bazk8mns/):

<!doctype html>
<html>
<head>
  <title>Bootstrap-modal by jschr</title>
  <!-- Bootstrap core CSS -->
  <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- Bootstrap-modal plugin -->
  <link href="http://jschr.github.io/bootstrap-modal/css/bootstrap-modal-bs3patch.css" rel="stylesheet">
  <link href="http://jschr.github.io/bootstrap-modal/css/bootstrap-modal.css" rel="stylesheet">
  <!-- jQuery UI -->
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
</head>
<body>
  <button class="demo btn btn-primary btn-lg" data-toggle="modal" href="#responsive">View Demo</button>
    
<!-- Modal Definition -->
<div id="responsive" class="modal fade" tabindex="-1" data-width="760" style="display: none;">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h4 class="modal-title">Responsive</h4>
  </div>
  <div class="modal-body">
    <div class="row">
      <div class="col-md-6">
        <h4>Some Input</h4>
        <p><input class="form-control" type="text" id="datepicker"/></p>
      </div>
    </div>
  </div>
  <div class="modal-footer">
    <button type="button" data-dismiss="modal" class="btn btn-default">Close</button>
    <button type="button" class="btn btn-primary">Save changes</button>
  </div>
</div>

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
<!-- Bootstrap-modal plugin -->
<script src="http://jschr.github.io/bootstrap-modal/js/bootstrap-modalmanager.js"></script>
<script src="http://jschr.github.io/bootstrap-modal/js/bootstrap-modal.js"></script>
<!-- jQuery UI -->
<script src="http://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>

<script>
  $(function() {
    $( "#datepicker" ).datepicker();
  });
</script>

  </body>
</html>

At that moment HTML-code looks like this (pay attention to style="z-index" rules):

<div id="ui-datepicker-div" 
	class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" 
	style="position: fixed; top: 0px; left: 277px; z-index: 1051; display: block;">
	... Datepicker's HTML-code
</div>
<div class="modal-scrollable" style="z-index: 1060;">
	<div id="responsive" class="modal fade in" tabindex="-1" data-width="760" 
		style="display: block; width: 760px; margin-left: -379px; margin-top: -117px;" aria-hidden="false">
		... modal's HTML-code  
	</div>
</div>
<div class="modal-backdrop fade in" style="z-index: 1050;">
</div>

CSS class ".modal" has rule:

.modal {
    ...
    z-index: 1050;
    ...
}

This means modal window has z-index equals 1050, but modal's parent DIV has z-index equals 1060!

The cause of the incorrect z-index of Datepicker is lazy algorithm in function datepicker_getZindex( elem ):

function datepicker_getZindex( elem ) {
	var position, value;
	while ( elem.length && elem[ 0 ] !== document ) {
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
		// This makes behavior of this function consistent across browsers
		// WebKit always returns auto if the element is positioned
		position = elem.css( "position" );
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
			// IE returns 0 when zIndex is not specified
			// other browsers return a string
			// we ignore the case of nested elements with an explicit value of 0
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
			value = parseInt( elem.css( "zIndex" ), 10 );
			if ( !isNaN( value ) && value !== 0 ) {
				return value;
			}
		}
		elem = elem.parent();
	}

	return 0;
}

I improved this function, and now it implements greedy algorithm (and Datepicker widget always have top position):

function datepicker_getZindex( elem ) {
	var position, value, zIndexMax = 0;
	while ( elem.length && elem[ 0 ] !== document ) {
		// Ignore z-index if position is set to a value where z-index is ignored by the browser
		// This makes behavior of this function consistent across browsers
		// WebKit always returns auto if the element is positioned
		position = elem.css( "position" );
		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
			// IE returns 0 when zIndex is not specified
			// other browsers return a string
			// we ignore the case of nested elements with an explicit value of 0
			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
			value = parseInt( elem.css( "zIndex" ), 10 );
			if ( !isNaN( value ) && value !== 0 && value > zIndexMax) {
				zIndexMax = value;
			}
		}
		elem = elem.parent();
	}

	return zIndexMax;
}

P.S. Sorry, my English is bad :)

Change History (1)

comment:1 Changed 6 years ago by Scott González

Resolution: duplicate
Status: newclosed

Duplicate of #9013.
Datepicker is in the process of being rewritten and the new version will follow our standard logic for stacking elements. This change is covered by #9013. You'll be able to make this work via the appendTo option at that time.

Last edited 6 years ago by Scott González (previous) (diff)
Note: See TracTickets for help on using tickets.