Probléme de menu dynamique

Bonjour,

Je partage avec vous, mon dernier blocage.
J’ai un script qui va chercher une liste pour un menu déroulant, dans un dossier.
Le code PHP est appuyé par le Javascript qui exécute Ajax pour accéder au fichier.

Mon problème est à chaque rechargement de la page, et donc sauvegarde. Le menu se réinitialise , et la valeur sélectionnée disparait.

ProJote.php

<...>
<div class="col-sm-6">
		<select class="eqLogicAttr form-control" id="enfantList" data-l1key="configuration" data-l2key="enfant">

		</select>
</div>
<...>

ProJote.js

<...>
//Je fais une liste pour enfantList
// Définir la fonction updateDropdown en dehors de toute autre fonction
function updateDropdown(data) {
  var selectElement = document.getElementById('enfantList');
  var currentValue = selectElement.value; // Récupérer la valeur actuelle du champ

  console.log('Réponse de la requête pour la sélection AJAX :', data);
  // Effacer les options existantes
  selectElement.innerHTML = '';
  // Ajouter les nouvelles options à la liste déroulante, sauf si elles sont vides
  data.forEach(function (value) {
    if (value.trim() !== '') {
      var option = document.createElement('option');
      option.value = value;
      option.textContent = value;
      selectElement.appendChild(option);
    }
  });

  // Vérifier si la valeur actuelle est présente dans la liste
  var optionExists = Array.from(selectElement.options).some(function (option) {
    return option.value === currentValue;
  });

  // Si la valeur actuelle est présente, la rétablir
  if (optionExists) {
    selectElement.value = currentValue;
  }
}


// Déclarer une variable globale pour stocker la valeur sélectionnée
var selectedValue = '';

// Action sur le drop down du menu list
document.getElementById('enfantList').addEventListener('mousedown', function () {
  // Récupérer l'ID de l'équipement
  var eqId = $('.eqLogicAttr[data-l1key=id]').val();

  // Stocker la valeur sélectionnée avant la mise à jour du dropdown
  selectedValue = $('#enfantList').val();

  // Faire une requête Ajax pour récupérer les informations de l'équipement depuis le fichier
  $.ajax({
    type: "POST",
    url: "plugins/ProJote/core/ajax/ProJote.ajax.php",
    data: {
      action: "GetEquipmentInfo",
      id: eqId
    },
    dataType: 'json',
    success: function (response) {
      console.log('Réponse de la requête AJAX :', response);
      // Vérifier si la propriété 'result' est définie et est un tableau
      if (response.result && Array.isArray(response.result)) {
        // Le traitement ici, par exemple :
        response.result.forEach(item => {
          console.log(item); // Afficher chaque élément du tableau
        });
        updateDropdown(response.result);
        // Rétablir la valeur sélectionnée après la mise à jour du dropdown
        $('#enfantList').val(selectedValue);
      } else {
        console.warn('La propriété \'result\' n\'est pas un tableau, affichage de la première ligne :');
        console.log(response.result); // Afficher la première ligne
      }
    },
    error: function (jqXHR, textStatus, errorThrown) {
      console.error('Erreur lors de la récupération des informations de l\'équipement :', textStatus, errorThrown);
    }
  });
});
<...>

Et enfin , ProJote.ajax.php :

<...>
  if ($action == "GetEquipmentInfo") {
    log::add('ProJote', 'debug', 'Ajax::Je recherche le fichier avec la liste d\'enfant');
    $eqId = init('id');
    $eqLogic = ProJote::byId(init('id'));
    $filePath = "/tmp/jeedom/ProJote/{$eqId}/listenfant.ProJote";
    log::add('ProJote', 'debug', 'Ajax::Je recherche le fichier ' . $filePath);
    if (file_exists($filePath) && filesize($filePath) > 0) {
      $fileContent = file_get_contents($filePath);
      // Convertir le contenu en un tableau en utilisant explode
      $fileContentArray = explode("\n", $fileContent);
      // Stocker le contenu dans une variable de session
      $_SESSION['equipment_info'] = $fileContentArray;
      ajax::success($fileContentArray);
    } else {
      ajax::error('Le fichier n\'existe pas ou est vide.');
    }
  }
<...>

Informations Jeedom

Core : 4.4.5 (V4-stable)
DNS Jeedom : non

Plugin : Plugin Pronote
Version : 2024-05-07 09:35:02 (stable)
Statut Démon : Démarré - (2024-05-11 23:16:42)

En ce qui concerne le log du navigateur voila ce que je pepux founrir :

Object { type: "AJAX", code: 42, message: "Unknown error" }
getResource.php:37:15

