Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does jQuery UI's datepicker break with a dynamic DOM?

I'm working with a dynamic DOM here, and have called the jQuery UI datepicker to all inputs with a specific class name, in this case .date

It works great with the first, static, construct but when I clone it the event handlers don't seem to want to move over. I get the Firebug error:

inst is undefined

I tried looking into jQuery's new live() function but couldn't combine the two. Any ideas?

like image 618
Will Morgan Avatar asked Jun 29 '09 16:06

Will Morgan


4 Answers

Ah, got it. Right after I append the HTML to the DOM I run this on all the inputs I'd like to have a datepicker pop up with. Datepicker adds a class to elements it has been attached to, so we can filter out existing inputs and only apply it to new ones.

$('.date').not('.hasDatePicker').datepicker();

I hope this helps people as I was Googling for days and didn't find anything!

You should also note that it would be faster to check for input.date in the new generated HTML by setting that as a context, rather than the whole page, as it will save time, due to this being a more efficient operation.

like image 51
Will Morgan Avatar answered Oct 30 '22 12:10

Will Morgan


I had a similar Issue, I had multiple tables on a page and each had multiple datepickers, also on click of button "AddLine" it added a table row with dynamic HTML and datepicker.

I realized after a lot of search that my input date fields had no "id" defined they looked like this

<input type="text" class="datepicker" name="mDate1" value="" size=8 >

jquery was pointing all the date fields values to the very first date field defined on page, the calendar would popup on all the date fields but the value of 1st date field would change, I made a change to the html like this

<input type="text" class="datepicker" id="Date1" name="mDate1" value="" size=8 >

by adding a "id" and it started working, for the dynamic date fields I change the Id like this

var allColumns = $("#"+$tableId+" tr:last td"); 
        $(allColumns).each(function (i,val) {
            if($(val).find(":input").hasClass("datepicker")){
                $(val).find(":input").attr("id",newId+$(val).find(":input").attr("id"));
            }
        });
like image 42
Richipal Avatar answered Oct 30 '22 12:10

Richipal


You need to use the 'live' event to make it work with dynamic DOM. So, if the class for your datepicker inputs is 'date-input', following code will make it work:

$(document).ready(function() {
    $('.date-input').live('click', function() {
    $(this).datepicker('destroy').datepicker({showOn:'focus'}).focus();
        });
});
like image 4
Tommy Avatar answered Oct 30 '22 11:10

Tommy


This might be a little late, but all the suggestions above didn't work for me, I came up with an easy solution for this.

First, what is causing the problem: JQuery assign datepicker to element id. if you are cloning element, then same id might be cloned as well. which jQuery doesn't like. You might end up with either receiving null reference error or the date being assigned to first input field regardless which input field you click on.

Solution:

1) destroy datepicker 2) assign new unique ids to all input field 3) assign datepicker for each input

Make sure your input is something like this

<input type="text" name="ndate[]" id="date1" class="n1datepicker">

Before you clone, destroy datepicker

$('.n1datepicker').datepicker('destroy');

After you clone, add these lines as well

var i = 0;
$('.n1datepicker').each(function () {
    $(this).attr("id",'date' + i).datepicker();
    i++;
});

and the magic happens

like image 4
EGN Avatar answered Oct 30 '22 11:10

EGN