Commentaires sur l'article Calendrier javascript gratuit : jsSimpleDatePickr v2

J'aimerai indiquer un bug et proposer une amélioration
1) le BUG
Sur le code généré par ta page, le moi d'Avril ressort comme undefined dans le code généré (surement un nom de champ erroné dans le formulaire qui propose les noms des mois)

2) J'ai trouvé pratique de changer dans le code le mask d'affichage : 'dateMask' pour le format de la date retournée (AAAA-MM-JJ par exemple). Mais ce serai sympa que ce mask s'applique aussi sur la date d'entrée ( dans me.CalDateInit )

Voilà, merci beaucoup pour ton code qui ma simplifié la vie, GG

Jo Melnik à 11h59

1) Le bug est corrigé

2) C'est prévu, c'est à ça que servira la variable dateMask. Elle fonctionnera dans les deux sens ;-)

Merci pour le retour.

Patrice à 12h22

Bonjour, super fonction.

J'ai un petit problème avec son utilisation.
J'aimerai l'utiliser sur deux input différent mais quand je l'appel avec deux inputFieldId et divId différent il fonctionne très bien sauf si je change d'année.

Lors de ce changement dans la deuxième input la valeur cliqué sur le cal remplace la valeur du premier.

Tant que l'on ne change pas d'année, pas de prob.
cal 1 -> input 1
cal 2 -> input 2

et lors du changement d'année
cal1 (2016) -> input1
cal2 (2017) -> input 1 (le problème est ici).

Bien à vous

Francois à 11h25

Bonjour Francois,

Vous avez créer un calendrier pour chaque champ ?

<input value="31/12/2016" name="calDate1" id="calDate1" size="30" maxlength="50" type="text">
<div id="calendarMain1" class="calendarMain"</div>

<input value="01/01/2017" name="calDate2" id="calDate2" size="30" maxlength="50" type="text">
<div id="calendarMain2" class="calendarMain"</div>

<script type="text/javascript">
var myCalendar = jsSimpleDatePickr();
// calendrier pour le premier champ
myCalendar.CalAdd({
'divId': 'calendarMain1',
'inputFieldId' : 'calDate1',
'navType': '01',
'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S']
});
// calendrier pour le second champ
myCalendar.CalAdd({
'divId': 'calendarMain2',
'inputFieldId' : 'calDate2',
'navType': '01',
'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S']
});
</script>

Patrice à 12h27

Oui les champs id et name sont différent pour les deux.
le bug ne se produit que quand on change d'année sur le deuxième cal.
Voir ici :
[code]
<div class="form-group col-md-3">
<label for="titre">Du</label>
<input type="text" class="form-control" data- id="date_deb_ajout" placeholder="" name="date_deb_ajout">
</div>
<div class="form-group col-md-3">
<label for="titre">Vers</label>
<select class="form-control margin-bottom-10" id="du_vers" name="du_vers">
<option value="09"></option>
<option value="09">9h</option>
<option value="12">12h</option>
<option value="16">16h</option>
<option value="20">20h</option>
<option value="23">23h</option>
</select>
</div>
<div class="form-group col-md-3">
<label for="titre">Au</label>
<input type="text" class="form-control" data- id="date_fin_ajout" placeholder="" name="date_fin_ajout">
</div>
<div class="form-group col-md-3">
<label for="titre">Vers</label>
<select class="form-control margin-bottom-10" id="au_vers" name="au_vers">
<option value="09"></option>
<option value="09">9h</option>
<option value="12">12h</option>
<option value="16">16h</option>
<option value="20">20h</option>
<option value="23">23h</option>
</select>
</div>

<script type="text/javascript">
//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMainDeb',

'inputFieldId': 'date_deb_ajout',
'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': false,
'showOnLaunch': true
});
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMainFin',

'inputFieldId': 'date_fin_ajout',
'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': false,
'showOnLaunch': true
});
//]]>
</script>
[/code]

Patrice à 12h33

Pour le deuxième calendrier cette ligne n'est pas utile :
[code]var myCalendar = new jsSimpleDatePickr();[/code]
La variable myCalendar est déjà instancié plus haut.
Essayez de la supprimer, ça devrait fonctionner.

Patrice à 12h59

Parfait.
Comme je disait, un script génial.

Francois à 13h59

Merci :-)

Patrice à 14h29

Bonjour,

Dans le cadre d'une modification d'enregistrement est il possible d'afficher dans le cal la date précédemment introduite.

Est t'il possible aussi dans la cadre de l'affichage de deux cal pour un date range de faire en sorte que le deuxième cal se met automatiquement sur la date choisie par le premier ?

Bien à vous

Francois à 15h25

Bonjour François,

1- Oui bien sûr. Il suffit de définir la date dans le champ input. Le calendrier s'initialisera d'après cette date.

2- Pas directement. Mais c'est possible en définissant une fonction de retour. Dans cette fonction de retour, vous comparez les deux dates et modifier celle qui n'est pas dans les clous :
[code]<script type="text/javascript">
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendar1',
'inputFieldId': 'ID_CHAMP_DATE_1',
'callBack': Day1Init,
});
myCalendar.CalAdd({
'divId': 'calendar2',
'inputFieldId': 'ID_CHAMP_DATE_2',
'callBack': Day2Init,
});

function Day1Init(aDate){
if(DateCompare('>')){
// si la date 1 est supérieur à la date 2, on change la date 2
document.getElementById('ID_CHAMP_DATE_2').value = aDate;
}
}

function Day2Init(aDate){
if(DateCompare('>')){
// si la date 1 est supérieur à la date 2, on change la date 1
document.getElementById('ID_CHAMP_DATE_1').value = aDate;
}
}

// compare les deux dates
// j'utilise cette fonction sur un site de réservation de salle
function DateCompare(aMode){
var d1 = document.getElementById('ID_CHAMP_DATE_1');
d1 = d1.value.split('/');
d1 = new Date(d1[2], d1[1]-1, d1[0]);
var d2 = document.getElementById('ID_CHAMP_DATE_2');
d2 = d2.value.split('/');
d2 = new Date(d2[2], d2[1]-1, d2[0]);
switch(aMode){
case '>' : return d1>d2;
case '>=' : return d1>=d2;
case '=' : return d1.valueOf()==d2.valueOf();
case '<=' : return d1<=d2;
case '<' : return d1<d2;
}
return 0;
}
</script>
[/code]

Je vais écrire un article sur ce fonctionnement, ça revient souvent :-)

Patrice à 16h51

Bonjour,

Magnifique script que je compte utiliser sur mon futur site, je m'engage d'ailleurs à mettre un lien sur ce blog.

Je voudrais simplement reporter un petit oubli dans les sources CSS : en effet, le bouton pour revenir en arrière n'est pas correctement placé, puisqu'il semble manquer la ligne suivante :

.calendarNav .calendarNavML, .calendarNav .calendarNavYL{
float: left;
}

Encore merci pour ce superbe script JS ! BRAVO pour le travail accompli.

Dominique

Dominique à 13h17

Bonsoir Dominique,

Tant mieux si le code aide.
Vous avez une capture d'écran pour les boutons mal placés ? D'avance merci :-)

Patrice à 18h27

Bonsoir Patrice,

Voici la capture d'écran demandée. Corriger ce petit décalage est très simple, il suffit d'ajouter la ligne CSS ci-dessus :-)

[img]http://athe.pagesperso-orange.fr/calendar_bf_gauche.png[/img]

Patrice à 20h04

Oui pas de soucis pour corriger ça, mais ça m'étonnait qu'il y ait un décalage.
Le flux de la page était centré j'imagine ?

Hop c'est corrigé. Merci pour le retour :-)

Je me suis contenté de rajouter un text-align: left; à la classe .calendarMain.
Passer les boutons gauche en flottant faisait remonter le calendrier.

Patrice à 20h29

Bonsoir Patrice,

"Le flux de la page était centré j'imagine ?"

Bonne remarque ! En enlevant cette propriété, tout revient en ordre.

Merci et bonne soirée !

Dominique à 20h39

Bonjour, je souhaite utiliser votre calendrier de la facon suivante mais je n'y arrive pas. Je voudrais que le calendrier s'affiche tout le temps et que lorsqu'un jour est cliqué, il reste sur un fond rouge. De plus, il me faut récupérer le jour, la date et l'année pour actualiser d'autres variables de ma page. Pourriez vous m'aider ?

esuquet à 07h05

Bonjour esuquet,

