web-dev-qa-db-fra.com

Conflit avec deux datepickers jquery sur la même page

Voici donc la configuration: J'ai deux datepickers jquery, dans un onglet jquery, dans une fenêtre de dialogue modale jquery:

\---/\---/\---/_______________
/                            /
\                            \
/  DATEPICKER1               /
\                            \
/  DATEPICKER2               /
\                            \
/                            /
\                            \
/____________________________/

Le premier datepicker fonctionne normalement, mais lorsque j'essaie de cliquer sur une date dans le deuxième datepicker, il active simplement la première. Avez-vous suivi cela? :)

Donc pour résumer, cliquer sur une date dans datepicker2 active datepicker1.

Je ne sais pas pourquoi cela se produit - ils ont des identifiants et des noms différents, comme indiqué ci-dessous.

Pour créer les sélecteurs de date que j'utilise simplement:

$(function() {
    $("#datepicker1").datepicker();
    $("#datepicker2").datepicker();
});

Les champs sont simplement:

<input type="text" id="datepicker1" name="datepicker1" value="" />
<input type="text" id="datepicker2" name="datepicker2" value="" />

J'utilise jQuery v1.9.0 et jQueryui v1.10.0.

Des idées à ce sujet? En guise de mise en garde, je ne peux pas publier le code réel en raison des restrictions imposées par mon employeur, mais je peux répondre à la plupart des questions si vous avez besoin de précisions. Toute aide, d'où qu'elle vienne, sera très appréciée!!

22
musicmunky

UPDATE: Il semble que le problème décrit ci-dessous ait été traité dans une autre question de stackoverflow:
Empêche la boîte de dialogue jQuery UI de définir le focus sur la première zone de texte

Toutes mes excuses pour la question "dupliquer" - si j'avais su que c'était le problème, je l'aurais compris rapidement !!!

################################################# ################################

Eh bien, la résolution est très simple, et peut-être que quelqu'un peut m'expliquer pourquoi cela fonctionne de cette façon parce que je suis un peu désemparé pour le moment.

Voici ce que j'ai fait:
J'ai ajouté deux autres champs de saisie au formulaire (ils étaient nécessaires) et réorganisé la mise en page de sorte qu'un de ces nouveaux champs de saisie constitue le "premier" élément (dans le coin supérieur gauche), comme suit:

\---/\---/\---/_______________
/                            /
\                            \
/  TEXTFIELD1   DATEPICKER1  /
\                            \
/  TEXTFIELD2   DATEPICKER2  /
\                            \
/                            /
\                            \
/____________________________/

Soudain, le problème a disparu! Cependant, je remarque un comportement intéressant:
Lorsque je sélectionne une date dans soit le datepicker, le curseur revient immédiatement au premier champ de texte . Si cela se produisait alors que j'avais les sélecteurs de date sans champs de texte, cela signifierait que le curseur immédiatement sur le premier datepicker qui aurait pu causer le problème que j’avais.

Maintenant, quant à POURQUOI cela fonctionne de cette façon, je n'en ai aucune idée. J'ai essayé de définir les paramètres tabindex pour les différents champs de saisie de texte/sélecteurs de date, mais cela n'a pas changé le comportement.

Quoi qu’il en soit, j’apprécie la contribution de tous ceux qui ont réagi: c’était un problème étrange, mais je n’oublierai jamais comment le résoudre. Merci à tous pour votre aide!!

9
musicmunky

Essayez cet ami: Dans votre JS

 $(function() {   
       $( "#from" ).datepicker({   
      defaultDate: "+1w",  
      changeMonth: true,   
      numberOfMonths: 1,  
      onClose: function( selectedDate ) {  
        $( "#to" ).datepicker( "option", "minDate", selectedDate );  
      }  
    });  
    $( "#to" ).datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 1,
      onClose: function( selectedDate ) {
        $( "#from" ).datepicker( "option", "maxDate", selectedDate );
      }
    });  
  });  
  
	<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css"/>
 <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
Start date: <input type="text" id="from" name="from"> 
End date: <input type="text" id="to" name = "to">

Dans votre entrée

Date de début: type d'entrée = "text" id = "de" name = "de" 

Date de fin: type d'entrée = "text" id = "to" name = "to"

Cela a fonctionné pour moi :)

par MacElie M.

4
McElie

Je pense que vous avez un autre code qui interfère avec le javascript comme This: http://jsfiddle.net/fMD62/

