web-dev-qa-db-fra.com

Pourquoi datepicker de jQuery UI rompt-il avec un DOM dynamique?

Je travaille ici avec un DOM dynamique et ai appelé le datepicker de l'interface utilisateur jQuery à toutes les entrées ayant un nom de classe spécifique, dans ce cas .date

Cela fonctionne très bien avec la première construction statique, mais lorsque je la clone, les gestionnaires d'événements ne semblent pas vouloir se déplacer. Je reçois l'erreur Firebug:

inst est indéfini

J'ai essayé d'examiner la nouvelle fonction live() de jQuery, mais je ne pouvais pas combiner les deux. Des idées?

31
Will Morgan

Ah, j'ai compris. Immédiatement après avoir ajouté le code HTML au DOM, je l’utilise sur toutes les entrées pour lesquelles je souhaite faire apparaître un sélecteur de date. Datepicker ajoute une classe aux éléments auxquels elle a été attachée afin de pouvoir filtrer les entrées existantes et de l'appliquer uniquement aux nouvelles.

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

J'espère que cela aide les gens, car je cherchais sur Google pendant des jours sans rien trouver!

Vous devez également noter qu'il serait plus rapide de rechercher input.date dans le nouveau code HTML généré en le définissant comme un contexte plutôt que pour la page entière, car cela vous fera gagner du temps, car cette opération est plus efficace.

38
Will Morgan

J'ai eu un problème similaire, j'avais plusieurs tables sur une page et chacun avait plusieurs datepickers, également en cliquant sur le bouton "AddLine" il a ajouté une ligne de table avec HTML dynamique et datepicker.

Après de nombreuses recherches, je me suis rendu compte que mes champs de date d'entrée n'avaient pas d'identifiant défini. Ils ressemblaient à ceci. 

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

jquery pointait toutes les valeurs de champs de date sur le tout premier champ de date défini sur la page, le calendrier s'afficherait sur tous les champs de date mais la valeur du 1er champ de date changerait 

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

en ajoutant un "id" et cela a commencé à fonctionner, pour les champs de date dynamiques, je change l'identifiant comme ceci

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"));
            }
        });
6
Richipal

Vous devez utiliser l'événement 'live' pour le faire fonctionner avec un DOM dynamique. Donc, si la classe pour vos entrées datepicker est 'date-input', le code suivant le fera fonctionner:

$(document).ready(function() {
    $('.date-input').live('click', function() {
    $(this).datepicker('destroy').datepicker({showOn:'focus'}).focus();
        });
});
4
Tommy

Utilisation 

$j(id or class).removeClass('hasDatepicker').datepicker();

Ça fonctionne 

3
kishore

C'est peut-être un peu tard, mais toutes les suggestions ci-dessus n'ont pas fonctionné pour moi, j'ai trouvé une solution facile pour cela.

Tout d’abord, la cause du problème: JQuery attribue datepicker à l’élément id. si vous clonez un élément, le même identifiant peut également être cloné. ce que jQuery n'aime pas. Vous pourriez vous retrouver avec une erreur de référence null ou la date attribuée au premier champ de saisie, quel que soit le champ de saisie sélectionné.

Solution:

1) détruit le sélecteur de date 2) attribue de nouveaux identifiants uniques à tous les champs de saisie 3) attribue un sélecteur de date pour chaque entrée

Assurez-vous que votre entrée est quelque chose comme ça

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

Avant de cloner, détruisez datepicker

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

Après avoir cloné, ajoutez également ces lignes

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

et la magie arrive

3
EGN

Utilisez les sélecteurs jQuery:

$(".mydatepicker:not(.hasDatepicker)").datepicker()
2
Quaternion

Plusieurs occurrences de la bibliothèque jquery-ui sur la page entraîneront également cette erreur. La suppression d'instances redondantes fonctionne pour mon cas

1
Anh Nguyen

Après avoir essayé plusieurs des réponses ici, c’est ce qui a fonctionné pour moi et qui s’affiche dès le premier clic/focus

function vincularDatePickers() {
    $('.mostrar_calendario').live('click', function () {
        $(this).datepicker({ showButtonPanel: true, changeMonth: true, changeYear: true, showOn: 'focus' }).focus();
    });
}

il faut que votre entrée ait la classe 'mostrar_calendario'

live est pour JQuery 1.3+ pour les versions plus récentes, vous devez l’adapter à "on"

En savoir plus sur la différence ici http://api.jquery.com/live/

Aujourd'hui, j'ai rencontré le même problème ... J'utilise datetimepicker plugin dans mon application.
Utilise également le sélecteur de date par défaut de jquery. Chaque fois que je les invoque tous deux sur un document prêt, je reçois le message d'erreur inst is undefined.

    $(document).ready(function(){
        $(".datepickerCustom").datetimepicker();
        $(".datepicker").datepicker();
        $("#MainForm").validationEngine('attach');
        ....
    });

J'ai donc changé le code à appeler avant que le document soit prêt comme ci-dessous:

    $(".datepickerCustom").datetimepicker();
    $(".datepicker").datepicker();
    $(document).ready(function(){
        $("#MainForm").validationEngine('attach');
        ....
    });

Maintenant tout fonctionne bien. Pas de problème.

0
vissu

J'ai eu un problème similaire avec le sélecteur de données ne fonctionnant pas après un premier appel. J'ai trouvé une réponse à mon problème ici:

http://www.stemkoski.com/problem-with-jquery-ui-datepicker-dynamic-dom/

Je clonais des sections de manière dynamique à partir d'un modèle et incluais par inadvertance la classe que datepicker ajoutait une fois appelée: 

hasDatepicker

J'ai placé mon premier appel datepicker après avoir cloné le modèle, ce qui l'a fait. J'ai ensuite ajouté un appel datepicker après chaque instance de clone:

$(source).clone().appendTo(destination).find(".datepicker").datepicker();
0
Vlad

J'ai eu le même symptôme, causé par un élément contenant td avec le même attribut id que l'entrée,

 <td id="fld_xyz"><input id="fld_xyz" class="date" /></td>

Je sais que ce n’est pas idéal, mais il faut savoir que le composant datepicker semble s’appuyer sur le caractère unique de l’id.

0
Stephen Francis

Si cela ne fonctionne toujours pas, c'est à cause de l'ID cloné. Vous pouvez supprimer complètement datepicker comme ceci: 

$(selector).removeClass('hasDatepicker').removeAttr('id').datepicker();
0
Octavian Vladu

J'ai eu ce problème. Ma situation a fini par être que j'avais un autre élément avec le même identifiant que l'entrée avec le sélecteur de date.

0
Scott K