Pour avoir un calendrier afficher constamment il faut utiliser les propriétés showOnLaunch (le calendrier est affiché à l'initialisation) et hideOnClick (le calendrier est masqué en cliquant sur une date).

Pour récupérer la date sélectionné vous pouvez utiliser une fonction de retour avec la propriété callBack.

[code]myCalendar.CalAdd({
'divId': 'calendarMain',
'callBack': maFonction,
'hideOnClick': true,
'showOnLaunch': true
});[/code]

Patrice à 13h40

Bonjour Patrice,
Tout d'abord merci pour ce calendrier pratique et joli.
Jusqu'à ce matin j'utilisais une version antérieure que j'avais modifiée pour rajouter deux boutons pour avancer ou reculer l'année de 30 par 30 pour saisir une date de la fin du siècle dernier. Maintenant plus besoin avec : 'dateCentury': 19, très bonne idée cette modification.
J'ai un petit souci dans son utilisation. j'ai deux champs date sur la même page pour lesquels j’instancie 2 calendriers. le souci est que quand je clique sur le second champ, çà m'enlève le calendrier du 1er et si je clique à nouveau le calendrier vient se mettre sous le 1er champ.
Quel que soit le champ sur lequel je clique, le calendrier apparait contre le 1er champ. Suis-je clair?
1ère instanciation
<div id="calendarMain0" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar0 = new jsSimpleDatePickr();
myCalendar0.CalAdd({
'divId': 'calendarMain0',
'inputFieldId': 'DatNaiss',
'dateMask': 'AAAA/MM/JJ',
'dateCentury': 19,
'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
});
//]]>
</script>

2ème instanciation
<div id="calendarMain1" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar1 = new jsSimpleDatePickr();
myCalendar1.CalAdd({
'divId': 'calendarMain1',
'inputFieldId': 'DateMmaJ',
'dateMask': 'AAAA/MM/JJ',
'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
});
//]]>
</script>
merci

Melk à 15h53

Re-bonjour Patrice,
Je me rend compte que j'ai oublié les balises <cote>
1ère instanciation
[code]<div id="calendarMain0" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar0 = new jsSimpleDatePickr();
myCalendar0.CalAdd({
'divId': 'calendarMain0',
'inputFieldId': 'DatNaiss',
'dateMask': 'AAAA/MM/JJ',
'dateCentury': 19,
'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
});
//]]>
</script>
[/code]
2ème instanciation[code]<div id="calendarMain1" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar1 = new jsSimpleDatePickr();
myCalendar1.CalAdd({
'divId': 'calendarMain1',
'inputFieldId': 'DateMmaJ',
'dateMask': 'AAAA/MM/JJ',
'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
});
//]]>
</script>
[/code]

Melk à 15h59

Bonjour Melk,

Sans avoir testé le code, je dirais que le problème vient de l'initialisation.
Pas besoin de créer deux objets. Vous pouvez créer un objet et y ajouter autant de calendrier que vous voulez.
Par exemple :
[code]<script type="text/javascript">
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
[les paramètres du premier calendrier)
});
</script>

// plus loin dans le code
<script type="text/javascript">
myCalendar.CalAdd({
[les paramètres du second calendrier)
});
</script>[/code]

Patrice à 16h00

Merci beaucoup,
C'est parfait.

Melk à 16h08

à oui, j'oubliais, chez moi, les boutons 'année +' 'année -' et 'mois +' 'mois -' affichent des hiéroglyphes. J'ai remplacé par '-A' 'A+' '-M' 'M+' mais les boutons sont étroits et 'M+' affiche 'M-' car on ne voit que le début du '+'.
Mon charset est 'utf8'
Merci encore pour ce "boulot".

Melk à 16h13

