Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird jQuery date picker action

When I declare a datepicker with live, seems to work as expected until you change the month. Then instead of going to the next or previous month it skips back to January 1900 if you press forward month and December 1899 if you press back month.

using

$('.datepicker').live('focus', function () {
  $(this).datepicker('destroy').datepicker();
});

Any ideas?

Thanks

like image 806
Trevor Nowak Avatar asked Feb 13 '11 22:02

Trevor Nowak


3 Answers

I think a possible reason you are seeing the problem is, when you use focus to attach to the input, you are then destroying your datepicker and remaking one. However, when you click on your input, it runs, so destroys the datepicker, and shows one. However when you click next or previous, you will initially loose focus on the input, but the datepicker script will 'refocus' it and hence fires off the destroy and re-create a datepicker.

I assume you are using live to attach a datepicker to a dynamic input - you could always use $('.datepicker').not('.hasDatePicker').datepicker(); call in your success:...... callback of your ajax call, where I will assume, you are creating your new input. This will have the affect of adding a .datepicker() to any input item with the class datepicker which hasn't already had a .datepicker() added. (An input which has had a .datepicker() added to it, will also have the class hasDatePicker added to it)


An alternative method - keeping with the live call - which has pro's and con's

  • PRO: you only need it once in your code - instead of placing it several times if you have several ajax calls which may add several dynamic inputs.
  • CON: You are creating a much more resource hungry bit of code as it will run every time an input receives focus, instead of just applying the .datepicker() once.

So to keep with the live, you could do the following:

$('.datepicker').live('focus', function () {
    $(this).not('.hasDatePicker').datepicker();
});

See it in action here

This will attach a .datepicker() to any input with the class datepicker which hasn't already got a .datepicker() attached (class hasDatePicker), this should save you destroying and recreating all datepickers.

This will do the same as @Andrew Whitaker's solution

like image 161
Scoobler Avatar answered Oct 22 '22 17:10

Scoobler


I was able to reproduce your example, and I logged to the console every time focus was being handled and it looked like twice for every click on the input. I changed the event that live was handling to focusin and the problem goes away:

$('.datepicker').live('focusin', function () {
  $(this).datepicker('destroy').datepicker();
});

I'm still doing some digging to see what exactly is going on.

Edit: In the source for datepicker, there are several manual focus() calls, its probably one of these that's causing the problem.

Also, thanks to @Scoobler's comment below, the fix above won't work with jQuery 1.5, but seems to work for 1.4.4

Additionally, if your goal is to apply datepickers to elements added via AJAX, you might want to consider checking for existence of a datepicker and then apply the datepicker widget if it does not already exist:

$('.datepicker').live('focus', function () {
    if (!$(this).data("datepicker")) {
      $(this).datepicker();
    }
});
like image 25
Andrew Whitaker Avatar answered Oct 22 '22 18:10

Andrew Whitaker


$('.datepicker').datepicker('destroy');    
$('.datepicker').removeClass("hasDatepicker").removeAttr('id');    
$('.datepicker').datepicker({dateFormat: "yy-mm-dd"});

This will completely remove the datepicker and make a new one each time you click on the datepicker. This is mostly helpful for the datepicker on a dropdown. I also found this to be usefull for having multiple rows of items that have their own dates.

like image 22
justengel Avatar answered Oct 22 '22 19:10

justengel