274

I have a JS code in which when you change a field it calls a search routine. The problem is that I can't find any jQuery events that will fire when the Datepicker updates the input field.

For some reason, a change event is not called when Datepicker updates the field. When the calendar pops up it changes the focus so I can't use that either. Any ideas?

1

19 Answers 19

414

You can use the datepicker's onSelect event.

$(".date").datepicker({
    onSelect: function(dateText) {
        console.log("Selected date: " + dateText + "; input's current value: " + this.value);
    }
});

Live example:

$(".date")
.datepicker({
    onSelect: function(dateText) {
        console.log("Selected date: " + dateText + "; input's current value: " + this.value);
    }
})
.on("change", function() {
    console.log("Got change event from field");
});
<link href="https://code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<input type='text' class='date'>
<script src="https://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>

Unfortunately, onSelect fires whenever a date is selected, even if it hasn't changed. This is a design flaw in the datepicker: It always fires onSelect (even if nothing changed), and doesn't fire any event on the underlying input on change. (If you look in the code of that example, we're listening for changes, but they aren't being raised.) It should probably fire an event on the input when things change (possibly the usual change event, or possibly a datepicker-specific one).


If you like, of course, you can make the change event on the input fire:

$(".date").datepicker({
    onSelect: function() {
        $(this).change();
    }
});

That will fire change on the underlying input for any handler hooked up via jQuery. But again, it always fires it. If you want to only fire on a real change, you'll have to save the previous value (possibly via data) and compare.

Live example:

$(".date")
.datepicker({
    onSelect: function(dateText) {
        console.log("Selected date: " + dateText + "; input's current value: " + this.value);
        $(this).change();
    }
})
.on("change", function() {
    console.log("Got change event from field");
});
<link href="https://code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<input type='text' class='date'>
<script src="https://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>

Sign up to request clarification or add additional context in comments.

13 Comments

@user760092: I posted this answer and then went out, and literally as I was leaving I thought "You know, you could trigger the change handler(s)" and so I've updated the answer with that. :-)
I've gone round and round in circles trying to go get this to work in all scenarios and this has done it! Much appreciated!
Why in the world didn't they make those actual events?
@AndroidDev: I've clarified that. (You could have, of course; the goal of the site is to have good answers; respectful editing to achieve that is encouraged.) It's a design flaw in the datepicker, not in the answer. (What it should do is fire a change event of some kind on the input, if and only if changing the date, but it doesn't.)
or if the date picker has already been initialized use $(".date").datepicker('option', 'onSelect', function() { $(this).change(); } );
|
83

T.J. Crowder's answer is very good and still remains accurate. Triggering the change event within the onSelect function is as close as you're going to get.

However, there is a nice property on the datepicker object (lastVal) that will allow you to conditionally trigger the change event only on actual changes without having to store the value(s) yourself:

$('#dateInput').datepicker({
     onSelect: function(d,i){
          if(d !== i.lastVal){
              $(this).change();
          }
     }
});

Then just handle change events like normal:

$('#dateInput').change(function(){
     //Change code!
});

7 Comments

Has anyone tested this recently? It doesn't work for me. i.lastVal returns undefined and it doesn't appear to be one of the available properties.
I just implemented this with no issue at all. Works like a charm.
this doesn't work anymore, lastval is no longer defined
@luke_mclachlan lastVal however is ;-)
lastVal does not exist on the datepicker object, at least in my testing. So this solution will always trigger the change.
|
15

Your looking for the onSelect event in the datepicker object:

$('.selector').datepicker({
   onSelect: function(dateText, inst) { ... }
});

Comments

13
$('#inputfield').change(function() { 
    dosomething();
});

5 Comments

I thought this should work, but unfortunately not. It's only triggered when the field is changed using the keyboard, not when selecting from the date-picker. Annoying.
From the jQuery UI docs: "This widget manipulates its element's value programmatically, therefore a native change event may not be fired when the element's value changes."
The funny thing is that I am getting the opposite of that - when I change the input by hand via keyboard, no event is triggered. But when I change the value of the field through the widget, the change event gets fired. Odd.
This works fine when I change with keyboard and when I change with the date picker widget.
somehow this calls multiple times .
13

I wrote this because I needed a solution to trigger an event only if the date changed.

It is a simple solution. Each time the dialog box closes we test to see if the data has changed. If it has, we trigger a custom event and reset the stored value.

$('.datetime').datepicker({
    onClose: function(dateText,datePickerInstance) {
        var oldValue = $(this).data('oldValue') || "";
        if (dateText !== oldValue) {
            $(this).data('oldValue',dateText);
            $(this).trigger('dateupdated');
        }
    }
});

Now we can hook up handlers for that custom event...

$('body').on('dateupdated','.datetime', function(e) {
    // do something
});

3 Comments

I am using this with knockout, I could not get it to trigger an event when the user deleted or manually changed the date without selecting a date on the picker. Very helpful.
My issue with jQuery datepicker fields is not exactly the same as the one posted here. It is about the change event firing multiple times. I tried several solutions and this is the only one that actually works in my situation.
I did more or less the same as this solution and I think it definitely works the best. I will post what I did in a separate answer...
11

I am using bootstrap-datepicker and none of above solution worked for me. This answer helped me:

bootstrap datepicker change date event doesnt fire up when manually editing dates or clearing date

Here is what I applied:

 $('.date-picker').datepicker({
     endDate: new Date(),
     autoclose: true,
 }).on('changeDate', function(ev){
        //my work here
    });

Comments

5

Try:

$('#idPicker').on('changeDate', function() {
    var date = $('#idPicker').datepicker('getFormattedDate');
});