Je viens de faire d'autres essais.
En fait je suis sous firefox et voila la partie de code en question que j'ai copié sur votre blog.
[code]
if(data.navType != null && data.navType.charAt(0) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYL', 'type': 'button', 'value': '«'});
i.onclick = function(){
me.CalYearNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYR', 'type': 'button', 'value': '»'});
i.onclick = function(){
me.CalYearNav(id, '+1');
};
}
// ajoute les boutons pour la navigation par mois
if(data.navType != null && data.navType.charAt(1) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavML', 'type': 'button', 'value': '‹'});
i.onclick = function(){
me.CalMonthNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavMR', 'type': 'button', 'value': '›'});
i.onclick = function(){
me.CalMonthNav(id, '+1');
};
}
[/code]
j'ai lancé opéra avec la même url et voila ce que j'ai récupéré:
[code] if(data.navType != null && data.navType.charAt(0) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYL', 'type': 'button', 'value': '«'});
i.onclick = function(){
me.CalYearNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYR', 'type': 'button', 'value': '»'});
i.onclick = function(){
me.CalYearNav(id, '+1');
};
}
// ajoute les boutons pour la navigation par mois
if(data.navType != null && data.navType.charAt(1) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavML', 'type': 'button', 'value': '‹'});
i.onclick = function(){
me.CalMonthNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavMR', 'type': 'button', 'value': '›'});
i.onclick = function(){
me.CalMonthNav(id, '+1');
};
}
[/code]
Donc le souci vient de mon navigateur.

Melk à 17h57

Je suis aussi sur Firefox (entre autre).
Quand vous ouvrez le fichier javascript avec un éditeur de texte, les caractères sont affichés correctement ?

Patrice à 22h01

Ils sont affichés de la même façon puisque le texte que je copie/colle depuis [url]https://blog.niap3d.com/calendrier-javascript/js/jsSimpleDatePickr.2.1.js[/url]
est, vu de mon navigateur (Firefox 50.1.0), comme ceci [code]/*http://blog.niap3d.com/jsSimpleDatePickr*/
function jsSimpleDatePickr(){
var me = this;
me.jsSDPObj = Array();
me.jsSDPId = 1;
//
// ajoute un calendrier
//
me.CalAdd = function(data){
var calDiv = document.getElementById(data.divId);
var dateEl = document.getElementById(data.inputFieldId);
// vérifie les données
if(typeof(calDiv) == 'undefined') return 0;
if(typeof(dateEl) == 'undefined') data.inputFieldId = '';
if(typeof(data.hideOnClick) != 'boolean') data.hideOnClick = 1;

var id = me.jsSDPId;
if(data.buttonTitle == null || data.buttonTitle.length <= 0){
if(dateEl != null){
// attache la fonction CalToogle au champ de texte qui contiendra la date
dateEl.addEventListener('click', function(){ me.CalDoFromField(data.inputFieldId, 'toogle'); }, false);
}

}else{
// ajoute le bouton pour afficher, masquer le calendrier
var bt = me.DomElementInit('input', {'parent': calDiv, 'value': data.buttonTitle, 'type': 'button'});
bt.onclick = function(){
me.CalToogle(id);
};
}
// bloc div principal
var divW = me.DomElementInit('div', {'parent': calDiv, 'id': 'calendarWrap'+id});
// ajoute le paragraphe du titre
if(data.navType != '00') divW.innerHTML += '<p id="calendarTitle'+id+'" class="calendarTitle"></p>';
var divNav = me.DomElementInit('div', {'parent': divW, 'class': 'calendarNav'});
// ajoute les boutons pour la navigation par an
if(data.navType != null && data.navType.charAt(0) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYL', 'type': 'button', 'value': '«'});
i.onclick = function(){
me.CalYearNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavYR', 'type': 'button', 'value': '»'});
i.onclick = function(){
me.CalYearNav(id, '+1');
};
}
// ajoute les boutons pour la navigation par mois
if(data.navType != null && data.navType.charAt(1) == 1){
var i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavML', 'type': 'button', 'value': '‹'});
i.onclick = function(){
me.CalMonthNav(id, '-1');
};
i = me.DomElementInit('input', {'parent': divNav, 'class': 'calendarNavMR', 'type': 'button', 'value': '›'});
i.onclick = function(){
me.CalMonthNav(id, '+1');
};
}
// bloc div qui contiendra le calendrier
me.DomElementInit('div', {'parent': divW, 'id': 'calendar'+id});
// masque le div principal
divW.style.display = 'none';
// sauvegarde l'objet
me.jsSDPObj.push({
'divId': data.divId,
'inputFieldId': data.inputFieldId,
'callBack': data.callBack,
'id': id,
'displayNumber': parseInt(data.displayNumber) > 1 ? data.displayNumber:1,
'dateSel': new Date(),
'dateDisp': new Date(),
'dateCentury': data.dateCentury == null ? 20:data.dateCentury,
'dayLst': data.dayLst,
'monthLst': data.monthLst,
'dateMask': data.dateMask == null ? 'JJ/MM/AAAA':data.dateMask,
'titleMask': data.titleMask == null ? '':data.titleMask,
'hideOnClick': data.hideOnClick,
'classTable': data.classTable,
'classDay': data.classDay,
'classDaySelected': data.classDaySelected
});
me.CalDateInit(id);
me.jsSDPId++;
if(data.showOnLaunch) me.CalToogle(id);
return id;
}
//
// supprime un calendrier
//
me.CalDelete = function(id){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
document.getElementById(me.jsSDPObj[nb]['divId']).innerHTML = '';
me.jsSDPObj.splice(nb, 1);
}
//
// supprime tous les calendriers
//
me.CalDeleteAll = function(){
for(var i = 0; i < me.jsSDPObj.length; i++){
document.getElementById(me.jsSDPObj[i]['divId']).innerHTML = '';
me.jsSDPObj[i]['inputFieldId'] = 0;
}
me.jsSDPObj = Array();
me.jsSDPId = 1;
}
//
// renvoi le numéro dans l'Array d'après l'id
//
me.CalId2Nb = function(id){
for(var i = 0; i < me.jsSDPObj.length; i++){
if(me.jsSDPObj[i]['id'] == id){
return i;
}
}
return -1;
}
//
// affiche / masque le calendrier (clic depuis un champ de texte)
//
me.CalDoFromField = function(fieldId, action){
for(var i = 0; i < me.jsSDPObj.length; i++){
if(me.jsSDPObj[i]['inputFieldId'] == fieldId){
if(action == 'toogle') me.CalToogle(me.jsSDPObj[i]['id']);
if(action == 'show') me.CalShow(me.jsSDPObj[i]['id']);
if(action == 'hide') me.CalHide(me.jsSDPObj[i]['id']);
break;
}
}
}
//
// affiche / masque le calendrier
//
me.CalToogle = function(id){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
var e = document.getElementById('calendarWrap'+me.jsSDPObj[nb]['id']);
if(e == 'undefined') return 0;
if(e.style.display == 'block'){
e.style.display = 'none';

}else{
if(me.jsSDPObj[nb]['inputFieldId'] != ''){
var f = document.getElementById(me.jsSDPObj[nb]['inputFieldId']);
if(f != null) me.CalDateInit(id, String(f.value));
}
me.CalShow(id);
}
}
//
// affiche le calendrier
//
me.CalShow = function(id){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
var e = document.getElementById('calendarWrap'+me.jsSDPObj[nb]['id']);
if(!e) return 0;
me.CalContentInit(nb);
me.CalShowTitle(nb);
e.style.display = 'block';
}
//
// masque le calendrier
//
me.CalHide = function(id){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
var e = document.getElementById('calendarWrap'+me.jsSDPObj[nb]['id']);
if(!e) return 0;
e.style.display = 'none';
}
//
// navigation par mois
//
me.CalMonthNav = function(id, val){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
me.jsSDPObj[nb]['dateDisp'].setDate(1);
var v = parseInt(val, 10);
if(val.charAt(0) == '+' || val.charAt(0) == '-') v = me.jsSDPObj[nb]['dateDisp'].getMonth()+v;
me.jsSDPObj[nb]['dateDisp'].setMonth(v);
me.CalContentInit(nb);
me.CalShowTitle(nb);
}
//
// navigation par année
//
me.CalYearNav = function(id, val){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
var v = parseInt(val, 10);
if(val.charAt(0) == '+' || val.charAt(0) == '-') v = me.jsSDPObj[nb]['dateDisp'].getFullYear()+v;
me.jsSDPObj[nb]['dateDisp'].setFullYear(v);
me.CalContentInit(nb);
me.CalShowTitle(nb);
}
//
// change la date
//
me.CalDateInit = function(id, dateStr){
var nb = me.CalId2Nb(id);
if(nb < 0) return 0;
var o = me.jsSDPObj[nb];
if(!dateStr) dateStr = '';
var m = o['dateMask'];
// extrait la date d'après le mask
var pos, dY, dM, dD;
pos = m.indexOf('JJ');
if(pos != -1) dD = parseInt(dateStr.substr(pos, 2), 10);
var pos = m.indexOf('AAAA');
if(pos != -1) dY = parseInt(dateStr.substr(pos, 4), 10);
else{
pos = m.indexOf('AA');
if(pos != -1) dY = parseInt(dateStr.substr(pos, 2), 10)+o['dateCentury']*100;
}
pos = m.indexOf('MM');
if(pos != -1) dM = parseInt(dateStr.substr(pos, 2), 10)-1;
today = new Date();
if(isNaN(dD)) dD = today.getDate();
if(isNaN(dM)) dM = today.getMonth();
if(isNaN(dY)) dY = parseInt(today.getFullYear().toString().substr(2, 2), 10)+o['dateCentury']*100;
o['dateSel'] = new Date(dY, dM, dD);
o['dateDisp'] = new Date(dY, dM, dD);
}
//
// affiche le calendrier
//
me.CalContentInit = function(nb){
var i, j;
var cal = me.jsSDPObj[nb];
var dayOrder = '1234560';
var curDate = new Date(cal['dateDisp'].getFullYear(), cal['dateDisp'].getMonth(), 1);
document.getElementById('calendar'+cal['id']).innerHTML = '';
for(j = 0; j < cal['displayNumber']; j++){
var num = today = 0;
var month = curDate.getMonth();
var year = curDate.getFullYear();
if(month == cal['dateSel'].getMonth() && year == cal['dateSel'].getFullYear()) today = cal['dateSel'].getDate();
var elT = me.DomElementInit('table', {'parent': document.getElementById('calendar'+cal['id']), 'class': cal['classTable']});
var elTr = me.DomElementInit('tr', {'parent': elT});
for(i = 0; i < 7; i++){
me.DomElementInit('th', {'parent': elTr, 'content': cal['dayLst'][dayOrder[i]]});
}
elTr = me.DomElementInit('tr', {'parent': elT});
var h, d = new Date(year, month, 1);
for(num = 0; num < dayOrder.indexOf(d.getDay()); num++){
me.DomElementInit('td', {'parent': elTr});
}
d.setMonth(month+1, 0);
for(i = 1; i <= d.getDate(); i++){
num++;
if(num > 7){
num = 1;
elTr = me.DomElementInit('tr', {'parent': elT});
}
var cell = me.DomElementInit('td', {'parent': elTr, 'class': (i == today ? cal['classDaySelected']:cal['classDay']), 'content': i});
cell.onclick = (function(v, m, y){
return function(){
me.CalClick(nb, v+'/'+m+'/'+y);
}
})(i, month, year);
}
for(i = num; i < 7; i++){
me.DomElementInit('td', {'parent': elTr});
}
curDate.setMonth(curDate.getMonth()+1);
}
}
//
// callback : gère une clic sur une date
//
me.CalClick = function(nb, dateStr){
var dateArr = dateStr.split('/');
var cal = me.jsSDPObj[nb];
cal['dateSel'] = new Date(dateArr[2], dateArr[1], dateArr[0]);
if(cal['inputFieldId'] != ''){
dateArr[1]++;
var m = cal['dateMask'];
m = m.replace('AAAA', dateArr[2]);
m = m.replace('AA', dateArr[2].toString().substr(2,2));
m = m.replace('MM', parseInt(dateArr[1], 10) < 10 ? '0'+dateArr[1]:dateArr[1]);
m = m.replace('M', dateArr[1]);
m = m.replace('JJ', parseInt(dateArr[0], 10) < 10 ? '0'+dateArr[0]:dateArr[0]);
m = m.replace('J', dateArr[0]);
f = document.getElementById(cal['inputFieldId']);
if(f != null) f.value = m;
if(cal['hideOnClick']) document.getElementById('calendarWrap'+cal['id']).style.display = 'none';
else me.CalContentInit(nb);

}else{
me.CalContentInit(nb);
}
// callback
if(typeof cal['callBack'] === "function") cal['callBack'](dateStr);
}
//
// affiche le titre
//
me.CalShowTitle = function(nb){
if(typeof me.jsSDPObj[nb] == 'undefined') return 0;
var e = document.getElementById('calendarTitle'+me.jsSDPObj[nb]['id']);
if(!e) return 0;
var cal = me.jsSDPObj[nb];
var m = cal['titleMask'];
if(m == '') return 0;
var d = cal['dateDisp'].getMonth();
m = m.replace('MM', parseInt(d, 10) < 10 ? '0'+[d]:[d]);
m = m.replace('M', cal['monthLst'][d]);
d = cal['dateDisp'].getFullYear();
m = m.replace('AAAA', d);
m = m.replace('AA', d.toString().substr(2,2));
e.innerHTML = m;
}
//
// crée un element DOM
//
me.DomElementInit = function(type, opt){
var e = document.createElement(type);
if(opt.id != undefined) e.id = opt.id;
if(opt.class != undefined) e.className = opt.class;
if(opt.type != undefined) e.type = opt.type;
if(opt.value != undefined) e.value = opt.value;
if(opt.content != undefined) e.innerHTML = opt.content;
if(opt.parent != undefined) opt.parent.appendChild(e);
return e;
}
return me;
}[/code] et si j'utilise opéra c'est bon je vois les guillemets au lieu '›' et compagnie. Et lorsque j'avais téléchargé la version que j'utilisais jusqu'à ce matin j'avais eu le même inconvénient. Il y a peut-être un mauvais paramétrage quelque part sur mon navigateur mais jusque là je ne m'étais pas aperçu de çà.
C'est peut-être aussi pour çà que sur 2 configs j'ai des chevauchements comme par exemple sur la dernière en bas à droite le titre et les jours de la semaine se chevauchent, j'ai essayé d'inclure une copie d'écran mais je n'arrive pas à l'afficher malgré les balises <img>

Melk à 23h23

À tous hasard, au lieu de copier-coller, essayez de faire enregistrer-sous sur le lien.

Pour les balises img, il faut mettre un lien http entre deux balises [img][/img]

Patrice à 23h30

effectivement avec "enregistrer sous" le texte est correct même avec firefox.
Pour l'image je ne saisi pas "il faut mettre un lien http entre deux balises"
l'image n'est pas sur un serveur mais sur mon ordinateur je ne sais pas comment la remonter.
Tant que j'y suis, je précise que je suis néophyte en JS mais j'essaye de me soigner, [b]une propriété m'intrigue[/b] : [code]'displayNumber': parseInt(data.displayNumber) > 1 ? data.displayNumber:1,[/code] elle n'est pas dans data de [code]<div id="calendarMain" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'buttonTitle': 'MonBouton',
'inputFieldId': 'MonChamp',
'callBack': MaFonction(UneDate),
'dateMask': 'AAAA/MM/JJ',
'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
});
//]]>
</script>[/code] et j'aime bien comprendre, d'autant que j'ai trouvé le calendrier tellement sympa esthétiquement que comme j'ai une grille de saisie d'un nombres à faire entre 0 et 99 à plusieurs reprises, j'aurai utilisé le même visuel que le calendrier qui va se trouver à coté. Donc à quoi sert cette propriété.
Merci

Melk à 23h45

displayNumber permet de définir le nombre de mois à afficher.
Ça permet d'afficher un trimestre ou une année d'un coup, par exemple.

Patrice à 00h42

Bonjour,
J'ai construit ma grille mais je n'arrive pas à faire fonctionner le gestionnaire de click. Seriez-vous d'accord pour m'expliquer la gestion du votre?
[code] var cell = me.DomElementInit('td', {'parent': elTr, 'class': (i == today ? cal['classDaySelected']:cal['classDay']), 'content': i});
cell.onclick = (function(v, m, y){
return function(){
me.CalClick(nb, v+'/'+m+'/'+y);
}
})(i, month, year);
[/code]
je met mon code au cas ou vous accepteriez mais je comprendrais très bien que vous refusiez! je vous remercie
[code]while (num <= NbMax)
{
for(j = 0; j < NbLig; j++)
{
var elTr = me.DomElementInit('tr', {'parent': elT});
for(i = 0; i < NbCol; i++)
{
var cell = me.DomElementInit('td', {'parent': elTr, 'id': 'td'+num, 'class': grl['classCellule'], 'content': num});
cell.addEventListener('click', function(){ me.grilleClick(nb, cell.id, NbMax); }, false);
num++;
if (num > NbMax) break;

}
elTr = me.DomElementInit('tr', {'parent': elT});
if (num > NbMax) break;
}
}
[/code] avec ce code, où que je clique c'est l'id de la dernière cellule qui passe.

Melk à 16h33

A mon avis le problème vient de la porté des variables.
Les variables nb et NbMax existent dans la boucle while, mais pas dans le fonction de clic. Il faut les enregistrer sur l'objet, ou les passer dans les attributs de fonction comme j'ai fait. Par exemple :
[code]cell.dataset.nb = nb;
cell.dataset.nbMax = nbMax;
[/code]
Et dans la fonction :
[code]cell.addEventListener('click', function(){ me.grilleClick(this.dataset.nb, this.id, this.dataset.nbMax); }, false);[/code]

Patrice à 21h38

Bonsoir Patrice
C'est bien çà.
çà fonctionne.
[b]Merci beaucoup[/b]

Melk à 23h41

Bonjour,
débutant dans HTML j'ai déjà quelques vbscript et javascript mais placé en "function" dans l'entête <head> </head>.
Est'il possible de ne garder dans le corp <body>
<div id="calendarMain" class="calendarMain"></div>
</body>
et de mettre le script générer par le configurateur en fonction javascript?


<script type="text/javascript">
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'buttonTitle': 'afficher le calendrier',
'inputFieldId': 'madate',
'dateMask': 'JJ/MM/AA',
'dateCentury': 20,
'titleMask': 'M AAAA',
'navType': '11',
'classTable': 'jsCalendar',
'classDay': 'day',
'classDaySelected': 'selectedDay',
'monthLst': ['Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Decembre'],
'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
'hideOnClick': true,
'showOnLaunch': false
});
</script>

autre remarque:Février Août Décembre ne s'affiche pas correctement sous IE, j'ai donc remplacer sans les accents

Patrice à 15h06

Bonsoir zarcraft,

Si vous placez le code tel quel dans l'entête, ça ne fonctionnera pas.
Car les éléments du DOM ne seront pas chargé avant l'initialisation du calendrier.

Si vous utilisez jQuery vous pouvez utiliser

[code]$( document ).ready(function() {
// insérer ici le code d'initialisation
});
[/code]

Patrice à 22h04

Bonjour,
afin de préciser mon besoin je ne travail pas directement du HTML mais du HTA...
bref
j'ai inséré ces 2 lignes entre les balises d'entête

<head>
<link rel="stylesheet" type="text/css" href="default_blue.css" />
<script type="text/javascript" src="jsSimpleDatePickr.2.1.js"></script>
</head>

et le div avec son script dans le <body>
j'ai 2 erreurs sur 2 popup différent:
ligne 319 caractère 9
identificateur attendu sur
url file:///C:/Users/xxx/Desktop/fichiers%20xxx/jsSimpleDatePickr.2.1.js
la ligne 319 est dans une fontion vbscript donc rien a voir

et ligne 972 caractère 1
jsSimpleDatePickr est indefini

cette ligne est var myCalendar = new jsSimpleDatePickr();

il faut redéclarer jsSimpleDatePickr a quel niveau?

zarcraft à 09h26

Je ne connais pas HTA, donc je ne sais pas s'il existe des limitations lors de la lecture.
Il faut déjà vérifier que le fichier jsSimpleDatePickr.2.1.js est correctement chargé.

Patrice à 10h11

Comment vérifier que le fichier jsSimpleDatePickr.2.1.js est correctement chargé?

zarcraft à 12h44

Par exemple en ajoutant console.log('jsSimpleDatePickr OK'); à la fin du fichier .js

Patrice à 14h01

j'ai tester avec d'autres fichiers js et ceux-ci ne contienne pas d'élément DOM et cela fonctionne mais ne repond pas exactement à mon besoin

zarcraft à 14h38

Vous pouvez aussi copier coller la fonction javascript directement dans le head plutôt que de faire appel à un fichier externe.

Patrice à 10h54

Auriez vous un exemple?
J'ai supprimer la ligne de référencement du fichier .js dans le head
J'ai copier tout le contenu du fichier .js dans le head
/*http://blog.niap3d.com/jsSimpleDatePickr*/
function jsSimpleDatePickr(){
var me = this;
me.jsSDPObj = Array();
me.jsSDPId = 1;
//
// ajoute un calendrier
//....etc...

zarcraft à 12h17

Oui c'est ça. Il faut copier le code dans des balises script. Mais je ne sais pas si ça va régler le problème de l'objet non définit.
[code]
<html>
<head>
<script>
// copier le code ici
</script>
</head>
<body>
</body>
</html>
[/code]

Patrice à 12h39

cela ne règle pas le pb . plusieurs erreur dont la première concerne la ligne
if(opt.class != undefined) e.className = opt.class;

zarcraft à 13h00

Essayez de remplacer '!= undefined' par '!== "undefined"'
Quel navigateur (version / système) ?

Patrice à 13h12

ko
je suis sous windows 7 pro x64 + IE11

Si vous aviez un peu de temps je pourrais vous envoyer mes sources directement,ce serais peut être plus explicite?

zarcraft à 16h47

Oui, vous pouvez poster un lien ou m'envoyez les source à patrice.k AT niap3d.com

Patrice à 16h52

Bjr,

Je n'y connais pas grand chose mais je pense avoir suivi la procédure.. J'ai créé un directory et ai placé mon fichier index.php . Dans ce directory j'ai créé un sous directory text et j'y ai mis les fichiers jsSimpleDatePickr.2.1.js et default_blue.css. Le fichier index.php est ci-dessous mais je n'obtiens qu'une page blanche. Je suis certain que cette question va vous paraître idiote mais je serai content si vous m'indiquiez pourquoi cela ne fonctionne pas..
Merci d'avance.
[code]
<!doctype html>
<html lang="fr">
<head>
<link rel="stylesheet" type="text/css" href="default_blue.css" />
<script type="text/javascript" src="jsSimpleDatePickr.2.1.js"></script>


</head>
<body>
<div id="calendarMain" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'callBack': tournois,
'dateMask': 'JJ-MM-AA',
'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'],
'ophicléide': true,
'showOnLaunch': false
});
//]]>
</script>

