Étiquette : Accordion

[Magento 2] Exploiter le widget javascript jQuery natif Accordion dans le fichier PHTML des filtres produit (page category)

Note: ce widget Accordion fait partie d’une collection étendue de widgets fournis de base par Magento 2 (à ne pas confondre avec la bibliothèque UI Magento 2, fournie de base également, et qu’il convient de connaître aussi.

Pour ce tuto, nous allons afficher les différentes familles de tri produits (catégorie, taille, activity, color, erin recommends, genre, material, nouveau, prix, etc…) sous forme d’accordéons. De base, ils s’affichent tous ouverts, y-compris en vue Mobile ce qui force l’utilisateur à scroller bas dans la page avant de voir apparaître le premier produit. Le fonctionnalités voulues pour ce accordéon:

  • tous les accordéons (différentes familles de tri) sont ouverts au chargement de la page
  • plusieurs accordéons peuvent rester ouverts simultanément

(Note pour plus tard: il peut être intéressant, dans le cadre de la découverte des media-queries côté JS, d’initialiser ce widget avec des options différentes en fonction de l’affichage mobile/desktop).

A noter: il existe plusieurs méthodes pour initialiser du code javascript dans une vue dans Magento 2. Nous allons nous concentrer sur deux d’entre-elles qui ne sont ni meilleures, ni moins bonnes que les autres.

Imperative notation

En initialisant notre widget directement dans un fichier *.phtml, entre balises <script type="text/javascript">.

Commencer par éditer le fichier *.phtml app\design\frontend\<Vendor_name>\<theme_name>\Magento_LayeredNavigation\templates\layer\view.phtml qui constitue la base de la vue des différents filtres. Notez bien l’ajout, par rapport à la vue que nous surchargeons, des attributs data-role="collapsible", data-role="trigger" et data-role="content" respectivement placés sur les éléments dt, a et dd, ainsi que de la classe filter-options-collapsible-trigger placée sur le nouvellement ajouté élément a.

Le widget s’initialise ensuite comme suit avec requireJS (code placé dans le même fichier view.phtml, immédiatement après la ligne <?php if ($block->canShowBlock()): ?>):

Declarative notation

Le widget va s’initialiser sans avoir recours à un require déclaré dans une balise <script />, par de biais d’un attribut data-mage-init placé directement sur l’élément à partir duquel nous venons précédemment d’initialiser notre widget à la manière de jQuery.

Dans les deux cas on n’oublie pas de lancer un cache:clean en console!

[Foundation 6] Contourner le bug du composant Modal en full screen qui empêche de scroller jusqu’en bas si on utilise l’attribut optionnel data-v-offset

Présentation du problème

Voir en fin de ce billet le paragraphe « Améliorations ».

Demande pour un site Responsive avec un menu qui, en vue Mobile:

  • S’ouvre en cliquant sur une icône Sandwich placée dans le bandeau
  • S’ouvre immédiatement sous le bandeau (pas de off-canvas) et par-dessus le contenu de la page (comprendre: sans s’intercaler entre le bandeau et le contenu de page, donc sans pousser ce dernier vers le bas).
  • Le menu doit être en accordéon

J’ai eu l’idée d’utiliser le composant Modal de Foundation 6 qui intègre une option full-screen et la possibilité de faire débuter la modale à x pixels du haut de la fenêtre (pour laisser le bandeau apparent). La modale de Foundation étant scrollable, je me suis dit « Bingo! ». Le code de ma modale ressemble à peu près à ceci :

Problème: la modale semble mal calculer les hauteurs lorsqu’on utilise l’attribut optionnel data-v-offset pour faire débuter la modale à x pixels du haut de la fenêtre. On ne peut pas scroller jusqu’en bas lorsque le contenu de celle-ci est plus haut que la hauteur totale de la fenêtre!!!

Mise en place de la solution

(optimisation) On stocke l’ID affecté à l’élément Modal dans une variable, car on va l’appeler à plusieurs reprises ensuite:

On commence par récupérer la hauteur du bandeau (en utilisant la très pratique javascript Utility BOX fournie avec Foundation 6) pour l’affecter à la modale via l’attribut optionnel data-v-offset du plugin Reveal (lui aussi fourni avec Foundation 6).

Seulement ensuite, on initialise le plugin Reveal de Foundation 6 (ou tous les plugins d’un coup dans notre exemple) :

De base, la modale Foundation a une hauteur et une hauteur minimale fixées à 100% ou 100vh pour les navigateurs les plus récents. Ces styles sont affectés à l’élément Modal via CSS.

D’autres styles sont affectés à l’élément Modal, lors de son ouverture, via javascript (voir l’attribut style="") :

Pour éviter le bug nous concernant, il faut surcharger les valeurs de height et de min-height en les recalculant via javaScript en fonction de la valeur de data-v-offset récupérée plus haut. On stocke les styles existants dans une variable elementStandardStyle et on ajoute les nouvelles valeurs de hauteur via une variable elementCustomStyle :

Optimisations d’ordre ergonomiques

Refermer la modale (le menu) au clic n’importe où d’autre sur l’écran

On commence par créer une fonction qui ferme la modale (cf. doc de Foundation).

Puis on exécute du code à l’événement open.zf.reveal (une fois la modale est ouverte) :

  • Pour une sélection d’éléments, la modale ne se refermera pas si on clique dessus.
  • Pour tout le reste du document, on exécute la fonction closeMobileNavModal() qui referme la modale.
  • Le 2ème point n’est exécuté qu’une seule fois grâce au $(this).off(e); (sinon, on ne peut plus ré-ouvrir la modale).

ATTENTION!!! Sur iPhone, il existe un bug connu qui empêche le clic sur l’ensemble du $(document). Il faut impérativement ajouter la propriété cursor: pointer; sur l’élément ciblé par le clic.

Dans l’exemple ci-dessous, je lance une détection de l’appareil servant à l’internaute et j’affiche une classe en conséquence sur l’élément html via le plugin browser-detection.

Améliorations (pas testé)

J’appelle deux fois l’événement open.zf.reveal. On peut optimiser ça en ne l’appelant qu’une seule fois:


On peut conserver le menu ouvert sur la page en cours (à condition d’avoir les classes standard d’un menu Change .in-path, .current) en ajoutant le code suivant:

Juste en dessous de l’initialisation des plug-ins Foundation ($(document).foundation();) :

…puis à l’événement open.zf.reveal (le if ($(primaryNav)) :

[jQuery][Foundation 3.5.2] Modifier le comportement natif du composant Accordion pour empêcher la fermeture d’un panneau au clic sur son en-tête

Les versions récentes de Foundation incluent toute une batterie d’options pour le composant Accordion.

Le comportement standard consiste à pouvoir fermer un panneau au clic sur son en-tête. Tous les panneaux sont alors fermés.
Nous allons modifier le code natif du composant accordion.js de Foundation 3.5.2 afin qu’un panneau ouvert ne puisse plus être fermé (par l’utilisateur) au clic sur son en-tête.

Il suffit de repérer et de commenter la ligne suivante : p.find('li').removeClass('active').end().find('.content').hide();.

[CSS][Foundation 3.5.2] Reset CSS des styles du composant Accordion de Foundation v3.5.2

en SASS (ajouter la classe .css-reset) :