I can't seem to show a datepicker from jQuery UI on a hidden field as I get this error:
Uncaught TypeError: Cannot read property 'left' of undefined
When I use a regular text field, I don't seem to have a problem. I get this error with both jQuery UI 1.9.0
and 1.9.2
, the version of jQuery is 1.8.3
html
<table>
<tr>
<td>
<small class="date_target">until <span>Dec. 31, 2013</span></small>
<input type="hidden" class="end_date" />
</td>
</tr>
</table>
JS
$(".end_date").datepicker({
dateFormat: 'yyyy-mm-yy',
yearRange: '-00:+01'
});
$('.date_target').click(function () {
$(this).next().datepicker('show');
});
I provided a (not) working example on this jsfiddle too
Let's check datepicker _findPos function
$.datepicker._findPos = function (obj) {
var position,
inst = this._getInst(obj),
isRTL = this._get(inst, "isRTL");
while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.visible(obj))) {
obj = obj[isRTL ? "previousSibling" : "nextSibling"];
}
position = $(obj).offset();
/*because position of invisible element is null, js will break on next line*/
return [position.left, position.top];
};
If target obj of datepicker is invisible, it will use the closest sibling position which is not invisible
There are several solutions:
Solution 1
Because of LTR, you can exchange position of two element
<tr>
<td>
<input type="hidden" class="end_date" />
<small class="date_target">until <span>Dec. 31, 2013</span></small>
</td>
</tr>
Solution 2
Add an visible element next to the hidden element, so datepicker will find the visible element position
<tr>
<td>
<small class="date_target">until <span>Dec. 31, 2013</span></small>
<input type="hidden" class="end_date" /><span> </span>
</td>
</tr>
Solution 3
Redefine _findPos function, so you can set position of calendar wherever you want
$.datepicker._findPos = function (obj) {
var position,
inst = this._getInst(obj),
isRTL = this._get(inst, "isRTL");
while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.visible(obj))) {
obj = obj[isRTL ? "previousSibling" : "nextSibling"];
}
position = $(obj).offset();
// if element type isn't hidden, use show and hide to find offset
if (!position) { position = $(obj).show().offset(); $(obj).hide();}
// or set position manually
if (!position) position = {left: 999, top:999};
return [position.left, position.top];
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With