</body>
</html>
[/code]

Patrice à 15h40

Bonjour philippe,

Le code collé n'est pas complet, mais je pense que c'est le copié collé qui a dû être effacé.
Que dit la console du navigateur ?

Patrice à 16h30

Le code copié/collé était bien correct: cela doit être un problème d'affichage sur le blog. Je ne sais pas comment marche la console mais j'ai trouvé une autre façon de faire et je vous remercie pour votre réponse.

philippe à 16h44

Pour afficher la console
[b]Sous Firefox[/b] : Outils / Développement Web / Console du navigateur
[b]Sous Chrome[/b] : Afficher / Options pour développeur / Console Javascript

Ça permet de voir les erreurs de chargement / script / autres

Patrice à 16h48

Bonjour,
Je voudrais que le calendrier s'affiche sur click du champ à mettre à jour. J'ai pensé mettre un écouteur sur ce champ mais je ne sais pas quelle fonction appeler.
Voici ma configuration:[code=javascript]//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'inputFieldId': 'init_abo',
'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
});
//]]>
[/code]

Marc à 17h33

Bonjour Marc,

Vous pouvez appelez la fonction CalShow avec comme paramètre l'identifiant du champ.

document.getElementById('ID_DU_CHAMP').addEventListener('click', function(){ myCalendar.CalShow('ID_DU_CHAMP'); }, false);