fonctionne parfaitement (avec jquery 1.9.1 et jqueryui 1.9.2

peut-être essayer

$(function() {
    $("#datepicker1,#datepicker2").datepicker();
});
3
Stanislas Nichini

C'est une prise totale dans le noir, mais avez-vous essayé d'initialiser chacun séparément? Quelque chose comme ce qui suit

$(function() {
    $('.datepicker').each(function(){
        $(this).datepicker();
    });
});

C'est probablement ce que les autres ont mentionné et vous rencontrez une certaine forme d'interférence avec votre code, mais ça vaut le coup.

1
Tom Yeldham

Dans votre exemple, les deux datepickers ont des identifiants et des noms différents. Cependant, le problème que vous décrivez est exactement ce qui se passera si vous utilisez le même nom pour les deux.

Votre code actuel utilise-t-il un identifiant et un nom différents pour les deux datepickers?

1
Bardo

Juste pour commencer, je suis un programmeur de base de données backend, donc je ne connais que très peu JavaScript. Nous avons donc cherché à trouver ce message avec exactement la même question. En se basant sur ce que j'ai lu ci-dessus et en comparant avec mon code existant, j'ai modifié mon JavaScript pour qu'il fonctionne et j'ai pensé le partager.

Le seul inconvénient était que mes formulaires existants avec des sélecteurs de date uniques ne fonctionnaient plus, j'ai donc dû en ajouter un peu pour gérer ceux-ci et tout semble bien aller maintenant. Dans ce cas, les champs de la base de données sont en fait un horodatage Unix. Le formulaire est donc traité lorsqu'il est soumis avec les deux champs convertis selon les besoins, mais pour plus de clarté, je n'ai pas inclus ce code ici.

$(document).ready(function(){ 
       $( "#StartDate" ).datepicker({   
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {  
        $( "#StartDate" ).datepicker( "option", "minDate", selectedDate );  
      }  
    });  
    $( "#EndDate" ).datepicker({
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {
        $( "#EndDate" ).datepicker( "option", "maxDate", selectedDate );
      }
    }); 
        $( "#datepicker" ).datepicker({
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {
        $( "#datepicker" ).datepicker( "option", "maxDate", selectedDate );
      }
    });     
  });
0
DonP

Cas 1:
Le commentaire de @ antony (y compris le lien jsfiddle en dessous de la question) fonctionne à partir de
version jquery-1.9.1 et 1.9.2/jquery-ui.js

Cas 2:
Le cas d'OP où datepicker1 fonctionne bien mais où choisir datepicker2 ouvrira datepicker1
version: jQuery v1.9.0 et jQueryui v1.10.0

Cas 3:
Mon cas où choisir datepicker1 fonctionne bien mais choisir datepicker2 n’a aucun effet.
version: jquery-3.1.1.min.js et jQueryui v1.12.1

Cas 3 solution:
initialise date1 en premier $('date1').datepicker() date1
Pour date2, commencez par détruire date1 puis initialisez date2. 

$('date1').datepicker('destroy');
$('date2').datepicker();

Maintenant pour date1, détruisez date2 et initialisez date1.

0
vusan

Essayez de placer le contenu de la boîte de dialogue JQuery UI dans un IFrame. Cela pourrait vous aider à résoudre certains de vos problèmes. 

\---/\---/\---/_______________
/                            /
\  ####IFRAME######          \
\  #              #          \
/  #DATEPICKER1   #          /
\  #              #          \
/  #DATEPICKER2   #          /
\  #              #          \
/  ################          /
\                            \
/____________________________/
0
Robert Bolton

EXPLICATION du problème

J'ai le même problème et c'est très décevant… .. J'ai cherché dans le code source de jQuery et j'ai trouvé ceci:

if ( $.ui.dialog.overlayInstances ) {
    this._on( this.document, {
        focusin: function( event ) {
            if ( !$( event.target ).closest(".ui-dialog").length ) {
                event.preventDefault();
                $(".ui-dialog:visible:last .ui-dialog-content")
                    .data("ui-dialog")._focusTabbable();
            }
        }
    });
}

Ainsi, lorsque vous définissez le focus dans un élément qui ne se trouve pas dans le .ui-dialog, il déclenche la fonction _focusTabbable() qui définit le focus sur la première entrée de la boîte de dialogue.

Le problème est que $.datepicker crée div à la fin du corps - donc en dehors de .ui-dialog

S'il y a une autre entrée sur laquelle _focusTabbable() donnera le focus, ok, car datepicker peut le gérer. Mais si cette entrée est liée à datepicker, elle fermera la datepicker précédente, en ouvrira une autre à la première entrée et la sélection sur la datepicker précédente ne sera pas déclenchée.

Une des solutions possibles

La solution est dans ce cas d'avoir une entrée qui aura le premier focus dans la boîte de dialogue sans datepicker.

J'utilise simplement ce code HTML comme première entrée au début du contenu de la boîte de dialogue. Sinon, l'entrée de datepicker sera à la première place:

<span class="ui-helper-hidden-accessible"><input type="text" /></span>
0
Gh61