Est ce que tu sauvegardes avant de recharger la page ou est ce que tu as cette disparition justement quand tu sauvegardes puis lorsque la page se recharge?

Est ce que tu as vérifié que tu récupérais bien dans ton js la currentValue et que ton test optionExists renvoyait bien true?

Bonjour,

La disparition est lorsque rafraichis « F5 » la page
Mais aussi lorsque je sauvegarde la page, elle se rafraichit et l’entrée disparait
Et encore quand je vais sur la page

Par contre, si je regarde les logs du deamon python , la valeur est bien présente puisqu’il la reçoit

Alors le log remonte bien un problème :

  var optionExists = Array.from(selectElement.options).some(function (option) {
    console.log("JS Option Exists:", optionExists);
    return option.value === currentValue;

JS Option Exists: undefined

Et

function updateDropdown(data) {
  var selectElement = document.getElementById('enfantList');
  var currentValue = selectElement.value; // Récupérer la valeur actuelle du champ
  console.log("JS Current Value:", currentValue);

JS Current Value:

Hello,

document.getElementById('enfantList').addEventListener('mousedown '...

Comment ce déclenche cet évènement a l’initiation de la page ?

car actuellement vu qu’a l’initiation de la page il n’y a aucune option dans le select, le core ne peut pas set la valeur.

Alors, il se déclenche pas au rafraichissement.
Lorsque l’on déplie le menu, il s’exécute pour afficher une liste de valeur.
Lorsque l’on déplis le menu, on obtient les log suivant :
JS Current Value: <empty string>
et
JS Option Exists: undefined

Quand je sélectionne une « valeure » :
JS Current Value: valeure
et
JS Option Exists: undefined

Si je sauvegarde j’ai le champs qui s’efface et l’erreur :
JS Option Exists: undefined

as-tu vraiment besoin d’initier cette liste en js ? tu peut pas le faire direct dans le php ?

Hier j’ai jetté l’éponge et testé en PHP.
Le problème est que lorsque l’on a plusieurs équipement la liste doit être différentié par équipement.

Donc lors du chargement de la page le script PHP est exécuté pour chaque équipement et donc le menu est une addition de tous les choix.

sinon dans ton js tu peut ajouter la function prePrintEqLogic(_eqlogicId), celle-ci se déclenche avant que le core remplisse les données.

Voici le code PHP que j’avais fais :

<?php
// Chemin du fichier listenfant.ProJote
$filePath = '/tmp/jeedom/ProJote/' . eqLogic::byType($plugin->getId()) . '/listenfant.ProJote';

// Vérifier si le fichier existe
if (file_exists($filePath)) {
// Lire le contenu du fichier
$fileContent = file_get_contents($filePath);

// Diviser le contenu en lignes
$lines = explode("\n", $fileContent);

// Commencer la construction du menu déroulant
$selectMenu = '<select type="text" class="eqLogicAttr form-control"  data-l1key="configuration" data-l2key="enfant">';

// Ajouter chaque ligne du fichier comme une option dans le menu déroulant
foreach ($lines as $line) {
// Supprimer les espaces en début et en fin de ligne
$line = trim($line);
// Vérifier si la ligne est vide
if (!empty($line)) {
// Ajouter une balise d'option avec la même valeur et texte
$selectMenu .= '<option value="' . htmlspecialchars($line) . '">' . htmlspecialchars($line) . '</option>';
}
}

// Fermer le menu déroulant
$selectMenu .= '</select>';

// Afficher le menu déroulant
echo $selectMenu;
} else {
// Afficher un message si le fichier n'existe pas
echo '<p>Le fichier listenfant.ProJote n\'existe pas pour cet objet.</p>';
}
?>

Ce que je comprend pas, c’est comment est alimenté/créé ton fichier listenfant.ProJote ?

J’ai ajouté la fonction comme cela dans js :

function prePrintEqLogic(_eqlogicId) {
  document.getElementById('div_pageContainer')?.querySelector('.eqLogicAttr[data-l1key="configuration"][data-l2key="enfant"]').jeeValue(0)
}

Mais pas de changement de comportement

non ca marchera pas car la liste n’est pas encore créée quand ce code ce lance.

J’ai un démon Python qui est exécuter avec des paramètres en configuration pour écrire un fichier propre pour chaque équipement :

"/tmp/jeedom/ProJote/{$eqId}/listenfant.ProJote"

donc ce fichier est monté en postSave ?

Quand j’appuie sur le bouton, le fichier doit exister.
Il a déjà été créé

dans le prePrintEqLogic il faudrait juste faire un ajax pour monter le select.