IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Ma variable reste indéfinie


Sujet :

JavaScript

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut Ma variable reste indéfinie
    Bonjour,
    J'ai le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    "use strict";
     
    const mainForm = document.querySelector('form')
    	, inputDates = mainForm.querySelectorAll("input[name*='_date']")
    	;
     
    var cal = new jsSimpleDatePickr()
    	, inputId
    	;
     
    mainForm.call_date.focus(); // Par défaut
     
    mainForm.source_date.addEventListener('focus', function(e) {
    	inputId = mainForm.source_date.id;
    }, false );
     
    mainForm.request_date.addEventListener('focus', function(e) {
    	inputId = mainForm.request_date.id;
    }, false );
     
    mainForm.offer_date.addEventListener('focus', function(e) {
    	inputId = mainForm.offer_date.id;
    	console.log('29: '+inputId);
    }, false );
     
    mainForm.call_date.addEventListener('focus', function(e) {
    	inputId = mainForm.call_date.id;
    	alert(inputId);
    }, false );
     
    console.log('31: '+inputId);
    Dans ce code et dans la mesure où ma variable est déclarée avant les écouteurs, je ne comprends pas pourquoi la ligne 31 renvoie toujours undefined malgré le focus par défaut.
    Remarques:
    Le focus par défaut ligne 11 déclenche bien l'écouteur correspondant (ligne 26) avec affichage du nom du champ
    La variable inputDates est prévue pour optimiser mon code, mais je ne vois pas comment.

  2. #2
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    Les callbacks de tes écouteurs sont exécutés après la ligne 31.

    Si tu initialises ta variable inputId avec 'toto' par exemple, tu verras qu'elle vaudra 'toto' à la ligne 31.
    Un problème avec Git ? Essayez la FAQ, sinon posez votre question sur le forum.



    "Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
    Kenneth E. Boulding

    "Les richesses naturelles sont inépuisables, car, sans cela, nous ne les obtiendrions pas gratuitement. Ne pouvant être ni multipliées ni épuisées, elles ne sont pas l’objet des sciences économiques."
    Jean-Baptiste Say, Traité d'économie politique, 1803.

    "/home/earth is 102% full ... please delete anyone you can."
    Inconnu

  3. #3
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    Bonjour,

    peut-être un problème lié au html, à la construction du formulaire?

  4. #4
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    Oui, Marco46!

    Les déclarations de variables sont traitées avant que le code soit exécuté, quel que soit leur emplacement dans le code
    - https://developer.mozilla.org/fr/doc...structions/var

    C'est valable pour les déclarations avec var, en tout cas;

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    Oui, vous m'avez appris quelque chose mais alors comment faire pour que la variable soit affectée par les écouteurs avant la suite du code et la fonction CalAdd ne doit être exécuté qu'une fois mais je dois juste mettre à jour le inputFieldId. Je vous donne le code entier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // Gestion du calendrier pour les champs dates
    // http://blog.niap3d.com/jsSimpleDatePickr
    // Nouvelle version 2.1
     
    "use strict";
     
    const mainForm = document.querySelector('form');
     
    var cal = new jsSimpleDatePickr()
    	, inputId
    	;
     
    mainForm.source_date.addEventListener('focus', function(e) {
    	inputId = mainForm.source_date.id;
    }, false );
     
    mainForm.request_date.addEventListener('focus', function(e) {
    	inputId = mainForm.request_date.id;
    }, false );
     
    mainForm.offer_date.addEventListener('focus', function(e) {
    	inputId = mainForm.offer_date.id;
    }, false );
     
    mainForm.call_date.addEventListener('focus', function(e) {
    	inputId = mainForm.call_date.id;
    }, false );
     
    //<![CDATA[
    cal.CalAdd({
    'divId': 'calendar',
    'inputFieldId': inputId,
    'dateMask': 'JJ/MM/AAAA',
    'dateCentury': 20,
    'titleMask': 'M AAAA',
    'navType': '11',
    'classTable': 'jsCalendar',
    'classDay': 'day',
    'classDaySelected': 'selectedDay',
    'monthLst': fromPHPtoJS.monthes,
    'dayLst': fromPHPtoJS.shortDays,
    'hideOnClick': false,
    'showOnLaunch': true
    });
    //]]>
    La fonction CalAdd n'est pas de moi et dans cette fonction, je ne comprends pas à quoi correspondent //<![CDATA[ et //]]>.

  6. #6
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Salut,

    <![CDATA ]]> pour isoler un script du reste de la page. Les plus vieux navigateurs avaient effectivement tendance à parser les symboles < et > des codes javascript comme des balises, ce qui provoquait des erreurs et a poussé à utiliser des commentaires standards HTML <!-- --> à l'intérieur des balises <script>, et surtout pas <![CDATA ]]>.

    En revanche il faut utiliser <![CDATA ]]>dans un document XML contenant du Javascript. C'est le cas des pages XHTML servies avec un content-type application xhtml/xml (qui sont très rares car la spécification HTML5 a fait concurrence avec XHTML1.1 auprès des utilisateurs, et car les versions d'Internet Explorer disponibles à l'époque du XHTML n'étaient pas capable de parser un document HTML servi en XML).

    Concernant l'utilisation multiple de jsSimpleDatePickr, j'ai bien cherché sur google pour trouver au moins une bonne documentation, mais sans succès...

    Dans l'exemple ci-dessous, on met un seul conteneur pour plusieurs input, puis on modifie le paramètre inputFieldId de l'objet myCalendar.jsSDPObj[0] lors de focus et après on appelle la fonction CalDoFromField :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    <!doctype html>
    <html lang="fr">
    <head>
    	<meta charset="utf-8" />
    	<title>Simple Date Picker</title>
    	<link href="https://blog.niap3d.com/calendrier-javascript/css/default_blue.css" rel="stylesheet"/>
    	<script type="text/javascript"  src="https://blog.niap3d.com/calendrier-javascript/js/jsSimpleDatePickr.2.11.js"!></script>
    </head>
    <body>
    	<form id="myForm">
    		<input name="source_date" id="source_date" class="date" />
    		<input name="request_date" id="request_date" class="date"  />
    		<input name="offer_date" id="offer_date" class="date" />
    		<input name="call_date" id="call_date" class="date" />
    	</form>
     
    	<div id="calendar-wrapper" class="calendarMain"></div>
     
    	<script type="text/javascript">
                    var myCalendar= new jsSimpleDatePickr()
                    ,inputId
                    ,mainForm = document.querySelector('form')
                    ,inputs=document.forms[mainForm.id].getElementsByClassName('date');
                    for(let i=0;i<inputs.length;i++){
                            inputs[i].addEventListener('focus',function(e){
                                    inputId = this.id;
                                    myCalendar.jsSDPObj[0]["inputFieldId"]=inputId;
                                    myCalendar.CalDoFromField(inputId,"toogle");//passer le inputId en paramètre + le paramètre "toogle" ==> affiche/masque le datepicker
                                    console.log('jsSDPObj :',myCalendar.jsSDPObj[0],', inputId :',inputId);
                            },false);
                    }
                    myCalendar.CalAdd({
                            'divId': "calendar-wrapper",
                            'inputFieldId':"source_date",//par défaut
                            'dateMask': 'JJ/MM/AAAA',
                            'dateCentury': 20,
                            'titleMask': 'M AAAA',
                            'navType': '01',
                            'classTable': 'jsCalendar',
                            'classDay': 'day',
                            'classDaySelected': 'selectedDay',
                            'monthLst': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
                            'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
                            'hideOnClick': true,
                            'showOnLaunch': false,
                            "callBack":function(date){console.log(' (callback) date :',date);}
                    });
     
            </script>
    </body>
    </html>

    Le seul problème qui te reste, c'est de positionner le conteneur #calendar-wrapper en dessus/dessous de l'input concerné, et ça je pense que tu peux le faire avec javascript...

  7. #7
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Citation Envoyé par Toufik83 Voir le message
    [...]
    Concernant l'utilisation multiple de jsSimpleDatePickr, j'ai bien cherché sur google pour trouver au moins une bonne documentation, mais sans succès...
    [...]


    Je n'ai rien trouvé de plus récent que :

    2017 : https://blog.niap3d.com/calendrier-javascript/
    2014 : https://blog.niap3d.com/fr/4,10,news...t-gratuit.html

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  8. #8
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    Il reste encore deux points à régler, mais ton code correspond à ce que j'avais imaginé mais avais été incapable de réaliser. J'étais déjà entré dans le code du datepicker sans être capable de bien l'utiliser. Donc déjà un premier grand merci. J'ai modifié quelques lignes et paramètres pour m'adapter à ma configuration et avoir un affichage permanent.
    Il reste deux défauts:
    • Lorsque je clique sur le premier champ (qu'il soit ou non le champ par défaut), le calendrier disparaît malgré le paramètre 'show' de CalDoFromField().
    • La date s'initialise toujours au 20 juin 1908. Elle devrait s'initialiser, soit à la date du jour lorsque le champ est vide, soit à la valeur du champ lorsqu'il y en une.


    Il semblerait que le problème réside entre les lignes 71, 72 et 83 et la fonction CalDateInit mais je n'arrive pas à résoudre le problème.
    Pour info, j'ai suggéré à deux reprises à l'auteur d'établir une documentation ( voir son blog )
    Dans des configurations plus classiques, j'utilise régulièrement sans difficultés ce datepicker depuis 2017.

  9. #9
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Citation Envoyé par danielhagnoul Voir le message
    -ha!, le premier lien je l'ai trouvé, mais le deuxième (qui est beaucoup mieux documenté) non.
    Merci @danielhangoul.
    Citation Envoyé par moimp
    Lorsque je clique sur le premier champ (qu'il soit ou non le champ par défaut), le calendrier disparaît malgré le paramètre 'show' de CalDoFromField().
    Si tu veux que le datepicker reste visible, tu n'a qu'à remplacer "toogle" par "show" dans CalDoFromField (mais le problème c'est qu'il garde toujours la dernière date):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myCalendar.CalDoFromField(inputId,"show");
    Citation Envoyé par moimp
    La date s'initialise toujours au 20 juin 1908. Elle devrait s'initialiser, soit à la date du jour lorsque le champ est vide, soit à la valeur du champ lorsqu'il y en une.
    Ben non, la date s'initialise à la date d'aujourd'hui quand la zone est vide et elle s'initialise à la date du champ quand ce dernier n'est pas vide.
    Pièce jointe 492341

    Sinon et si tu veux utiliser jQuery, il existe un bon widget jQuery UI datepicker...

  10. #10
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    @Toufik83:
    En ce qui concerne le widget, il semble intéressant et bien documenté mais j'hésite à l'utiliser car mon site est en voie d'achèvement et qu'il utilise plusieurs instances de jsSimpleDatePickr. D'autre part, je ne suis pas très à l'aise avec jQuery, encore moins qu'avec JavaScript natif.

    EDIT 1: Pour l'affichage initial, j'ai simplement une erreur sur le masque de date.

    EDIT 2: Il me reste le problème de disparition de l'affichage du calendrier.

  11. #11
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Essaies ça :

    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #calendar-wrapper{position:absolute;width:auto;}

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    var myCalendar= new jsSimpleDatePickr()
    		,inputId
    		,mainForm = document.querySelector('form')
    		,inputs=document.forms[mainForm.id].getElementsByClassName('date')
    		,Aujourdhui=new Date();
     
    		for(let i=0;i<inputs.length;i++){
    			inputs[i].addEventListener('focus',function(e){
    				inputId = this.id;
    				myCalendar.jsSDPObj[0]["inputFieldId"]=inputId;
    				myCalendar.jsSDPObj[0].dateSel=this.value.trim()!=""
    					?new Date(this.value.split("/").reverse())
    					:new Date(Aujourdhui.getFullYear(),Aujourdhui.getMonth(),Aujourdhui.getDate());
                                    myCalendar.jsSDPObj[0].dateDisp=myCalendar.jsSDPObj[0].dateSel;//obligatoire si on change de mois...
    				myCalendar.CalDoFromField(inputId,"show");
    				document.getElementById("calendar-wrapper").style.top=(this.getBoundingClientRect().top+this.clientHeight+10)+"px";
    				document.getElementById("calendar-wrapper").style.left=this.getBoundingClientRect().left+"px";
    			},false);
    		}
    		myCalendar.CalAdd({
    			'divId': "calendar-wrapper",
    			'inputFieldId':"date1",
    			'dateMask': 'JJ/MM/AAAA',
    			'dateCentury': 20,
    			'titleMask': 'M AAAA',
    			'navType': '01',
    			'classTable': 'jsCalendar',
    			'classDay': 'day',
    			'classDaySelected': 'selectedDay',
    			'monthLst': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
    			'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
    			'hideOnClick': true,//true ici pour masquer le datepicker après le clic sur une date
    			'showOnLaunch': false,
    			"callBack":function(date){console.log(' (callback) date :',date);}
    		});

  12. #12
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    Bonjour et surtout merci pour le temps que tu me consacres.
    J'ai viré ton css car je veux que le calendrier soit affiché en permanence et au même endroit. ça c'est bon.
    Pour le fonctionnement, on y est presque. Il reste un petit souci au niveau de la sélection de la date.
    Sans cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myCalendar.jsSDPObj[0].dateDisp=myCalendar.jsSDPObj[0].dateSel; //obligatoire si on change de mois...
    En l'absence de date (champ vide), c'est bien la date du jour qui s'affiche. Par contre, lorsque le champ est renseigné, aucune date n'est sélectionnée. J'ai analysé les lignes 12 à 14 de ton code et je ne vois pas d'erreur. La console me donne bien les bonnes valeurs.

    Avec cette même ligne, j'obtiens un undefined NaN à la place de la ligne de titre (mois et année) et le tableau des jours est vide.

  13. #13
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Salut,

    Tu as surement un truc différent dans ton code que je n'arrives pas à cibler, parce que j'ai testé le code sous chrome,opera et firefox avant de le poster.

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <form id="myForm">
      <input name="source_date" id="source_date" class="date" />
      <input name="request_date" id="request_date" class="date" />
      <input name="offer_date" id="offer_date" class="date" />
      <input name="call_date" id="call_date" class="date" />
    </form>
     
    <div id="calendar-wrapper" class="calendarMain"></div>

    Code jQuery : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    var myCalendar = new jsSimpleDatePickr(),
      inputId, mainForm = document.querySelector('form'),
      inputs = document.forms[mainForm.id].getElementsByClassName('date'),
      Aujourdhui = new Date();
     
    for (let i = 0; i < inputs.length; i++) {
      inputs[i].addEventListener('focus', function(e) {
        inputId = this.id;
        myCalendar.jsSDPObj[0].inputFieldId = inputId;
        myCalendar.jsSDPObj[0].dateSel = this.value.trim() != "" 
           ?
          new Date(this.value.split("/").reverse()) :
          new Date(Aujourdhui.getFullYear(), Aujourdhui.getMonth(), Aujourdhui.getDate());
        myCalendar.jsSDPObj[0].dateDisp = myCalendar.jsSDPObj[0].dateSel;
        myCalendar.CalDoFromField(inputId, "show");
      }, false);
    }
    myCalendar.CalAdd({
      'divId': "calendar-wrapper",
      'inputFieldId': "date1",
      'dateMask': 'JJ/MM/AAAA',
      'dateCentury': 20,
      'titleMask': 'M AAAA',
      'navType': '01',
      'classTable': 'jsCalendar',
      'classDay': 'day',
      'classDaySelected': 'selectedDay',
      'monthLst': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
      'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
      'hideOnClick': true,
      'showOnLaunch': false,
      "callBack": function(date) {
        console.log(' (callback) date :', date);
      }
    });

  14. #14
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    En recopiant ton code sans rien modifier, j'ai toujours le même problème. Donc j'abandonne l'idée de n'avoir qu'un calendrier pour toutes mes dates.

    Je me suis donc inspirer de ton code pour tout réécrire mais quelque soit le réglage des paramètres hideOnClick et showOnLaunch l'affichage est très aléatoire: Parfois j'affiche plusieurs calendriers en dessous les uns des autres pour la même date, parfois il faut cliquer deux fois sur le champ pour obtenir l'affichage. D'autres fois, je n'arrive pas du tout à obtenir un affichage, malgré plusieurs clics. Dans une application précédente, j'avais ajouté ce script pour effacer le calendrier en cliquant à l'extérieur du champ mais je n'arrive pas à le transposer pour plusieurs dates:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	document.addEventListener('click', function(e) {
    		if ( e.target.name != 'ma_date' && e.target.name != '' )  cal.CalDoFromField('ma_date', 'hide');
    	}, false );
    Voici mon nouveau code avec tous les inconvénients d'affichage mentionnés plus hauts.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    // Gestion du calendrier pour les champs dates
    // http://blog.niap3d.com/jsSimpleDatePickr
    // Nouvelle version 2.1
     
    "use strict";
     
    (function()
    {
     
    	var myCalendar	= new jsSimpleDatePickr()
    		,inputId
    		,divId
    		,mainForm	= document.querySelector('form')
    		,inputs		= mainForm.querySelectorAll("input[name*='_date']")
    		,params
    	;
     
    	for(let i=0, max=inputs.length; i<max; i++)
    	{
    		inputs[i].addEventListener('focus',function(e)
    		{
    			inputId = this.id;
    			divId	= inputId.substring(0, inputId.indexOf('_')) + 'Calendar';
    			console.log(divId)
    			console.log(inputId);
    			params	= {
    				'divId': divId,
    				'inputFieldId': inputId,
    				'dateMask': 'JJ/MM/AAAA',
    				'dateCentury': 20,
    				'titleMask': 'M AAAA',
    				'navType': '11',
    				'classTable': 'jsCalendar',
    				'classDay': 'day',
    				'classDaySelected': 'selectedDay',
    				'monthLst': fromPHPtoJS.monthes,
    				'dayLst': fromPHPtoJS.shortDays,
    				'hideOnClick': true,
    				'showOnLaunch':true
    			};
    			myCalendar.CalAdd(params);
    		},false);
    	}
     
    	document.addEventListener('click', function(e) {
    		for(let i=0, max=inputs.length; i<max; i++)
    		{
    			console.log('target='+e.target.name);
    			console.log('input name='+inputs[i].name);
    			if ( e.target.name != inputs[i].name && e.target.name != '' ) myCalendar.CalDoFromField(inputs[i].name, 'hide');
    		}
    	}, false );
     
    }) ();

  15. #15
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Salut,

    Si tu as toujours le même problème en local alors que ça fonctionne nickel dans l'exemple en ligne, dans ce cas il faudrait comprendre pourquoi ça n'a pas fonctionné au lieu de changer de méthode.

    Est-ce que tu utilises le même fichier jsSimpleDatePicker que celui que j'ai mis sur jsfiddle (https://blog.niap3d.com/calendrier-j...ePickr.2.11.js), t'en es sûr ?

  16. #16
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    Bonjour,

    Mon changement de mode d'affichage du calendrier est essentiellement motivé par le côté ergonomique de ton CSS, avec un positionnement absolu. Il est vrai que j'en ai aussi ras le bol de buter sur ce problème qu'on arrive pas à résoudre. Ce sont deux raisons d'abandonner l'affichage unique au profit d'un affichage plus classique pour chaque champ. Mais sur le principe tu as raison.

    J'ai quand même essayé de charger la nouvelle version 2.11 mais elle me pose des problèmes d'encodage d'une part (je n'arrive pas à déceler l'encodage d'origine et à le convertir en UTF-8) et d'autre part je ne vois pas de différence entre la version 2.1 et 2.11. Il y a quelque chose de pas très clair à ce niveau là.

    Je sais que j'abuse mais est-ce que tu peux regarder mon nouveau code et le problème d'affichage.

  17. #17
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Salut,

    Ce n'est pas Mon CSS qui pose problème, mais c'est la propriété position absolute que tu n'arrives pas à gérer, probablement parce que tu n'as pas appliqué une position relative au parent...

    Concernant les versions, je viens d'importer la 2.1 et tout fonctionne normal, je ne comprends pas pourquoi ça ne fonctionne pas pour toi.

    D'après le script, l'auteur à déjà attaché un eventListener "click" aux zones de texte, si on regarde la fonction me.CalAdd on voit bien la ligne 21
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dateEl.addEventListener('click', function(){ me.CalDoFromField(data.inputFieldId, 'toogle'); }, false);
    , donc l'idée d'attacher encore un événement "focus" n'est pas bonne.

    J'ai vu ton code, et la fonction CalDoFromField accepte 2 paramètres, le id de l'input (pas le name) et une action (show/hide/toogle) mais le grand problème n'est pas là, c'est le faite d'attacher un eventListener "click" au document pour masquer tous les datepickers, ce qui va les masquer aussi lorsqu'on clic sur les flèches pour modifier le mois ou l'année.

    Je voulais essayé d'utiliser event.stopPropagation() mais impossible de l'appliquer avec la capture "false" de eventListener, et si on essaie de changer la capture en "true", stopPrppagation fonctionne mais le datepicker ne s'affiche pas

    Concernant l'encodage, tu n'en as pas besoin si tu veux utiliser le fichier localement, il faut seulement modifier les valeurs des inputs Mois/Année avec les caractères spéciaux (« ,») pour l'année et (‹ , ›) pour le mois.

    J'ai réussi à faire cet exemple Avec la version 2.1, et je l'ai testé biensûr et ça fonctionne :

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    <form>
      Date 1:<input name="source_date" id="source_date" />
      <div id="source_dateCalendar" class="calendarMain"></div>
     
      Date 2:<input name="request_date" id="request_date" />
      <div id="request_dateCalendar" class="calendarMain"></div>
     
      Date 3:<input name="offer_date" id="offer_date" />
      <div id="offer_dateCalendar" class="calendarMain"></div>
     
      Date 4:<input name="call_date" id="call_date" />
      <div id="call_dateCalendar" class="calendarMain"></div>
     
    </form>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    "use strict";
    (function() {
      let myCalendar = new jsSimpleDatePickr(),
        mainForm = document.querySelector('form'),
        inputs = mainForm.querySelectorAll("input[name*='_date']"),
        params;
     
      for (let i = 0; i < inputs.length; i++) {
        params = {
          'divId': inputs[i].id + "Calendar",
          'inputFieldId': inputs[i].id,
          'dateMask': 'JJ/MM/AAAA',
          'dateCentury': 20,
          'titleMask': 'M AAAA',
          'navType': '11',
          'classTable': 'jsCalendar',
          'classDay': 'day',
          'classDaySelected': 'selectedDay',
          'monthLst': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai',
            'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre',
            'Novembre', 'Décembre'
          ],
          'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
          'hideOnClick': false,
          'showOnLaunch': false,
          "callBack": function(date) {
            console.log(' date cliquée :', date);
          }
        };
        myCalendar.CalAdd(params);
     
      }
      document.addEventListener("click", function(e) {
        let node = e.target.nodeName.toLowerCase();
        console.log("target.nodeName :", node);
        if (node != "input" && node != "td") {
          for (let i = 0; i < inputs.length; i++) {
            myCalendar.CalDoFromField(inputs[i].id, "hide");
          }
        }
      }); //capture false est déjà par défaut
      console.log('myCalendar :', myCalendar);
    })();
    La ligne 37
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (node != "input" && node != "td")
    consiste à déterminer le nodeName de l'élément sur lequel on a cliqué, !="input" pour ne pas cacher le calendrier au moment de clic sur les flèches mois/année, et !="td" pour ne pas le cacher lors d'un clic sur une date. (tu peux utiliser les classes pour mieux contrôler ça...)

  18. #18
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    En gros, ça fonctionne, sauf deux points:
    • Il y avait une erreur sur le nom du div que j'ai corrigé.
    • Le masquage des calendriers si on clique en dehors du champ ou du calendrier.

    Citation Envoyé par Toufik83 Voir le message
    Ce n'est pas Mon CSS qui pose problème, mais c'est la propriété position absolute que tu n'arrives pas à gérer, probablement parce que tu n'as pas appliqué une position relative au parent...
    Non, au contraire, tu m'as mal compris, la position absolue est une bonne idée et c'est elle qui m'a fait changé d'avis sur la méthode à utiliser.

    Citation Envoyé par Toufik83 Voir le message
    D'après le script, l'auteur à déjà attaché un eventListener "click" aux zones de texte, si on regarde la fonction me.CalAdd on voit bien la ligne 21
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dateEl.addEventListener('click', function(){ me.CalDoFromField(data.inputFieldId, 'toogle'); }, false);
    , donc l'idée d'attacher encore un événement "focus" n'est pas bonne.
    Merci pour cette explication.

    Citation Envoyé par Toufik83 Voir le message
    J'ai vu ton code, et la fonction CalDoFromField accepte 2 paramètres, le id de l'input (pas le name) et une action (show/hide/toogle) mais le grand problème n'est pas là, c'est le faite d'attacher un eventListener "click" au document pour masquer tout les datepickers, ce qui va les masquer aussi lorsqu'on clic sur les flèches pour modifier le mois ou l'année.
    J'ai utilisé le name à la place de l'id car ils sont identiques. C'était volontaire. Le masquage de tous les calendriers a été vu avec l'auteur mais n'a jamais été bien vu. Le principe est qu'on ne doit toucher ni au champ en cours, ni au calendrier associé.

    Citation Envoyé par Toufik83 Voir le message
    Je voulais essayé d'utiliser event.stopPropagation() mais impossible de l'appliquer avec la capture "false" de eventListener, et si on essaie de changer la capture en "true", stopPrppagation fonctionne mais le datepicker ne s'affiche pas
    C'est une chose que j'avais déjà vu précédemment.

    Citation Envoyé par Toufik83 Voir le message
    J'ai réussi à faire cet exemple Avec la version 2.1, et je l'ai testé bien sûr et ça fonctionne :
    ... code ...
    Et c'est là que je te dois un grand, grand remerciement.

    Citation Envoyé par Toufik83 Voir le message
    La ligne 38
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (target != "input" && target != "td")
    consiste à déterminer le nodeName de l'élément sur lequel on a cliqué, !="input" pour ne pas cacher le datepicker au moment de clic sur les flèches mois/année, et !="td" pour ne pas cacher le datepicker lors d'un clic sur une date. (tu peux utiliser les classes pour mieux contrôler ça...)
    Il me reste à affiner ce dernier point et voir pourquoi il ne fonctionne pas avec "use strict".

  19. #19
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 433
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 433
    Points : 4 923
    Points
    4 923
    Par défaut
    Citation Envoyé par moimp Voir le message
    Il me reste à affiner ce dernier point et voir pourquoi il ne fonctionne pas avec "use strict".
    Tu n'as pas d'erreur dans la console en cliquant dehors du calendrier ?

    Avec "use strict" il faut déclarer les variables avec let ou var même dans les boucles, dans ton cas il faut écrire la boucle comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for (let i = 0,max=inputs.length;i < max; i++)
    ou bien directement sans "max" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for (let i = 0;i<inputs.length;i++)
    Ou bien avec "of"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for (let elem of inputs) {
    	myCalendar.CalDoFromField(elem.id, "hide");
    }

  20. #20
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 590
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 590
    Points : 813
    Points
    813
    Par défaut
    J'ai fini par avoir un code définitif qui marche avant de lire ton dernier message car je suis au point sur l'écriture des boucles, sauf pour le of que je n'utilise pas car il est incompatible avec IE.
    Mon code fonctionne parce que les éléments du calendrier ne sont pas nommés.
    Pour info, voici mon code complet.
    Il fonctionne à la perfection sur IE11. Sur Chrome, le masquage fonctionne si je clique sur un autre input ou si je clique sur un div mais il ne fonctionne pas si je clique dans une zone vide d'un fieldset. J'ai ajouté un stopPropagation mais rien ne change. Je n'ai pas testé sur les autres navigateurs. Comme dans l'ensemble, ce n'est pas très grave, je n'ai pas approfondi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    "use strict";
     
    (function(){
     
    let myCalendar = new jsSimpleDatePickr()
    	,mainForm = document.querySelector('form')
    	,inputs = mainForm.querySelectorAll("input[name*='_date']")
    	,max	= inputs.length
    	,params
    	;
     
    for (let i = 0; i < max; i++) {
    	let inputId = inputs[i].id;
    	params = {
    		'divId': inputId.substring(0, inputId.indexOf('_')) + 'Calendar',
    		'inputFieldId': inputId,
    		'dateMask': 'JJ/MM/AAAA',
    		'dateCentury': 20,
    		'titleMask': 'M AAAA',
    		'navType': '11',
    		'classTable': 'jsCalendar',
    		'classDay': 'day',
    		'classDaySelected': 'selectedDay',
    		'monthLst': fromPHPtoJS.monthes,
    		'dayLst': fromPHPtoJS.shortDays,
    		'hideOnClick': false,
    		'showOnLaunch': false
    	};
    	myCalendar.CalAdd(params);
    }
     
    document.addEventListener("click", function(e) {
    	let target = e.target.name;
     
    	for (let i=0; i<max; i++)
    	{
    		if (target != inputs[i].name && target != '')
    		{
    			myCalendar.CalDoFromField(inputs[i].id, "hide");
    		}
    	}
    });
     
    }) ();

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Variable POST indéfinie
    Par Mickael2604 dans le forum Langage
    Réponses: 6
    Dernier message: 02/03/2010, 07h11
  2. Valeur variable reste inchangée
    Par gator dans le forum Langage
    Réponses: 4
    Dernier message: 18/11/2009, 19h05
  3. [HTML] Variable ${theme_images} indéfinie
    Par kahya dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 20/05/2008, 10h30
  4. Réponses: 3
    Dernier message: 25/10/2007, 10h25
  5. [4D 2004.5/MacOSX.4] Variable système indéfinie ?
    Par Jean-Marc JULES dans le forum 4D
    Réponses: 8
    Dernier message: 26/02/2007, 08h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo