Bonjour à tous
Je remets ici un post de l’ancien forum
Avec une tentative d’explication sur le codage des widgets
ces informations m’ont manquées pour la correction de mes widgets
Merci à ceux qui m’ont fournit ces infos (@salvialf@, @Cadavor, @Claude69, @JAG, @domoggvad, @mich0111, …)
Si il y a des erreurs, je m’en excuse par avance, n’hésitez pas à me corriger
PRINCIPE DE BASE :
Le bon codage des widgets, permet de rafraîchir une information (texte, image, icone, …) dans une vignette sans que toute la page soit rafraîchir.
Les informations qui ne changent pas : le label d’une commande, l’unité d’une valeur, n’ont pas besoin d’être mise à jour. Elles le seront automatique si vous modifiez ces informations dans votre virtuel lors de la sauvegarde.
Donc pour tout ce qui change souvent, la température d’une sonde, l’image d’une prise, … il faut que ce soit codé dans le widget.
CORPS DU WIDGET
jeedom.cmd.update['#id#'] = function(_options){
[...]
$('.cmd[data-cmd_id=#id#]').attr('title','Valeur du '+_options.valueDate+', collectée le '+_options.collectDate);
}
jeedom.cmd.update['#id#']({display_value:'#state#',valueDate:'#valueDate#',collectDate:'#collectDate#',alertLevel:'#alertLevel#'});
CODAGE DU WIDGET :
Pour l’affichage des informations, le widget est composé de balise html DIV ou SPAM entre autre.
Pour que l’information contenue dans ces balises soit mise à jour, il faut qu’elle est une CLASS
Cette CLASS sera utilisée comme référence pour lancer la mise à jour de la valeur
EXEMPLE avec l’information STATE :
Je veux afficher la valeur de ma commande et qu’elle soit mise à jour en automatique
J’ai donc ma balise SPAN :
<span class='label label-info' style="font-size: 10px;">#state#</span>
J’utilise le code suivant dans SCRIPT pour lui dire d’afficher la valeur value correspondant à #state#
$('.label-info').text(_options.display_value);
il est possible de faire référence à plusieurs class dans la même ligne
$('.label-info, .label-info,2 .label-info3').text(_options.display_value);
On retrouve le .label-info qui fait référence à cette même valeur dans la balise class du span
Si la valeur est suivi de l’unité, rien de plus à faire que d’ajouter #unite# après le #state# dans la balise SPAN, puisque cette information ne va pas évoluer et de l’ajouter dans la partie script sous la forme
$('.label-info').text(_options.display_value+' #unite#');
Si vous voulez ajouter un texte après la valeur, par exemple un % qui ne serait pas dans l’unité, il suffit de faire ca
$('.label-info').text(_options.display_value + '%');
il est également possible d’ajouter du code HTML dans une balise DIV par exemple
$('.label-info').html('<i class='icon jeedom-off'></i>');
VIDER LES INFORMATIONS PRECEDENTES :
Il est possible de vider l’info ou l’image présente, afin d’éviter l’effet double image.
Soit pour tout, il faut alors ajouter : $('.iconCmd').empty();
après l’appel de la fonction
Soit pour une commande, en ajout : .empty()
Exemple : $('.label-info') .empty() .html(_options.display_value + '%');
CACHER UNE INFORMATION :
En ajoutant .hide()
Exemple : $('.label-info').hide();
EXEMPLE AVEC UNE VALEUR DANS UNE BALISE IMAGE
Si vous voulez mettre à jour une image (par exemple provenant d’une caméra)
C’est une balise IMG qui faut utiliser
<img class"iconCmd" style="width:180px" width="180px" src="core/php/downloadFile.php?pathfile=/tmp/jeedom/ftpd/ftpd_records#state#" />
On retrouve la balise CLASS et le #state# dans le nom de l’image qui sera utilisée
Pour la partie SCRIPT, on garde le même principe mais là c’est dans un attribut de l’image que l’on change la valeur, donc utilisation de .attr
$('.iconCmd').attr('src', "core/php/downloadFile.php?pathfile=/tmp/jeedom/ftpd/ftpd_records" + _options.display_value);
EXEMPLE AVEC DES ICONES OU IMAGES
Là c’est plusieurs icones possible pour une même zone, donc on à la balise DIV ou SPAN qui va recevoir l’icone
<span style="font-size: 2.5em; font-weight: bold; margin-top: 5px;" class="iconCmd"></span>
et on code les test avec l’envoi de l’icone
if (_options.display_value == "Fermé") { $('.iconCmd').append('<i class="fa fa-eye-slash"></i>'); }
if (_options.display_value == "Ouvert") { $('.iconCmd').append('<i class="fa fa-eye"></i>');}
on retrouve toujours la référence .iconCmd qui fait le lien entre le SPAN et le code, mais le nom peut être changé
Après dans le contenu du append, qui peut être remplacé par html, on retrouve le code HTML, qui peut être l’affiche d’un icone comme ci-dessus ou d’une image avec une balise IMG
Exemple :
$('.iconCmd').empty().append('<img src="plugins/widget/core/template/dashboard/cmd.action.other.ActifInactifSlide/ToggleSlide_ON.png" />');
NDA : il doit surement y avoir une différence entre ces 2 attribues append et html ?
VALEURS COLLECTÉES :
Les 2 dernières lignes de la partie SCRIPT du Widget :
Pour afficher les informations de mise à jour au passage de la souris sur la vignette
$('.cmd[data-cmd_id=#id#]').attr('title','Valeur du '+_options.valueDate+', collectée le '+_options.collectDate);
jeedom.cmd.update['#id#']({display_value:'#state#',valueDate:'#valueDate#',collectDate:'#collectDate#',alertLevel:'#alertLevel#'});
AJOUTER LA DUREE
Par exemple la durée d’ouverture ou de fermeture d’une fenêtre
<span class="timeCmd#uid#" style="background-color:#cmdColor# !important;padding : 3px;border-radius: 4px"></span>
jeedom.cmd.displayDuration(_options.valueDate, $('.timeCmd#uid#'));
WIDGET ACTION
Là c’est un peu plus compliqué, je pige pas trop le système avec les show et le hide
Il faut dans un 1er temps, tester la valeur, qui peut être numérique et/ou alpha
if (_options.display_value == 1 || _options.display_value == 'on') {
Puis, c’est là que je décroche, on teste le nom de la commande « name » avec une fonction normalizeName, s’il contient « on » ou « off »
NDA: mais est-ce que cela implique que les 2 commandes actions, doivent avoir ON et OFF dans le nom ?
if (jeedom.cmd.normalizeName('#name#') == 'on') {
$('.cmd[data-cmd_id=#id#]').hide();
}else{
$('.cmd[data-cmd_id=#id#]').show();
$('.cmd[data-cmd_id=#id#] .iconCmd').empty().append('IMAGE QUAND ON');
}
} else {
if (jeedom.cmd.normalizeName('#name#') == 'off') {
$('.cmd[data-cmd_id=#id#]').hide();
}else{
$('.cmd[data-cmd_id=#id#]').show();
$('.cmd[data-cmd_id=#id#] .iconCmd').empty().append('IMAGE QUAND OFF');
}
ce que j’en comprends :
Si la valeur retournée par le clique sur l’image (résultat de la commandes action) retourne 1 ou on
alors si le nom de ma commande action contient « on » alors je la cache, sinon je l’affiche avec l’image indiquée, correspondant au ON
Si la valeur retournée est ni 1, ni on, donc par déduction 0 ou off
alors si le nom de ma commande action contient off alors je la cache, sinon je l’affiche avec l’image indiquée, correspondant au OFF
GESTION DE PLUSIEURS COMMANDES DANS UN WIDGET
CAS 1 : Plusieurs commandes mise à la suite, séparées par une virgule dans un commande principale où sera appliqué le widget
exemple avec 3 commandes :
// Récupération des valeurs de la commande
var state = _options.display_value;
var teststate = state.indexOf(",");
if ( teststate > 0 && teststate < 3 ) {
var stateListe = state.split(",");
var commande1= stateListe[0];
var commande2= stateListe[1];
var commande3= stateListe[2];
}
On récupère la valeur qui est en fait composée des 3 valeurs des commandes séparées par une , et on l’affecte à des variables que l’on pourra ensuite réutiliser. On peut le faire avec uniquement
commandes ou beaucoup plus
L’avantage de cette méthode par rapport à la suivante, c’est que vous créez une seule commande spéciale pour le widget avec le nom que vous voulez. Inconvénient, il faut mettre dans la valeur de al commande, les liens vers les commandes indiquées par le widget, il faut respecter l’ordre et le contenu. et dans un design. Autre avantage, vous pouvez appeler directement la commande dans un design.
CAS 2 : Plusieurs commandes où on appliquera le widget
Là il faut, dans la cas de l’exemple du code que je vais donner, mais il semble que cela puisse s’améliorer, nommer des commandes avec le nom utilisé dans le code et pour l’ajouter dans un design, il faudra ajouter l’équipement, avec parfois l’obligation de faire un virtuel dédié.
var valeur = parseFloat(_options.display_value);
var widget = $('.cmd[data-cmd_id=#id#]').closest('.eqLogic').find('.widget-AfficheurMulti:first');
if('#name#' == 'PuissanceMax'){
widget.find('.zone1').text(valeur.toFixed(1)).attr('title','Valeur du '+_options.valueDate+', collectée le '+_options.collectDate);
widget.find('.zone1Unite').text('#unite#/#maxValue#');
}
if('#name#' == 'IntensiteMax'){
widget.find('.zone2').text(valeur.toFixed(1)).attr('title','Valeur du '+_options.valueDate+', collectée le '+_options.collectDate);
widget.find('.zone2Unite').text('#unite#/#maxValue#');
}
setTimeout(function(){
if($('.cmd[data-cmd_id=#id#]').closest('.eqLogic').find('.widget-AfficheurMulti').length > 1){
$('.cmd[data-cmd_id=#id#]').closest('.eqLogic').find('.widget-AfficheurMulti:not(:first)').hide();
}
},100)
Merci à @Salvialf qui m’a fait découvrir cette possibilité avec son plugin LINKY_V4
Le principe est que l’on va rechercher le nom du widget dans les commandes, puis rechercher le nom des commandes pour en récupérer les valeurs.
Il faut bien que le widget soit tagué,. dans l’exemple ‹ widget-AfficheurMulti ›
<div class="cmd cmd-widget #history# widget-AfficheurMulti" data-type="info" data-subtype="numeric" data-template="AfficheurMulti" data-cmd_id="#id#" data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#">
AFFICHAGE DU NOM AVEC GESTION DE LA CASE A COCHER POUR LE CACHER
EN V3
<div class="cmdName" style="#hideCmdName#">#name_display#</div>
EN V4
<div class="cmdName #hide_name#">#name_display#</div>
OU (référence Widget Core, merci @Salvialf)
<div class="title #hide_name#">
<div class="cmdName">#name_display#</div>
</div>
NB : la balise « title » a t’elle une importance ?
AJOUTER/ENLEVER UN PARAMETRE (exemple « Checked » dans balise INPUT)
Ajouter : $('.Toggle#uid#').prop('checked', True);
Enlever: $('.Toggle#uid#').prop('checked', False);
SUPPRIMER UNE BALISE
<div class="value">
<span class="timeCmd label label-default #history#" data-type="info"></span>
</div>
$('.timeCmd').parent().remove();
Voici ce qui j’ai pu réunir, j’espère qu’il n’y a pas trop d’erreur,…
j’ai mis les questionnements qui persistes en NDA, si qqun peut les éclaircies, merci d’avance
Et si vous avez d’autres informations, n’hésitez pas à compléter