Patrice à 18h08

OK, merci. De plus j'avais essayé une version précédente et celle-ci est plus facile à mettre en oeuvre.

Marc à 20h18

Bonjour
Je souhaite cacher le calendrier, lorsque le champ et le calendrier perdent le focus.
J'ai écrit un petit script mais je ne trouve pas le paramètre à transmettre à la fonction.
[code=javascript]var divAbo = document.getElementById('calendarMain');
divAbo.addEventListener('blur', function(e) {
myCalendar.CalHide(/*divId*/'calendarMain'/*'ID_DU_CHAMP'*/);
}), false;
</script>
[/code]

Marc à 11h33

Re-Bonjour,
A la relecture, je vois que j'ai du mal utiliser la balise 'code'.
Je souhaite cacher le calendrier, lorsque le champ et le calendrier perdent le focus.
J'ai écrit un petit script mais je ne trouve pas le paramètre à transmettre à la fonction.
[code]var divAbo = document.getElementById('calendarMain');
divAbo.addEventListener('blur', function(e) {
myCalendar.CalHide(/*divId*/'calendarMain'/*'ID_DU_CHAMP'*/);
}), false;[/code]

Marc à 12h04

Bonjour Marc,

Erreur de ma part, avec CalHide c'est l'identifiant interne un calendrier qu'il faut passer. Cet id est renvoyé par la fonction CalAdd.
[code]
var myCalendar = new jsSimpleDatePickr();
var calId = myCalendar.CalAdd({
/* liste des paramètres */
});
divAbo.addEventListener('blur', function(e){ myCalendar.CalHide(calId); }, false);
[/code]
CalHide => masquer
CalShow => Afficher
CalToogle => inverser l'affichage

Sinon il y a une fonction CalDoFromField qui attend deux paramètres :
- l'identifiant du champ (qui a été passé à l'initialisation)
- l'action : 'toogle', 'show', 'hide
Ça évite de devoir enregistrer l'id interne

Patrice à 09h32

Bonjour Patrice,
Aucune des deux solutions ne fonctionne. Voici mon code complet:[code]<script src="jsSimpleDatePickr.2.1.js"></script>
<script>
var divAbo = document.getElementById('calendarMain');
var myCalendar = new jsSimpleDatePickr();
//<![CDATA[
var calId = myCalendar.CalAdd({ // ajout de 'var calId = '
'divId': 'calendarMain',
'inputFieldId': 'init_abo',
//'dateMask': 'JJ/MM/AAAA',
'dateMask': 'AAAA-MM-JJ',
'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'],
'monthLst': <?= json_encode(JS_CAL_MONTHES); ?>,
//'dayLst': ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
'dayLst': <?= json_encode(JS_CAL_DAYS); ?>,
'hideOnClick': false,
'showOnLaunch': false
});
//]]>
// Effacement sur clic hors divAbo
divAbo.addEventListener('blur', function(e){ alert('rrrrrr'); myCalendar.CalHide(calId); }, false);
/*
// Ne fonctionne pas
divAbo.addEventListener('blur', function(e) {
CalDoFromField('init_abo', 'hide');
}, false);
*/
</script>
[/code]

Marc à 12h40

Les deux méthodes semblent équivalentes.
Je récapitule. Je veux masquer le calendrier après mise à jour du champ date ou après avoir cliqué en dehors du calendrier ou du champ date.
Ma difficulté est d'appliquer l'écouteur du bon type et sur le bon élément. Actuellement soit le calendrier n'est pas masqué, soit il est masqué avant la mise à jour du champ date.

Marc à 17h10

Bonjour Marc,

Il faut appliquer l'évenement blur au champ, pas au calendrier.

[code]document.getElementById('init_abo').addEventListener('blur', function(e){ alert('rrrrrr'); myCalendar.CalHide(calId); }, false);
[/code]

Pour le calendrier je contournerais le problème en ajouter un écouteur click sur le fenêtre (lorsque le calendrier est affiché) et vérifier e.target.
- Si e.target est le calendrier => ne rien faire.
- Sinon masquer le calendrier (et effacer l'écouteur).

Patrice à 10h17

Il faut aussi vérifier si le click n'est pas sur le calendrier sur l'écouteur blur du champ init_abo sinon le calendrier s'effacera.

Patrice à 10h20

Bonjour Patrice,
Je galère et je ne m'en sors pas.
En particulier, je n'arrive pas à voir ce qui se passe au niveau du calendrier et en particulier à remonter l'arborescence du DOM jusqu'au div conteneur 'calendarMain' en cas de clic sur le calendrier.

Marc à 11h22

Bonjour Patrice,
C'est bon, j'ai résolu mon problème, en ajoutant simplement ceci:
[code]// Effacement du calendrier si clic en dehors du champ init_abo
document.addEventListener('click', function(e) {
if (e.target.id == 'init_abo') return false;
myCalendar.CalDoFromField('init_abo', 'hide');
}, false);
[/code]

[b]Question :[/b]
Comment faîtes-vous le contrôle anti-robot dans l'envoi de ce commentaire. Il semble simple et efficace.

Marc à 16h05

Bonjour,

Je viens de récupérer le calendrier, c'est parfait pour mon projet. Je suis débutant en javascript donc je ne comprend pas encore tout.

Je voulais vous demander, est ce qu'il est possible d'afficher en couleur plusieurs dates du calendrier au chargement ?
Je voudrai lors du chargement de la page que certaines dates du calendrier (provenant de ma base de données) s’affiche avec une autre couleur afin que l'utilisateur puisse visualiser directement les dates en question.

J'ai aussi un peu de mal comprendre comment extraire la date que l'utilisateur a sélectionné. J'ai encore des difficultés à comprendre l'objet.

Cordialement.

Bryan à 16h56

Bonjour Bryan,

Concernant la coloration de différente date. Par défaut, ça n'est pas possible. Mais vous pouvez modifier la fonction d'affichage (CalContentInit) pour intégrer vos données.

Pour récupérer la date c'est plus facile
- Soit vous avez un champ de type text attaché au calendrier. Dans ce cas au clic sur une date, le calendrier va automatiquement changer la valeur du champ. Et vous pouvez utiliser ces valeurs avec un écouteur sur le champ par exemple.
- Soit vous n'avez pas de champ attaché et dans ce cas vous pouvez définir un callBack, c'est à dire une fonction qui sera appelé au clic sur une date.
myCalendar.CalAdd({
'divId': 'calendar1',
'callBack': DateInit,
});


function Day1Init(aDate){
console.log(aDate);
}

Désolé pour le délais de ma réponse.

Patrice à 15h50

Bonjour, j'ai inséré le code dans une page, mais rien ne s'affiche sur ma page, je ne sais vraiment pas où se trouve le problème.
Voici le code:

<html>
<head>
<link rel="stylesheet" type="text/css" href="default_blue.css" />
<script type="text/javascript" src="jsSimpleDatePickr.2.1.js"></script>

</head>
<body>
<div id="calendarMain" class="calendarMain"></div>
<script type="text/javascript">
//<![CDATA[
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'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': false,
'showOnLaunch': false
});
//]]>
</script>

