fgtoul
1
Bonjour Ă tous,
voici un widget permettant de modifier directement les attributs d’un objet Calendrier existant sur un Dashboard de l’IPX800 V5, sans aller en configuration de l’objet. Ce widget devra être installé sur un Dashboard, il n’est pas compatible avec le Liveview.
Avec l’outil API Deck, récupérez l’ID du calendrier à modifier, puis modifiez la variable myCalendar dans le code.
Le code étant assez long, je ne l’ai pas alourdi avec des contrôles comme date fin doit être supérieure à date début, etc. L’utilisateur devra lui-même faire attention à la cohérence des valeurs entrées.
Une led verte signale que la mise à jour s’est bien passée.
code remplacé, voir plus bas
bonne utilisation
j’ai développé le code sur mon téléphone, il est sans doute optimisable mais il est fonctionnel à 100%
EDIT : un code optimisé est fourni plus bas.
2 « J'aime »
Bonjour,
Très bonne idée, je n’ai peut être pas tout compris, je n’arrive pas à créer plusieurs objets calendrier,
Merci
Bonne soirée
fgtoul
3
je suis en train d’optimiser le code. pour créer plusieurs widgets, il faudra un iframe.
Pardon,
Je trouve cela tellement pratique pour gérer mes volets
1 « J'aime »
fgtoul
5
voici un code avec css optimisé:
<style>
.led {
width: 1em;
height: 1em;
border-radius: 50%;
background-color: #999;
position: absolute;
top: 0.1em;
right: 0.5em;
}
.bton {
font-size: 1em;
margin-top: 1.4em;
padding: 0.5em 1em;
border: none;
border-radius: 0.5em;
cursor: pointer;
}
.form-table {
display: grid;
grid-template-columns: 40% 50%;
gap: 0.5em;
align-items: center;
font-size: 1em;
height:65%;
}
.form-table label {
text-align: right;
padding-right: 0.5em;
font-size: 0.8em;
margin-top: 0.3em;
}
.form-table input, .form-table select {
width: 100%;
padding: 0.1em;
font-size: 1em;
height: 1.3em;
}
/* Pour les navigateurs basés sur WebKit (Chrome, Safari, Edge) */
.form-table select option {
background-color: #f0f0f0;
color: #333;
}
/* Pour Firefox */
.form-table select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #000;
}
.form-table select option:checked {
background-color: #4CAF50;
color: white;
}
</style>
<script>
var myCalendar=1507328;
window.GCE_Refresh.push(function(data) { //IMPORTANT: binding refresh function to the WebSocket
switch (data['_id']) {
case myCalendar:
parseCalendar(data);
break;
}
});
function init() {
GCE_API.get('api/object/calendar/' + myCalendar)
.then((ret) => { // ask for the actual value
parseCalendar(ret);
}).catch((err) => {
alert(err);
});
}
function parseCalendar(mydata){
document.getElementById("calendarName").value=mydata.name;
document.getElementById("frequence").value=mydata.mode;
document.getElementById("date1").value=initDate(mydata.start_date);
document.getElementById("time1").value=mydata['start_time'];
document.getElementById("date2").value=initDate(mydata.end_date);
document.getElementById("time2").value=mydata.end_time;
}
function formaterDate(maDate){
var date= new Date(maDate);
var jour=("0"+date.getDate()).slice(-2);
var mois=("0"+(date.getMonth() +1)).slice(-2);
var annee=date.getFullYear();
return jour+"/"+mois+"/"+annee;
}
function initDate(madate){
var composants=madate.split("/");
return composants[2]+"-"+composants[1]+"-"+composants[0];
}
function toggleDatepicker() {
var frequence = document.getElementById("frequence").value;
var date1 = document.getElementById("date1");
var labelDate1 = document.getElementById("label-date1");
var date2 = document.getElementById("date2");
var labelDate2 = document.getElementById("label-date2");
if (frequence != "0" && frequence != "32") {
date1.disabled = true;
date2.disabled=true;
} else {
date1.disabled = false;
date2.disabled=false;
}
}
function changeColor(ok) {
var div = document.getElementById("led2");
div.style.backgroundColor = ok ? "#1fdb49" : "red";
setTimeout(function() {
div.style.backgroundColor = "#999"; }, 1000);
}
function valider(){
var calendrier={
_id: myCalendar,
name: document.getElementById("calendarName").value,
mode: parseInt(document.getElementById("frequence").value),
start_date: formaterDate(document.getElementById("date1").value),
start_time: document.getElementById("time1").value,
end_date: formaterDate(document.getElementById("date2").value),
end_time: document.getElementById("time2").value
};
GCE_API.put('api/object/calendar/'+myCalendar, calendrier).then((ret) => {
changeColor(true);
console.log("OK ", ret);
}).catch((err) => {
changeColor(false);
console.error("KO ", err);
});
}
init();
toggleDatepicker();
//init();
</script>
<div id="led2" class="led"></div>
<div class="form-table">
<label id="label1" for="calendarName">Nom :</label>
<input type="text" id="calendarName" name="calendarName" maxlength="20">
<label id="label2" for="frequence">Fréquence :</label>
<select id="frequence" name="frequence" onchange="toggleDatepicker()">
<option value="0" selected>Pas de récurrence</option>
<option value="1">Lundi</option>
<option value="2">Mardi</option>
<option value="3">Mercredi</option>
<option value="4">Jeudi</option>
<option value="5">Vendredi</option>
<option value="6">Samedi</option>
<option value="7">Dimanche</option>
<option value="10">Tous les jours</option>
<option value="20">Jours de travail</option>
<option value="21">Avant jours de travail</option>
<option value="30">Week-end</option>
<option value="31">Avant week-end</option>
<option value="32">Chaque année</option>
</select>
<label for="date1" id="label-date1">Date de début :</label>
<input type="date" id="date1" name="date1" lang="fr">
<label id="label-time1" for="time1">Heure de début :</label>
<input type="time" id="time1" name="time1" step="1">
<label for="date2" id="label-date2">Date de fin :</label>
<input type="date" id="date2" name="date2" lang="fr">
<label id="label-time2" for="time2">Heure de fin :</label>
<input type="time" id="time2" name="time2" step="1">
</div>
<button class="widget-color bton neumorphism no-hover" onclick="valider()">Valider</button>
J’ai testé l’inclusion dans un iFrame, l’API ne fonctionne plus, il faudrait tout réécrire.
2 « J'aime »
Voila ce que j’obtiens maintenant,
fgtoul
7
copiez à nouveau le code, j’ai apporté une petite modif pour un affichage plus responsive.
Le widget ne tiendra pas dans un format 1x2, il faut un 2x2
Pour créer plusieurs widgets sur un même dashboard, il faut renommer les variables, les id des balises html et les fonctions.
Malheureusement on ne profite pas des fonctions du serveur de l’ipx qui font ça automatiquement à la création d’un widget.
EDIT : voir la solution plus bas
1 « J'aime »
Bonjour @fgtoul
Merci
Pour l’instant cela fonctionne uniquement sur mon Mac, erreur sur IPHONE et IPAD.
Je vais chercher pour changer les fonctions, pas de problème pour les id
Bonne journée
Bernard
fgtoul
9
Je vais voir s’il est possible de faire un Get ALL Calendars pour remplir une liste qui permettrait de sélectionner le calendrier à modifier parmi la collection complète.
MĂŞme si cela alourdi le code, je pense que ce sera quand mĂŞme moins lourd que plusieurs widgets de 5ko chacun.
fgtoul
10
voici le widget capable de modifier sur Dashboard tout calendrier existant sur ipx800 v5.
Il suffit de sélectionner le calendrier à modifier dans une liste, puis valider après modification des paramètres.
J’ai désactivé la possibilité de renommer les calendriers afin d’éliminer le risque de noms en doublons si erreur de frappe.
<style>
.l {
width: 0.9em;
height: 0.9em;
border-radius: 50%;
background-color: #999;
position: absolute;
top: 0.1em;
right: 0.5em;
}
.btn {
font-size: 0.9em;
margin-top: 2.8em;
padding: 0.2em 1em;
border: none;
border-radius: 0.5em;
cursor: pointer;
}
.tbl {
display: grid;
grid-template-columns: 35% 55%;
gap: 0.2em;
align-items: center;
font-size: 0.9em;
height: 65%;
}
.tbl label {
text-align: right;
padding-right: 0.5em;
font-size: 0.7em;
margin-top: 0.3em;
}
.tbl input, .tbl select {
width: 100%;
padding: 0.1em;
font-size: 0.9em;
height: 1.4em;
}
.tbl select option {
background-color: #f0f0f0;
color: #333;
}
.tbl select:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #000;
}
.tbl select option:checked {
background-color: #4CAF50;
color: white;
}
</style>
<script>
var cal = 1507328;
window.GCE_Refresh.push(function(d) {
if (d['_id'] === cal) parseCal(d);
});
function loadCal() {
cal = document.getElementById("col").value;
GCE_API.get('api/object/calendar/' + cal)
.then(parseCal)
.catch(alert);
}
function listCal() {
GCE_API.get('api/object/calendar').then((data) => {
var lst = document.getElementById("col");
data.forEach((itm, i) => {
var opt = document.createElement("option");
opt.value = itm._id;
opt.text = itm.name;
if (i === 0) opt.selected = true;
lst.appendChild(opt);
});
loadCal();
}).catch(alert);
}
function parseCal(d) {
document.getElementById("calName").value = d.name;
document.getElementById("freq").value = d.mode;
document.getElementById("d1").value = initDate(d.start_date);
document.getElementById("t1").value = d['start_time'];
document.getElementById("d2").value = initDate(d.end_date);
document.getElementById("t2").value = d.end_time;
}
function fmtDate(dt) {
var d = new Date(dt);
return ("0" + d.getDate()).slice(-2) + "/" + ("0" + (d.getMonth() + 1)).slice(-2) + "/" + d.getFullYear();
}
function initDate(d) {
var c = d.split("/");
return c[2] + "-" + c[1] + "-" + c[0];
}
function toggleDP() {
var f = document.getElementById("freq").value;
var d1 = document.getElementById("d1");
var d2 = document.getElementById("d2");
d1.disabled = d2.disabled = (f !== "0");
}
function setLed(ok) {
var l = document.getElementById("l2");
l.style.backgroundColor = ok ? "#1fdb49" : "red";
setTimeout(() => l.style.backgroundColor = "#999", 1000);
}
function saveCal() {
var calData = {
_id: cal,
name: document.getElementById("calName").value,
mode: parseInt(document.getElementById("freq").value),
start_date: fmtDate(document.getElementById("d1").value),
start_time: document.getElementById("t1").value,
end_date: fmtDate(document.getElementById("d2").value),
end_time: document.getElementById("t2").value
};
GCE_API.put('api/object/calendar/' + cal, calData).then(() => {
setLed(true);
}).catch(() => {
setLed(false);
});
}
listCal();
toggleDP();
</script>
<div id="l2" class="l"></div>
<div class="tbl">
<label for="col">Calendrier :</label>
<select id="col" onchange="loadCal();"></select>
<label for="calName">Nom :</label>
<input type="text" id="calName" disabled>
<label for="freq">Fréq. :</label>
<select id="freq" onchange="toggleDP();">
<option value="0" selected>Pas de récurrence</option>
<option value="1">Lundi</option>
<option value="2">Mardi</option>
<option value="3">Mercredi</option>
<option value="4">Jeudi</option>
<option value="5">Vendredi</option>
<option value="6">Samedi</option>
<option value="7">Dimanche</option>
<option value="10">Tous les jours</option>
<option value="20">Jours de travail</option>
<option value="21">Avant jours de travail</option>
<option value="30">Week-end</option>
<option value="31">Avant week-end</option>
<option value="32">Chaque année</option>
</select>
<label for="d1">Début :</label>
<input type="date" id="d1" lang="fr">
<label for="t1">Heure :</label>
<input type="time" id="t1" step="1">
<label for="d2">Fin :</label>
<input type="date" id="d2" lang="fr">
<label for="t2">Heure :</label>
<input type="time" id="t2" step="1">
</div>
<button class="btn" onclick="saveCal()">Valider</button>
Développé et testé sur téléphone. L’apparence peut être différente sur PC.
Attention, ce widget est lourd. J’ai donc optimisé les noms de variables sans dégrader la lisibilité. En minifiant le code nous pourrions encore gagner 1,2 ko (48%), voire 1.3ko (50%) en remplaçant chaque appel de getElementById() par une fonction « g » par exemple mais cela deviendrait difficilement lisible. C’est donc recommandé de ne pas le faire avant la mise en place définitive.
3 « J'aime »
Cela fonctionne très bien avec un nouveau Dashboard, pas sur IPHONE et IPAD,
Merci de ce que vous faites pour nous.
Bernard
1 « J'aime »
fgtoul
12
sur iPhone et iPad, utilisez vous le navigateur ou bien l’application IPX800 V5 ?
Bonjour,
Après vérification cela fonctionne avec Safari, pas avec l’application.
Bonne journée
Bernard
1 « J'aime »
Bonjour,
je confirme que avec l’appli V5 sur Iphone, le widget s’affiche mais la liste de calendriers est vide (affiche No Options quand on clique).
Bonne journée
fgtoul
15
Bonjour,
je pense que l’API Widget HTML ne fonctionne pas dans l’appli.
Il faudrait donc développer sans l’API, mais nous avions vu par le passé que c’était trop agressif pour l’API REST (d’où la mise en place de l’API Widget)
Test réalisé avec application sous Androïd, ne fonctionne pas non plus.
Mais en affichant l’IHM avec un navigateur sur le smartphone, cela fonctionnera.
Bonjour,
Ca ne fonctionne pas chez moi : message 400 “taille du contenu invalide” au moment de valider le widget. Celui-ci fonctionne bien mais le script n’est pas mémorisé quand on quitte le dashboard.
Cordialement
fgtoul
17
Bonjour
Ce n’est pas un problème de widget mais de taux d’occupation du dashboard. Avez-vous essayé sur un autre dashboard.?
Bonne journée
Bonsoir,
Effectivement ça fonctionne sur un autre dashboard. Merci.
Bonne soirée