Comments

5

I couldn't get the jQuery $(this).change() event to fire correctly onSelect. So I went with the following approach to fire the change event via vanilla JavaScript.

$('.date').datepicker({
     showOn: 'focus',
     dateFormat: 'mm-dd-yy',
     changeMonth: true,
     changeYear: true,
     onSelect: function() {
         var event;
         if(typeof window.Event == "function"){
             event = new Event('change');
             this.dispatchEvent(event);
         }   else {
             event = document.createEvent('HTMLEvents');
             event.initEvent('change', false, false);
             this.dispatchEvent(event);
         }
     }
});

4 Comments

Error "'$' is undefined" for this snippet. Uh oh.
You're dispatching a change event in the onSelect event which isn't quite the desired effect since select will fire each time a date is clicked but it doesn't necessarily mean the date was actually changed i.e. the user might have clicked the same date twice.
@Jacques you are correct. i believe you could compare String dateText to this.value and only fire this if they are different.
@Michael12345 i see what you mean. i have modified it so that its no longer a snippet. my apologies.
4

Try this:

$('#dateInput').datepicker({
 onSelect: function(){
       $(this).trigger('change');
      }
 }});

Comments

4

On jQueryUi 1.9 I've managed to get it to work through an additional data value and a combination of beforeShow and onSelect functions:

$( ".datepicker" ).datepicker({
    beforeShow: function( el ){
        // set the current value before showing the widget
        $(this).data('previous', $(el).val() );
    },
    
    onSelect: function( newText ){
        // compare the new value to the previous one
        if( $(this).data('previous') != newText ){
            // do whatever has to be done, e.g. log it to console
            console.log( 'changed to: ' + newText );
        }
    }
});

Comments

1

Manual says:

apply.daterangepicker: Triggered when the apply button is clicked, or when a predefined range is clicked

So:

$('#daterange').daterangepicker({
  locale: { cancelLabel: 'Clear' }  
});

$('#daterange').on('apply.daterangepicker', function() {
  alert('worked!');
});

Works for me.

Comments

1

I think your problem may lie in how your datepicker is setup. Why don't you disconnect the input... do not use altField. Instead explicitly set the values when the onSelect fires. This will give you control of each interaction; the user text field, and the datepicker.

Note: Sometimes you have to call the routine on .change() and not .onSelect() because onSelect can be called on different interactions that you are not expecting.

Pseudo Code:

$('#date').datepicker({
    //altField: , //do not use
    onSelect: function(date){
        $('#date').val(date); //Set my textbox value
        //Do your search routine
    },
}).change(function(){
    //Or do it here...
});

$('#date').change(function(){
    var thisDate = $(this).val();
    if(isValidDate(thisDate)){
        $('#date').datepicker('setDate', thisDate); //Set my datepicker value
        //Do your search routine
    });
});

Comments

1

My solution:

var $dateInput = $('#dateInput');

$dateInput.datepicker({
    onSelect: function(f,d,i){
        if(d !== i.lastVal){
            $dateInput.trigger("change");
        }
    }
}).data('datepicker');

$dateInput.on("change", function () {
   //your code
});

Comments

0

DatePicker selected value change event code below

/* HTML Part */
<p>Date: <input type="text" id="datepicker"></p>

/* jQuery Part */
$("#datepicker").change(function() {
                selectedDate= $('#datepicker').datepicker({ dateFormat: 'yy-mm-dd' }).val();
                alert(selectedDate);        
            });

Comments

0

My solution is:

events: {
    'apply.daterangepicker #selector': 'function'
}

1 Comment

Does not apply to jQuery UI Datepicker, which is the topic of this question. Also, doesn't mention for which random javascript library this is intended for.
0

You can use the onClose option for the datepicker and put your change code inside. This triggers when the datepicker modal is closed. I tried to trigger the change event but that wouldn't work so I put my code inside of the onClose instead and it works. The same may work for onSelect that was mentioned if you need to trigger when the date is selected.

$('#el').datepicker({ 
   onClose: function () {
     // code here
   }
});

Datepicker options https://api.jqueryui.com/datepicker/

Comments

0

If you are using wdcalendar this going to help you

 $("#PatientBirthday").datepicker({ 
        picker: "<button class='calpick'></button>",
        onReturn:function(d){
          var today = new Date();
          var birthDate = d;
          var age = today.getFullYear() - birthDate.getFullYear();
          var m = today.getMonth() - birthDate.getMonth();
          if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
            age--;
          }

          $('#ageshow')[0].innerHTML="Age: "+age;
          $("#PatientBirthday").val((d.getMonth() + 1) + '/' + d.getDate() + '/' +  d.getFullYear());
        }
      }); 

The event onReturn works for me.

Comments

0

Some of you may be using something called XDSoft DateTimePicker.

There, the change event is onSelectDate:

onSelectDate: function(){
  alert('change date event);
}

2 Comments

This question is about the jQuery UI DatePicker component. I know there are answers here about many other plugins, but those should really be in separate questions that are tagged appropriately.
I came here thinking I was using jQuery UI DatePicker because they look exactly the same, .datetimepicker({..}). Only through browsing the answers did I discover my plugin was actually a different one, similar to Bootstrap. So this is a valid post.
-1

This approach is simple and works everytime with textbox control:

$('#controlID').on('changeDate', function() {
               $(this).change();
    });

1 Comment

"works everytime"... IF AND ONLY if you happen to be using some datepicker component that generates some custom "changeDate" event. You don't mention which one you use. jQuery UI Datepicker, which this question is about, does not have such an event.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.