</body>
</html>

JDRIKORE à 12h26

Bonjour,
Super calendrier, j'ai réussi à l'affiché sur mon site, maintenant j'aimerais pouvoir désactiver les dates antérieures à la date d'aujourd'hui afin de permettre aux utilisateurs de sélectionner que à partir de la date d'aujourd'hui.

JDRIKORE à 13h35

Bonjour JDRIKORE,

Ce n'est pas possible actuellement (ce sera pour une prochaine mise à jour).
Il faudrait modifier les fonctions CalMonthNav, CalYearNav et CalContentInit pour vérifier la date.

Patrice à 13h37

Bonjour,

Il faut soit lier le calendrier à un input de type text soit mettre la propriété showOnLaunch à true

Patrice à 13h40

Bonjour,
Merci pour vos réponses.

JDRIKORE à 16h47

Bonjour Patrice,
Dans le code suivant, je rencontre plusieurs difficultés:
Il semble qu'il y ait confusion partielle entre le calendrier d'entrée (calendarIn) et le calendrier de sortie (calendarOut). Ce dernier s'affiche toujours à l'emplacement du calendrier d'entrée.
Le comportement est instable sans que j'arrive à analyser les causes.
Le calendrier d'entrée s'efface quand je clique sur le calendrier d'entrée (normal) ou de sortie (pas normal) et réciproquement.
L'écouteur n'est jamais appelé.

Code CSS:[code=css].calendarInLine {
display: inline-block;
}
[/code]

Code html:[code=html] <label for="entree">Date d'entrée</label><input type="text" id="entree" name="entree" value="<?= setPostValue('entree'); ?>" placeholder="<?= TODAY_SQL; ?>" required />
<div id="calendarIn" class="calendarMain calendarInLine"></div><br/>
<label for="sortie">Date de sortie</label><input type="text" id="sortie" name="sortie" value="<?= setPostValue('sortie'); ?>" placeholder="<?= TODAY_SQL; ?>" />
<div id="calendarOut" class="calendarMain calendarInLine"></div><br/>
[/code]

Code Javascript:[code=javascript]var entree = new jsSimpleDatePickr();
//<![CDATA[
entree.CalAdd({
//'divId': 'calendarMain',
'divId': 'calendarIn',
'inputFieldId': 'entree',
'dateMask': 'AAAA-MM-JJ',
'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", "Ma", "Me", "J", "V", "S"],
'hideOnClick': true,
'showOnLaunch': false
});
//]]>

var sortie = new jsSimpleDatePickr();
//<![CDATA[
sortie.CalAdd({
//'divId': 'calendarMain',
'divId': 'calendarOut',
'inputFieldId': 'sortie',
'dateMask': 'AAAA-MM-JJ',
'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", "Ma", "Me", "J", "V", "S"],
'hideOnClick': true,
'showOnLaunch': false
});
//]]>

const body = document.getElementsByTagName('body')[0],
calIn = document.getElementById('calendarIn'),
calOut = document.getElementById('calendarOut');
console.log(body);
body.addEventListener('clic', function(e) {
console.log(e.target.name);
alert(e.target);
if (e.target.id !== 'entree') calIn.CalHide('entree');
if (e.target.id !== 'sortie') calOut.CalHide('sortie');
}, false );
[/code]

Marc à 16h56

Bonsoir Marc,

Il suffit de n'utiliser qu'un seul objet jsSimpleDatePickr.

var entree = new jsSimpleDatePickr();

entree.CalAdd({
'divId': 'calendarIn',
[...]
});

entree.CalAdd({
'divId': 'calendarOut',
[...]
});

Vous initialisez une fois l'objet, ensuite vous ajoutez autant de calendrier que vous voulez.

Patrice à 17h34

Bonjour Patrice,
J'ai un problème avec mon champs input qui récupère la date lors du clic sur le calendrier, en effet lors de la soumission du formulaire le champs input est considéré vide et je sais pas pourquoi, pourtant la date s'affiche bien dans le input.
J'ai donc décidé de faire une fonction de callBack dans laquelle je vais attribuer la date sélectionnée à un autre input masqué, mais là encore, la fonction n'attribut pas la valeur. Pouvez vous jeter un coup d'oeil à mon code:
[code]
<script type="text/javascript">
var myCalendar = new jsSimpleDatePickr();
myCalendar.CalAdd({
'divId': 'calendarMain',
'dateMask': 'JJ/MM/AAAA',
'dateCentury': 20,
'inputFieldId' : 'datereserv' ,
'titleMask': 'M AAAA',
'callBack': 'FuncToday',
'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': false,
'showOnLaunch': true
});

function FuncToday(date)
{
document.getElementById('datereserv2').value = date;
}
</script>
<!-- Fin Ajouts de scripts -->
[/code]

Patrice à 11h25

Bonjour JDRIKORE,

Pas facile à dire comme ça.
Si vous mettez une valeur par défaut, est-elle transmise correctement ?
Comment vous récupérez cette valeur ?
Il n'y aurait pas un autre champ qui porte le même nom dans le fichier ?

Patrice à 14h03

Bonjour Patrice,
1- Lorsque je mets une valeur par défaut, elle est transmise correctement
2- Je récupère par POST lors de la soumission du formulaire
3- Non, il n'y a pas un autre champs qui porte le même nom dans le fichier

JDRIKORE à 11h33

Vous avez un exemple en ligne, pour que je vois ?

Patrice à 14h16

Bonjour Patrice,
Dans le code suivant, je ne comprends pas pourquoi les quatre premières conditions de l'écouteur ne fonctionnent pas.[code=javascript]var cal = new jsSimpleDatePickr();
//<![CDATA[
cal.CalAdd({
'divId': 'calendarIn',
'inputFieldId': 'entree',
'dateMask': 'AAAA-MM-JJ',
'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", "Ma", "Me", "J", "V", "S"],
'hideOnClick': true,
'showOnLaunch': false
});
//]]>

//<![CDATA[
cal.CalAdd({
'divId': 'calendarOut',
'inputFieldId': 'sortie',
'dateMask': 'AAAA-MM-JJ',
'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", "Ma", "Me", "J", "V", "S"],
'hideOnClick': true,
'showOnLaunch': false
});
//]]>

const body = document.getElementsByTagName('body')[0],
calIn = document.getElementById('calendarIn'),
calOut = document.getElementById('calendarOut');

body.addEventListener('click', function(e) {
console.log(cal);
if (e.target.name !== 'entree') cal.CalHide('entree');
if (e.target.name !== 'sortie') cal.CalHide('sortie');
if (e.target.name !== 'entree') cal.CalHide('divId');
if (e.target.name !== 'sortie') cal.CalHide('divId');
if (e.target.name !== 'entree') cal.CalDoFromField('entree', 'hide');
if (e.target.name !== 'sortie') cal.CalDoFromField('sortie', 'hide');
//alert(e.target.name);
}, false );
[/code]
P.S. Je n'ai pas trouvé de notice sur votre site. Ce serait bien d'avoir la liste des propriétés publiques et des fonctions. Après le travail initial, ce serait un gain de temps pour tous, notamment sur ce blog.

Marc à 16h46

Bonsoir Marc,

Ça ne fonctionne pas parce que ces fonctions attendant un identifiant :
me.CalHide = function(id){
}

Il s'agit de l'identifiant interne que vous ne connaissez pas forcément. C'est pour ça que j'avais ajouté la fonction CalDoFromField qui attend le nom du champ passé au constructeur.

Sinon sur la page du configurateur, dans l'historique, il y a la liste des paramètres d'initialisation mais pas les fonctions :
[url]https://blog.niap3d.com/calendrier-javascript/[/url]

Je mettrais cette page à jour en fin d'année, d'ici là je vais prépare un autre petit code.

Patrice à 17h27

OK, merci

Marc à 18h27

Bonjour,
Pour info, j'ai du modifier le css de default_blue.css pour éviter de prendre en compte certaines données héritées.
Peut-être pourriez-vous intégrer ces lignes directement de façon native dans votre code. C'est peut-être aussi vrai pour d'autres parties du css.
Voici mon code modifié:[code=css].jsCalendar th{
color: #8ba7bf;
font-size: 16px;
font-weight: normal;
text-align: center;
background-color:transparent; /* Ligne ajoutée */
border:none; /* Ligne ajoutée */
}
[/code]

Marc à 15h53

Merci pour cet excellent travail! J'utilise abondamment ce calendrier.

