Informations codage widget

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

8 J'aimes

Bel exposé, je vais étudier ça à tête reposée.
Bonne soirée.

Bonjour,

Très utile ce début de tuto. Merci

Sais-tu comment on force le non affichage du nom d’une commande info bin d’un virtuel.
Sachant que j’ai mon code pour l’affichage de cette info/bin. Et que j’ai beau décocher afficher nom dans l’onglet Affichage du paramétrage de cette commande, le nom apparait (ce qui est forcément lié à mon code mal fait) ?

Salut,

en V4 tu devrais avoir un bout de code comme ça concernant l’affichage du nom de la commande et la possibilité de le faire disparaître en décochant “afficher le nom”:

<div class="title #hide_name#">
    <div class="cmdName">#name_display#</div>
  </div>

N’hésites pas à partager le code de ton widget si tu ne t’en sors pas…

Le code a changé entre la V3 et la V4, je vais l’ajouter a l’article

Mon code actuel :

<!-- Widget affichage caméra http
	CamURL : URL http de la caméra (si vide icon CAM IP off)
	CamH : Hauteur du widget (défaut 180)
	CamW : Largeur du Widget (défaut 320)
 -->
<div style="iconStyle#uid#" class="cmd #history# tooltips cmd-widget container-fluid" data-type="info" data-subtype="binary" data-cmd_id="#id#" data-cmd_uid="#uid#" title="#collectDate#">
	<div class="row">
		<div class="center-block col-xs-12 h5 cmdName" id="cmdName#id#" style="margin-top:0; #hideCmdName#;">#name_display#</div>
		<div class="center-block col-xs-12 iconCmd#uid#"></div>
	</div>


  <style>
    .iconCmd#uid# {
      margin:4px 4px 4px 4px;
    }
  </style>
  <script> 

	jeedom.cmd.update['#id#'] = function(_options){
 	  var valueH = is_numeric('#CamH#') ? parseFloat('#CamH#'):180;
      var valueL = is_numeric('#CamW#') ? parseFloat('#CamW#'):320;
      //(".iconCmd#uid#").empty();
      if (parseInt(_options.display_value) == 1) {
      //if ('#state#' == '1' || '#state#' == 1) {
        var valueFile = ('#CamURL#' != '') ? "#CamURL#":"plugins/widget/core/template/dashboard/cmd.action.other.Cam_IP/off.png";
      } else {
        var valueFile = "plugins/widget/core/template/dashboard/cmd.action.other.Cam_IP/off.png";
      }
      $('.iconStyle#uid#').empty().append('padding:0px;width:'+valueL+';height:'+valueH);
      $('.iconCmd#uid#').empty().append('<img src="'+valueFile+'" width=100% height=100%/>');
  
      $('.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#'});
  </script>
</div>

Tu vas trouver ta réponse en bas de l’article que je viens de mettre a jour

Merci à vous 2.

Attention le code que tu as mis pour le nom de la commande en V4 est incomplet. C’est le code que j’ai mis quelques messages au-dessus qui est utilisé en V4

Tu devrais regarder un widget comme IconInfo pour ce genre de widget info binaire. Tu n’aurais qu’un seul widget pour toutes tes info binaire en mettant l’image qui va bien + plein d’options :innocent:

tu es sur ? pour moi c’est la même chose, tu n’es pas obligé d’avoir 2 balises DIV

Les widgets core sont codés comme ça en fait et comme je suis discipliné je fais pareil :slight_smile: après je me dis que s’ils ont prévu comme ça avec une classe “title” et tout c’est qu’il doit y avoir une raison. Ça ne change sûrement pas grand chose c’est vrai c’est surtout que j’ai cru que t’avais loupé un copier/coller :dizzy_face:

Désolé du dérangement :zipper_mouth_face:

pas de soucis, j’ai pu faire une erreur en effet, c’est le code que m’avais donné Loïc, je l’avais testé rapidement mais comme je suis revenu en V4 je préférais te demander

je vais mettre les 2 codes

Pas faux. Je vais optimiser.

EDIT : @Salvialf
En regardant le code iconinfo, c’est OK pour les dimensions en param, mais je vois mal comment je peux passer des url de stream HTTP sans toucher au code iconinfo.
Exemple de variable CamURL = http://192.168.1.9:81/stream que je passe en param dans le virtuel à mon code ci-dessus.

Et le code iconinfo formate l’icône à afficher comme ceci :

var iconPath = "plugins/widget/core/template/dashboard/cmd.info.binary.IconInfo/"+valueType+"_"+valueState+"."+valueFile;

ou alors faudrait que mon url de straming soit dans fic (html ou je ne sais quoi) pour que la commande qui suit dans le code iconinfo :

$('.iconCmd#uid#').empty().append('<img src="'+iconPath+'" '+paramTaille+'>');

prenne en compte ?

Ah mince j’avais pas fait gaffe que tu passais un flux de caméra donc effectivement IconInfo est juste prévu pour afficher une image :roll_eyes:

Super post ca c’est de la doc :wink:

Tu n’as plus qu’à créer tes Widgets
:wink: