jquery-accessible-modal-window-aria icon indicating copy to clipboard operation
jquery-accessible-modal-window-aria copied to clipboard

[SPIP] Ajax + Modale = cassé

Open jpyrat opened this issue 6 years ago • 11 comments

Bonjour

Sur https://www.tisseursdemots.org/, j'utilise https://a11y.nicolas-hoffmann.net/modal/ pour y afficher un miniagenda qui passe de mois en mois en ajax sauf que ça casse l'ajax et provoque le rechargement de la page avec le paramètre du mois comme si ajax de SPIP ne retrouvait pas ses petits suite à la manipulation du DOM par le script de modale (le div est initialement caché, et déplacé dans une autre zone du DOM https://github.com/nico3333fr/jquery-accessible-modal-window-aria/blob/master/jquery-accessible-modal-window-aria.js#L73)

L'appel à la modale est ici : https://zone.spip.org/trac/spip-zone/browser/squelettes/soyezcreateurs_net/trunk/plugins/soyezcreateurs/noisettes/header/cadre_outils_agenda.html Et le miniagenda est là https://zone.spip.org/trac/spip-zone/browser/squelettes/soyezcreateurs_net/trunk/plugins/soyezcreateurs/noisettes/footer/footer_pied.html#L25

J'ai vérifié :

  • si je modifie la CSS pour afficher l'agenda là où il est masqué, l'ajax fonctionne
  • mais quand la modale déplace le html du mini agenda, le comportement ajax associé ne suit pas

Quelques pistes : https://stackoverflow.com/questions/26321432/move-element-to-another-div-without-losing-events-listeners-etc-without-jquer

jpyrat avatar May 15 '18 16:05 jpyrat

Solution : https://zone.spip.org/trac/spip-zone/changeset/110277

J'essaye de faire un PR

jpyrat avatar May 15 '18 21:05 jpyrat

Hello !

Il faut que je regarde plus précisément tes changements, j'ai fait qq tests et j'ai qq soucis. Je te dis dès que possible.

nico3333fr avatar May 16 '18 07:05 nico3333fr

Le PR, je l'ai fait en codant directement dans le trunk. Alors que ce que j'ai testé, c'est sur le tag 1.8.2 (parce que tu n'as pas fait de tag depuis). ;-) Merci

jpyrat avatar May 16 '18 08:05 jpyrat

Donc, si je comprends bien ton souci (j'essaie de résumer pour avoir la vision globale du problème) :

  • ma modale prend le contenu que tu veux injecter dedans, le coupe et le colle dans le contenu de la modale (En fait, j'avais fait ainsi pour éviter les id dupliqués, et comme je fonctionne souvent en delegation, je n'ai pas le souci que tu rencontres.)
  • et toi tu as besoin de dupliquer le contenu pour l'injecter dans la modale pour ne pas perdre les événements posés dessus.

Est-ce que j'ai bien compris ? Si c'est ça, faudra voir pour réunir le meilleur de ces deux mondes ;)

nico3333fr avatar May 16 '18 11:05 nico3333fr

Oui, c'est bien ça. Et comme je ne suis pas un kador en JS, je ne sais même pas ce que tu veux dire par délégation.

Ce que j'ai compris de ce que j'ai fait :

  1. toi, tu cut/paste du texte (avec ".html") ce qui perd les events
  2. moi, j'ai essayé de déplacer (.appendTo) le même HTML mais en tant que DOM, ce qui garde les events

Le résultat est en ligne sur https://www.tisseursdemots.org/

jpyrat avatar May 16 '18 14:05 jpyrat

En fait, il faut le comprendre ainsi (j'essaie de simplifier, voici l'idée https://javascript.developpez.com/actu/85848/Comprendre-la-delegation-d-evenement-en-JavaScript/ ) : au lieu de poser mes listeners sur l'élément proprement dit, je les pose sur le body en disant : "écoute depuis le body tels éléments". Ce qui fait que si de nouveaux éléments sont ajoutés, ils sont quand même écoutés (tu perds un poil en rapidité mais tu gagnes en praticité, même si ça n'est pas parfait).

Du coup, je me dis que je peux p-e essayer ta méthode et combiner à la mienne... faut que je voie.

nico3333fr avatar May 16 '18 14:05 nico3333fr

En l’occurrence, ça n'est pas "ma" méthode, mais celle du CMS que j'utilise. Il pose des événements qui s'occupent de gérer l'ajax. Ne pas perdre les événements du DOM affichés par ton script de modale va le rendre plus universel et robuste ;-)

jpyrat avatar May 16 '18 19:05 jpyrat

Hello !

Je me suis penché sur ta PR, j'ai fait qq essais. En fait, je constate que la méthode que tu as trouvée fonctionne... mais elle a un souci : elle ne prend que les éléments enfants (comprendre que les tags enfants) et pas tout le contenu. En clair, dans le second exemple de la doc ("Second simple example"),

<div id="modal_id_2nd_example" class="hidden">Woot, you can take the content of a hidden <code>div</code>, and it is animated.</div>

elle ne prenait que <code>div</code>. :-\

Après avoir lutté pour trouver une solution, je suis passé par cette méthode :

var $content_modal = $js_modal_content.contents().clone(true, true);
$content_modal.appendTo($('#' + $content_back_id));

En gros, je prends le contenu que je clone avec les events, et j'utilise appendTo comme toi. mes essais montrent que les events ont l'air de bien rester.

Pourrais-tu essayer ? La dernière version est là pour le moment: https://a11y.nicolas-hoffmann.net/modal/js/jquery-accessible-modal-window-aria_1527504140.js

nico3333fr avatar May 28 '18 13:05 nico3333fr

Bonsoir Nicolas !

Merci d'avoir cherché. J'ai testé ta modif et elle casse encore l'Ajax de SPIP :(

De mémoire, j'avais dû passer par children parce que pour remettre le contenu déplacé, il fallait garder le id de départ en place. Donc, si on rajoutait autour du contenu à déplacer un id l'englobant avant de faire le déplacement, on pourrait se baser sur lui pour le retour... Qu'en dis-tu ?

jpyrat avatar May 28 '18 20:05 jpyrat

Bingo ! J'ai utilisé .wrap et .unwrap et ça marche. Je te fais le diff en PJ FileComparisonDiffReport.txt

jpyrat avatar May 28 '18 21:05 jpyrat

Bonjour,

je rencontre le même problème, je pense, sur une modale qui contient un sélecteur select2 : lorsque le formulaire est dans une modale, les choix et la recherche select2 ne s'effectuent pas. Hors modale ça fonctionne.

@jpyrat j'ai regardé ton diff mais le code a du pas mal changer depuis, et je n'arrive pas à l'appliquer.

MarieComet avatar Apr 30 '19 09:04 MarieComet