Une petite suggestion: En attendant une éventuelle notice (c'est un gros boulot), il serait utile de publier au moins la définition des paramètres. Ils ne sont pas tous évidents à comprendre et à régler.

Marc à 19h47

Bonjour Marc,

Sur la page du configurateur il y a la liste des paramètres et leurs fonctions :
https://blog.niap3d.com/calendrier-javascript/
Dans l'historique.
C'est un peu brouillant, je me note de le refaire au propre ;-)

Patrice à 11h30

Bonjour Patrice,
Oui, mais je veux dire le nom de la fonction de chaque variable. Exemple:
[code]'divId': 'calendarMain',
'inputFieldId': 'init_abo',
'dateMask': 'AAAA-MM-JJ',
'dateCentury': 20,
[/code]etc.

Marc à 20h05

Bonjour Patrice,
Il est vraiment dommage et agaçant d'être obligé de retoucher le css à chaque implantation du calendrier sur un nouveau site. En effet divers sélecteurs ne sont pas définis dans votre CSS et de ce fait hérite des éléments parents de la page. Dans mon exemple la taille et le fond du tableau sont hérités de la page.

Patrice à 19h42

Bonjour Marc,

Ça me parait normal, c'est le principe du CSS :-)
De la même manière, si vous avez définit des styles sur des boutons (input[type=button]) ou sur les paragraphes (p), vous devrez redéfinir les attributs dont vous ne voulez pas.
À vous de l'adapter à vos besoins.

Patrice à 23h13

Bonjour Patrice, je ne sais pas si tu vas me répondre, mais j'essaie quand même, au faite je suis confronter à problème qui consiste à afficher sur un calendrier la disponibilité de mes annonces publier en fonction de leurs statuts (disponible,indisponible et déterminé), j'ai trouvé ton calendrier très sympa et donc je souhaiterais l'intégré à mon application. je précise que je travail sous symphonie 3.3 et que je suis débutant dans le développement web. ainsi j'aimerais savoir quelle fonction doit je modifier afin d'integré mes variables dans ton calendrier javascript pour qu'ils s'affiche correctement. je tiens également à te dire j'ai réussi à afficher ton calendrier dans mon projet.
merci de me répondre

cordialement

Innocent à 19h43

Bonjour Innocent,

Ce calendrier a été conçu pour choisir une date, pas réellement pour afficher des événements.

Tu peux modifier la fonction CalContentInit().
Les jours sont affichés dans la boucle
for(i = 1; i <= d.getDate(); i++)

Le jour est la variable i, le mois est définit par month et l'année par year.
A vous d'importer une liste d'événements classés par date, de faire le lien entre les deux et de gérer l'affichage.

Il faudra aussi modifier la CSS.

Patrice à 10h59

Bonjour Patrice, Merci pour ta réponse elle ma beaucoup aidé à avancer, cependant j'ai pu modifier la fonction CalContentInit() pour la affichage et la coloration sur un intervalle de date dont j'ai fixé des valeurs comme ceci:[code][/code]

me.CalContentInit = function(nb){
var deb = 15;
var fin = 30;
var i, j;
/..../
var cell = me.DomElementInit('td', {'parent': elTr, 'class': (( i>= deb && i <= fin) ? cal['classDaySelected']:cal['classDay']), 'content': i});

Par contre je remarque que cette affichage et coloration se fait également sur tous les mois qui et années suivantes et même précédentes. Du coup je souhaiterais savoir s'il était possible de bloqué cette affichage uniquement qu'à un mois précis ?

Merci.

Innocent à 11h28

Si tu veux supprimer les boutons de navigation, il faut définir navType à 00.

myCalendar.CalAdd({
'navType': '00',
[...]
});

00 = pas de navigation
01 = navigation par mois
10 = navigation par année
11 = navigation par mois et par année

Si tu veux garder les boutons mais que tu souhaite que la coloration se fasse uniquement sur un mois précis, il suffit de tester si le mois correspond à la création de la cellule :
var cell = me.DomElementInit('td', {'parent': elTr, 'class': (month == [LeNuméroMoisQueTuVeux] ? i == today ? cal['classDaySelected'] : cal['classDay'] : ''), 'content': i});

Patrice à 11h45

Merci pour tous, mais lorsque je modifie comme ceci

var cell = me.DomElementInit('td', {'parent': elTr, 'class': (month == [10] ? i == today ? cal['classDaySelected'] : cal['classDay'] : ''), 'content': i});

le calendrier ne s'affiche plus je suis complètement perdu.

Innocent à 22h23

Regarde dans la console. Je pense que la navigateur doit te signaler un problème au niveau de
month == [10]

Il faudrait plutôt écrire month == 10 (month == '10')

Patrice à 22h40

Bonjour, j'ai un petit soucis sur la version en ligne que je viens de définir, ma version marche en test et ne fonctionne pas en ligne car mon serveur sur le web est anglophone et quand je compare le jour "mercredi" et "wednesday" n'est pas pareil !
Il y a t'il moyen de forcer la langue du calendrier en français car même sur la version web il s'affiche en anglais sur un site français ...
Merci en tout cas de ce beau calendrier, je suis fan !
Hervé

Hervé à 10h31

Bonjour Hervé,

Je peux voir l'exemple en ligne pour me rendre compte ?
À tous hasard, si vous changez le format d'affichage, le problème reste présent ?

[code]calId = calObj.CalAdd({
divId: 'calendarMain',
dateMask: 'MM-JJ-AAAA'
});[/code]

Patrice à 11h41

bsr bsr. svp comment desactiver un ou plusieurs jour du mois sur un calendrier avec jsSimpleDatePickr

leonel à 14h43

Bonjour leonel,

Tu peux créer une liste des jours et les vérifier dans la fonction CalContentInit.

Dans la boucle for(i = 1; i <= d.getDate(); i++){ il faut vérifier si le jour en cours est dans la liste. Si oui, ne pas mettre d'événement onclick sur la cellule.

Je ferais une mise à jour du script dans ce sens à l'occasion.

Patrice à 16h14

Bonjour Patrice,
J'utilise régulièrement votre script avec satisfaction mais j'ai un problème.
J'ai une page avec plusieurs formulaires identiques mais avec des données différentes.
J'ai donc adapté mon script habituel comme ci-dessous.
Malheureusement, j'ai une erreur [u][i]Impossible d’obtenir la propriété « formKey » d’une référence null ou non définie[/i][/u] à la lecture du tableau de paramètres. Pourtant cette référence est reconnue à la ligne 8.
[code]
// Gestion du calendrier pour le champ action_date
// http://blog.niap3d.com/jsSimpleDatePickr
// Nouvelle version 2.1

"use strict";

console.log('8 :',fromPHPtoJS);

var cal = new jsSimpleDatePickr();

//<![CDATA[
cal.CalAdd({
'divId': 'calendarAct_'.fromPHPtoJS.formKey,
'inputFieldId': 'action_date_'.fromPHPtoJS.formKey,
'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': false
});
//]]>

document.addEventListener('click', function(e) {
if ( e.target.name != 'action_date_'.fromPHPtoJS.formKey && e.target.name != '' ) cal.CalDoFromField('action_date_'.fromPHPtoJS.formKey, 'hide');
}, false );
[/code]

Marc à 11h04

Bonjour Marc,

L'erreur se produit à quelle ligne ?

Essayez de changer 'action_date_'.fromPHPtoJS.formKey en 'action_date_'+fromPHPtoJS.formKey

Patrice à 11h16

J'ai tellement l'habitude de concaténer avec un point en php que je me suis laissé entraîné. Je n'ai plus d'erreur mais les calendriers ne sont pas appelés.

Marc à 13h47

et j'ajoute mon code php (html)
[code]<label for="action_date_<?= $n; ?>"><?= ACTION_LBL_DATE; ?></label><input type="text" name="action_date" id="action_date_<?= $n; ?>" value="<?= setPostValue('action_date'); ?>" />
<div id="calendarAct_<?= $n; ?>" class='calendarMain calendarInLine'></div><br/>
[/code]

Marc à 13h53

Si jamais ça ne va toujours pas, la fonction CalAdd renvoie l'ID du calendrier crée.
Si elle renvoie 0 ça veut dire qu'elle n'a pas trouvé l'élément divId.
Dans votre code c'est l'élément définit par 'calendarAct_'+fromPHPtoJS.formKey

Patrice à 11h30

Avec le code ci-après et avec 3 formulaires, la ligne 8 renvoie une valeur évolutive de 1 à 3.
Par contre la ligne 29 renvoie toujours 1.
Aucun calendrier ne s'affiche lors du clic sur le champ input correspondant.

Marc à 11h11

Bonjour,
J'ai toujours énormément de mal à personnaliser l'utilisation du calendrier. Il manque vraiment une notice. A ceci, il faut aussi prendre en compte les limites de mes compétences en javascript.
1) Je n'arrive pas à résoudre mon problème précédent.
2) J'ai une nouvelle difficulté:
J'ai un calendrier unique, affiché en permanence, qui sert à plusieurs champs. Je veux affecter le calendrier au champ qui a le focus.
Voici mon code qui ne marche pas:[code]"use strict";

const mainForm = document.querySelector('form')
, inputDates = mainForm.querySelectorAll("input[name*='_date']")
;

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
});
//]]>
[/code]

