可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm 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
回答1:
It's because the input field is not visible to the browser (because it's hidden).
Try this:
<input type="text" style="height: 0px; width:0px; border: 0px;" class="end_date" />
and you are fine. Of course, you can add the extra style attributes to the CSS class "end_date". A "display:none" will not help, because then the field is fully invisible again.
Example also in a JS Fiddle.
回答2:
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]; };
回答3:
I had the same problem while using Bootstrap as well, cause I needed my datepicker to show with a button click.
This works:
<div class="form-group"> <label class="sr-only" for="txtDate">Date</label> <input type="text" class="form-control input-sm" style="display: none;" id="txtDate"> <button type="button" class="btn btn-default btn-sm" id="btnDate"> <span class="glyphicon glyphicon-calendar"></span> Calendar </button> </div>
This doesn't work:
<div class="form-group"> <label class="sr-only" for="txtDate">Date</label> <input type="text" class="form-control input-sm" style="display: none;" id="txtDate"> </div> <button type="button" class="btn btn-default btn-sm" id="btnDate"> <span class="glyphicon glyphicon-calendar"></span> Calendar </button>
JS:
$('#txtDate').datepicker({ dateFormat: 'yy-mm-dd', showAnim: 'fade' }); $("#btnDate").on('click', function(){ $('#txtDate').datepicker('show'); });
So all I needed was to put the button on the same div element. In case anyone else has this problem.