I'm trying to dynamically size a field on the screen, but unfortunately we are using IE quirks mode. Chrome is behaving perfectly and everything is lining up exactly how I expect, however in IE8 under quirks mode the calculated size is causing the last element on the screen to wrap to the next line. I really, really want to avoid the wrapping to the next line, but ideally I would like the rendered output to look like it does in Chrome.
Chrome:
IE:
Part of the issue is that the 'dateentry' div is in a table cell, which is stretched to 100%. Before the resize happens, this causes the div to stretch to the table cell size. We don't want that, instead we want the div to be as large as it's own content. As a result, I am writing a javascript function to resize the div according to it's content.
How can I improve my width calculation under IE without breaking Chrome? Why is the size incorrect in IE?
<!-- QUIRKS MODE AHOY! -->
<!-- DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" -->
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<style>
.datefield {
display: inline-block;
padding: 1px;
margin-left: 2px;
border: solid 1px gray;
background: #FFF;
white-space: nowrap;
}
.datefield * {
position: relative;
display: block;
float: left;
margin: 0;
border: 0;
padding: 0;
}
.datefield input {
width: 1.8em;
margin: 0 1px;
font-family: inherit;
background: none;
}
.datefield div {
display: inline-block !important;
width: 5px;
margin-left: 1px;
margin-right: 1px;
}
.datefield .month-mmm {
width: 2.6em;
}
.datefield .year-yyyy {
width: 2.7em;
}
.datefield input:focus {
outline: none;
}
.datefield-error {
background-color: red;
}
.datefield-error input {
background-color: none;
color: white;
}
</style>
<script type="text/javascript">
var logging = false;
var resize = function( parent ) {
// find the border, margin and padding of the div element.
// var width = this.$el.outerWidth(true) - this.$el.width();
var width = 0;
// add up the width of the inner elements including the elements margin.
$.each( parent.children(), function() {
// Having tried using .is(':visible') and failed, I went for the simpler, is display 'none' or not.
if ( $(this).css('display') != 'none' ) {
if ( logging ) console.log( $(this).outerWidth(true), $(this).get(0) );
var w = $(this).outerWidth(true);
width += w;
}
} );
if ( logging ) console.log(width);
if ( logging ) console.log('-----------------------------------------------------');
parent.width(width);
};
$(document).ready( function() {
resize( $('#dateentry') );
} );
</script>
</head>
<body>
<table width="100%">
<tr>
<td>
<div id="dateentry" class="datefield" datepicker="true" minute="" hour="" year="" month="" date="" format="datetime">
<input style="display: block" id=date_value maxLength=2 placeholder="DD" edit="true" view="true" min="1" max="31" maxlength="2">
<div>/</div>
<input id="month_view" class="month-mmm" maxLength="3" placeholder="MMM" edit="false" view="true" maxlength="3">
<input style="display: none" id=month_value class=month-mmm maxLength=2 placeholder="MM" edit="true" view="false" min="1" max="12" maxlength="2">
<div>/</div>
<input style="display: block;" id="year_value" class=year-yyyy maxLength=4 aa_="0" placeholder="YYYY" edit="true" view="true" min="1900" max="2100" maxlength="4">
<div> </div>
<input style="display: none; visibility: hidden" id="datepicker" class="hasDatepicker" type="hidden">
<img style="zoom: 1" class="ui-datepicker-trigger" title="..." alt="..." src="http://jqueryui.com/resources/demos/datepicker/images/calendar.gif" width="16" height="15">
</div>
</td>
</tr>
</table>
</body>
</html>
It feels a bit hacky (because it is), but I decided to use the height to determine if the item was rendered correctly. It's not very nice and I think there could be a number of pitfalls, but it appears to be working for me currently.
I was able to determine if using quirks mode (IE only) by checking if jQuery is using the box model. Then it was simply a case of adding a while loop until the target height was returned.
var resize = function( parent ) {
parent.width('auto');
var targetHeight = parent.outerHeight(true);
var width = 0;
// add up the width of the inner elements including the elements margin.
$.each( parent.children(), function() {
// Having tried using .is(':visible') and failed, I went for the simpler, is display 'none' or not.
if ( $(this).css('display') != 'none' ) {
var w = $(this).outerWidth(true);
width += w;
}
} );
parent.width( width );
// add an arbitrary amount to the size of the field.
while( !jQuery.support.boxModel && parent.outerHeight(true) > targetHeight ) {
width += 1;
parent.width( width );
}
};