javascript - jQuery UI datepicker: onSelect called twice - Stack Overflow

I noticed a strange behavior with the jQuery datepicker onSelect method, you can take a look at this fi

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:

  1. put the focus on the text field (the datepicker should appear)
  2. press enter to select the default date (as the datepicker API says it can be done)
  3. 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:

  1. put the focus on the text field (the datepicker should appear)
  2. press enter to select the default date (as the datepicker API says it can be done)
  3. 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
Add a ment  | 

5 Answers 5

Reset to default 1

I 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

相关推荐

  • javascript - jQuery UI datepicker: onSelect called twice - Stack Overflow

    I noticed a strange behavior with the jQuery datepicker onSelect method, you can take a look at this fi

    3小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信