Marc à 16h21

Bonjour,
J'ai noté une erreur à la ligne 139 de la version 2.1:[code]if(e == 'undefined') return 0;[/code]
Lorsque le div est incorrect, la ligne précédente ne renvoie pas 'undefined' mais null.

Marc à 11h08

Bonjour Marc,

Il faudrait changer cette ligne par "if(!e) return 0;"

Mais ça ne devrait pas arriver puisque l'existance du div est vérifié avec CalAdd. Si le div n'existe pas, le calendrier n'est pas crée. Le code n'avait pas été pensé pour déplacer le calendrier sur les différents champs de la page.

Je pourrais voir un lien avec la page en développement ?

Patrice à 09h53

J'ai eu ce problème en cours de mise au point de mon code et je ne suis malheureusement plus en mesure de fournir ce code.
Ce que j'ai constaté est que la console renvoyait null sur e.
J'avais déjà fait cette correction sur ma version mais je vous le signale parce qu'il me semble qu'il faudrait modifier également l'original sur les versions 2.1 et 2.11.

Marc à 10h18

Bonjour Patrice,
Ma fonction de rappel n'est pas appelée. Quand doit-elle l'être?
Voici mon code:
[code]
"use strict";

// Fonction de rappel
function send2(date)
{
alert(date);
}

(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,
'callBack': 'send2',
'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);
}

// Cette fonction permet de masquer le calendrier quelque soit l'endroit où je clique.
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");
}
}
});

}) ();
[/code]

Marc à 11h45

Bonjour Marc,

Le paramètre callback doit être sans les guillemets je pense, puisque c'est une fonction. 'callBack'::::: send2,

Patrice à 12h34

Merci, c'est bien ça. Par contre la date transmise n'est pas bonne, ni au bon format.
Exemples:
Un clic sur 06/12/2011 renvoie 6/11/2011
Un clic sur 04/01/2012 renvoie 4/[b]0[/b]/2012
Un clic sur 04/02/2012 renvoie 4/1/2012

Marc à 17h51

La date est au format Javascript. Donc les mois vont de 0 à 11 au lieu de 1 à 12 comme chez les gens normaux :-)

Patrice à 18h52

OK, merci.

Marc à 19h27

Bonjour Patrice,
Je ne sais pas si vous allez pouvoir m'aider. Avec le code transmis hier, je voudrais enregistrer (envoi du formulaire) la nouvelle date, dès la mise à jour du champ par le calendrier. Lorsque j'essaye de le faire, c'est la date avant mise à jour qui est prise en compte au lieu de la nouvelle. Mon script est prévu pour fonctionner sur plusieurs champs, de ce fait est-il possible de récupérer l'attribut inputFieldId?

Marc à 11h14

Bonsoir Marc,

Vous pouvez ajouter un écouteur input sur les champs.
Ainsi dès que le champ est modifié l'évenement est envoyé :
- https://developer.mozilla.org/fr/docs/Web/API/HTMLElement/input_event

Patrice à 20h48

J'avais déjà essayé avant de vous poser la question mais l'événement n'est pas déclenché.

Marc à 22h50

vous avez un exemple en ligne ?

Vous avez essayez avec change aussi ?

Patrice à 22h57

Voici: https://jsfiddle.net/moimp/f16h50q4/8/. C'est la première fois que j'utilise jsfiddle et je ne sais pas trop comment m'en servir.

Marc à 16h16

Ok, je vois deux solutions :
:
1) La plus élégante :
Rajouter un callback sur les calendriers et dans la function de callback créer un formulaire avec l'API formData et envoyer les données
https://developer.mozilla.org/fr/docs/Web/API/FormData/Utilisation_objets_FormData

2) La moins élégante
Ajouter un timer sur les champs input et contrôler sur la valeur à été modifier. Et, si c'est le cas, envoyer le formulaire avec document.NOM_DU_FORMULAIRE.submit();
À l'initialisation vous pouvez enregistrer la valeur par défaut dans un attribut data-
https://developer.mozilla.org/fr/docs/Web/API/HTMLElement/dataset

Patrice à 17h54

Je ne m'en sors pas.
Voici le code de ma fonction:[code]"use strict";

(function(){

let myCalendar = new jsSimpleDatePickr()
,mainForm = document.querySelector('.cardForm')
,inputs = mainForm.querySelectorAll("input[name*='_date']")
,max = inputs.length
,params
,calendarId
;
console.log(editFile);
console.log(mainForm);
console.log(inputs);

// Handle calendars
function pick(date)
{
var formData = new FormData(),
request = new XMLHttpRequest()
;

for (let i=0; i<max; i++)
{
formData.append(inputs[i].name, inputs[i].value);
request.open('$_POST', editFile); // false
request.send(formData);
}
}

// Prepare
for (let i = 0; i < max; i++) {
let inputId = inputs[i].id;
params = {
'divId': inputId.substring(0, inputId.indexOf('_')) + 'Calendar',
'inputFieldId': inputId,
'callBack': pick,
'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);
}

// Mask
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");
}
}
});
[/code]
J'ai activé la console réseau qui pour chaque champ me donne le résultat suivant:
/frontend/controllers/editField.php?field=source_date avec résultat=200.

J'ai vérifié le code editField.php qui fonctionne pour les champs qui ne sont pas des dates.

Marc à 16h30

Bonjour Marc,

Attention dans la fonction pick() il y a une erreur. Il faut créer l'objet FormData (ça c'est OK), ajouter chacune des valeurs à envoyer et ensuite seulement envoyer l'objet avec send().

Il faut donc sortir ces deux lignes de la boucle for
request.open('$_POST', editFile); // false
request.send(formData);

Patrice à 17h06

Bonjour Patrice. D'abord un grand merci pour ce code!

J'ai un petit soucis que j'ai contourné, mais peut-être que je me suis compliqué la vie...

J'utilise votre script pour l'affichage de réservation de salle. L'idée est que l'utilisateur peut naviguer heure par heure dans les réservations et que quand il dépasse les heures ouvrables, il saute directement au jour d'avant ou d'après.

En lisant les différentes question ci-dessus, j'ai légèrement modifié la fonction CalDateInit pour pouvoir lui passer un ID ou un NB(je n'ai qu'un seul calendrier sur la page).

Du coup arrivée à une heure précise, j'exécute CalDateInit suivi de de CalContentInit. Et ça fonctionne nickel, j'ai juste un léger soucis d'affichage de la dénomination du mois(Mais c'est surement une bêtise de mon côté qui devrait être vite réglée).

Ma question est donc simplement de savoir si le chemin que j'ai pris est le "meilleur".
ou si j'ai réinventé la poudre ?

qouet à 17h00

Bonjour Patrice,

Je souhaite utiliser un calendrier unique pour plusieurs champs. Je me réfère à votre message du 15/06/2017 à 18h08 avec le code suivant (simplifié):[code]const
dates = document.querySelectorAll("[id*='date_']")
;

var max=dates.length
,inputForCal
;

var cal = new jsSimpleDatePickr();

for (let i=0;i<max;i++) {
dates[i].addEventListener('focus', function(e) {
inputForCal = dates[i].id;
cal.CalShow(inputForCal);
}, false );
}
document.addEventListener('DOMContentLoaded', function() {
inputForCal = dates[0].id;
}, false );
if (inputForCal === undefined) {
inputForCal = dates[0].id;
cal.CalShow(inputForCal);
}

cal.CalAdd({
'divId': 'tradingCalendar',
'inputFieldId': inputForCal,
'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
});
[/code]
MAUVAIS FONCTIONNEMENT: Quelque soit le champ sélectionné (qui détient le focus), c'est toujours le champ par défaut qui est mis à jour.

Marc à 10h32

Je voudrais savoir comment créer un script pour prendre un rendez vous sur un site ou il ya beaucoup de charge, beaucoup de personnes qui prennent un rendez vous en même temps, ou les places sont limités, j'ai essayé de prendre le rendez vous plusieurs fois moi même, mais à chaque fois les rendez vous disparaissent rapidement, et le site beugue tellement il ya beaucoup de personnes essayent de prendre un rendez vous en même temps.

PS : je ne suis pas du domaine, pourriez vous m'expliquer avec un langage simplifié, si j'ai recours à ceci, c'est parce que c'est ma dernière chance d'avoir un rendez vous à temps pour passer mon test.

Merci par avance.

elmehdi kitabrhi à 12h40

Ajouter votre commentaire

Votre adresse ne sera pas affichée.

Elle sert à vous envoyer une notification.