I noticed a strange behavior with the jQuery datepicker onSelect method, you can take a look at this fiddle to test it.
Tested with jQuery 1.7.2 and jQuery UI 1.8.18, happens in Firefox, IE and Chrome.
Scenario:
- put the focus on the text field (the datepicker should appear)
- press enter to select the default date (as the datepicker API says it can be done)
- notice that onSelect is called twice.
Everything works fine if you select the date with the mouse.
Is this a bug? If not, how can I avoid this behaviour? Thanks for your help.
I noticed a strange behavior with the jQuery datepicker onSelect method, you can take a look at this fiddle to test it.
Tested with jQuery 1.7.2 and jQuery UI 1.8.18, happens in Firefox, IE and Chrome.
Scenario:
- put the focus on the text field (the datepicker should appear)
- press enter to select the default date (as the datepicker API says it can be done)
- notice that onSelect is called twice.
Everything works fine if you select the date with the mouse.
Is this a bug? If not, how can I avoid this behaviour? Thanks for your help.
Share Improve this question asked Jul 4, 2012 at 8:54 VirginieVirginie 9494 gold badges12 silver badges35 bronze badges 2-
I am on mac osx safari
Version 5.1.6
only one select ? hmmm – Tats_innit Commented Jul 4, 2012 at 8:56 - Yes, it is happening in my firefox 11.0. Not sure why. – Mohayemin Commented Jul 4, 2012 at 9:15
5 Answers
Reset to default 1I have a solution suggestion that is so ugly I'm half ashamed to post it. However, desparate times call for desperate measures.
var trigger = false;
var previousDate = "";
$("#datepicker").datepicker({
onSelect: function(dateText, inst) {
if (!trigger || (previousDate != dateText)) {
// Do whatever you want to do
alert("fire!");
// I decided to alert
trigger = true;
previousDate = dateText;
} else {
trigger = false;
}
}
});
Try something like this. I had a couple of minutes to test it and it seems to work. Improve on the idea if it doesn't.
I'll explain if you don't understand the awful, ugly idea behind the hack.
Cheers.
Yes you are right, even I got this error some time back but just neglected it. But this time i looked into the datepicker script where I found as it might be bug. This is reproducible in specific way only as you have mentioned
- Click on the field/ bring focus on it by using tab
- press enter
You will have callback function 'onSelect' called twice.
This is because in datepicker javascript, '_selectDate' function is used to get the selected date which is called from key event handler function(_doKeyDown()->_selectDay()->_selectDate()) and both functions invokes the call back function which seems to be bug.
Updates -
I have modified the _doKeyDown function in jquery.ui.datepicker.js file. I have modified the code when event is enter(keycode-13). So now callback function 'onSelect' is called once in above scenario.
Here is the code for version 1.8.21
_doKeyDown: function(event) {
var inst = $.datepicker._getInst(event.target);
var handled = true;
var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
inst._keyEvent = true;
if ($.datepicker._datepickerShowing)
switch (event.keyCode) {
case 9: $.datepicker._hideDatepicker();
handled = false;
break; // hide on tab out
case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
$.datepicker._currentClass + ')', inst.dpDiv);
//Update by Sunil start
if (sel[0]){
$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
}else{
$.datepicker._hideDatepicker();
return true;
}
//Update by Sunil end
return false;
break; // select the value on enter
case 27: $.datepicker._hideDatepicker();
break; // hide on escape
case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
-$.datepicker._get(inst, 'stepBigMonths') :
-$.datepicker._get(inst, 'stepMonths')), 'M');
break; // previous month/year on page up/+ ctrl
case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+$.datepicker._get(inst, 'stepBigMonths') :
+$.datepicker._get(inst, 'stepMonths')), 'M');
break; // next month/year on page down/+ ctrl
case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
handled = event.ctrlKey || event.metaKey;
break; // clear on ctrl or mand +end
case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
handled = event.ctrlKey || event.metaKey;
break; // current on ctrl or mand +home
case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
handled = event.ctrlKey || event.metaKey;
// -1 day on ctrl or mand +left
if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
-$.datepicker._get(inst, 'stepBigMonths') :
-$.datepicker._get(inst, 'stepMonths')), 'M');
// next month/year on alt +left on Mac
break;
case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
handled = event.ctrlKey || event.metaKey;
break; // -1 week on ctrl or mand +up
case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
handled = event.ctrlKey || event.metaKey;
// +1 day on ctrl or mand +right
if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+$.datepicker._get(inst, 'stepBigMonths') :
+$.datepicker._get(inst, 'stepMonths')), 'M');
// next month/year on alt +right
break;
case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
handled = event.ctrlKey || event.metaKey;
break; // +1 week on ctrl or mand +down
default: handled = false;
}
else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
$.datepicker._showDatepicker(this);
else {
handled = false;
}
if (handled) {
event.preventDefault();
event.stopPropagation();
}
},
I hope this would fix your problem.
Update 2 There is another workaround as answered by user1042031 but not plete solution. Here you will find what you need to do
$("#datepicker").datepicker({
onSelect: function(dateText,inst) {
$.datepicker._hideDatepicker();
inst.preventDefault();
}
});
You need to remove alert which causes to set focus on input field which will show datepicker again. This is call onSelect once for sure hiding the datepicker after pressing enter key.
DEMO
I am copying the part of solution just to have both working ways :)
Use
inst.preventDefault();
like this:
$("#datepicker").datepicker({
onSelect: function(dateText,inst) {
alert('s');
inst.preventDefault();
}
});
EDIT : to remove the calendar after selection of date
a work around is you need to use removeclass:
$( "#datepicker" ).datepicker({
onSelect: function(dateText, inst) {
$(inst.dpDiv).find('.ui-state-highlight.ui-state-hover').removeClass('ui-state-highlight ui-state-hover');
},
});
The best solution so far:
$("#datepicker").datepicker({
onSelect: function(dateText, inst) {
// do stuff
$.datepicker._hideDatepicker();
inst.preventDefault();
}
});
inst.preventDefault()
is the most important part: it prevents the double firing of onSelect()
. By using it, the datepicker doesn't hide anymore once the date is selected, so you have to call $.datepicker._hideDatepicker()
to do it.
Thanks to user1042031 and Sunil Chavan.
Seems like a bug to me... I've got this tied into all sorts of async calls and it's messing up everything... best solution I came up with is this:
jQuery(".date-picker").each(function (index, item) {
jQuery(item).removeClass("date-picker");
item.ondpchange = item.onchange;
jQuery(item).datepicker({
format: "mm/dd/yyyy",
autoclose: true,
todayHighlight: true,
}).on('changeDate', function (e) {
if (item.ondpchange != null) {
item.ondpchange();
}
});;
item.onchange = null;
});
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742346337a4426618.html
评论列表(0条)