From 024da11934b508c36a1139013bf3dccf9f2111f5 Mon Sep 17 00:00:00 2001 From: william Date: Wed, 26 Aug 2026 07:31:40 +0200 Subject: [PATCH] =?UTF-8?q?Corrige=20le=20blocage=20des=20clics=20apr?= =?UTF-8?q?=C3=A8s=20le=20premier=20rafra=C3=AEchissement=20de=20donn?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Régression introduite par le commit précédent (préservation de l'état visuel transitoire dans applyOpenRowBindings) : la restauration du dataset complet d'un nœud copiait aussi clickBound/hoverBound/ hoverTriggerBound — des indicateurs INTERNES au moteur (voir bindClicks/ bindHoverTexts/bindHoverTriggers), jamais un état posé par une action "Modifier un élément". Un nœud tout juste régénéré se retrouvait donc marqué "déjà lié" à tort, alors qu'aucun écouteur de clic n'y était réellement rattaché : bindClicks() le voyait déjà "bound" et sautait son rattachement, rendant l'élément silencieusement inerte pour le reste de la partie. Symptôme rapporté : dans un écran avec un Répéteur ET un panneau de détail utilisant des {{champ}}, le premier clic sur une ligne fonctionne (exécuté par les gestionnaires posés au chargement de la page), mais plus aucun clic ne répond ensuite sur AUCUNE ligne — le Répéteur étant regénéré dans le même sous-arbre que le panneau de détail (ancêtre commun avec des {{champ}} non résolus), donc concerné par la même restauration de dataset. Fix : exclure ces trois clés internes de la sauvegarde/restauration — seul l'état réellement transitoire (style inline, classes, data-toggle-* posés par "Modifier un élément") doit survivre à la regénération. Co-Authored-By: Claude Sonnet 5 --- templates/play.html | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/templates/play.html b/templates/play.html index ab635e79..1fce822e 100644 --- a/templates/play.html +++ b/templates/play.html @@ -355,10 +355,22 @@ // recrée entièrement ses nœuds à partir de leur état PAR DÉFAUT. const savedState = {}; wrapper.querySelectorAll('[data-element-id]').forEach(function(node) { + // clickBound/hoverBound/hoverTriggerBound (voir bindClicks/ + // bindHoverTexts/bindHoverTriggers) sont des indicateurs INTERNES du + // moteur, jamais un état posé par une action "Modifier un élément" — + // les restaurer sur le nœud tout neuf créé ci-dessous lui ferait + // croire à tort qu'un écouteur de clic/survol lui est déjà rattaché + // (alors qu'aucun ne l'est réellement), ce qui bloquait + // silencieusement TOUS les clics suivants sur cet élément (ex. les + // lignes d'un Répéteur voisin, une fois régénérées avec lui). + const dataset = Object.assign({}, node.dataset); + delete dataset.clickBound; + delete dataset.hoverBound; + delete dataset.hoverTriggerBound; savedState[node.dataset.elementId] = { style: node.getAttribute('style') || '', className: node.className, - dataset: Object.assign({}, node.dataset), + dataset: dataset, }; });