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
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<dl class="filter-options" id="narrow-by-list"> <?php $wrapOptions = true; endif; ?> <?php if ($filter->getItemsCount()): ?> <dt data-role="collapsible" aria-level="3" class="filter-options-title"> <a class="filter-options-collapsible-trigger" href="#" data-role="trigger"> <?= $block->escapeHtml(__($filter->getName())) ?> </a> </dt> <dd data-role="content" class="filter-options-content"> <?= /* @escapeNotVerified */ $block->getChildBlock('renderer')->render($filter) ?> </dd> <?php endif; ?> <?php endforeach; ?> <?php if ($wrapOptions): ?> </dl> |
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()): ?>
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<script type="text/javascript"> require([ 'jquery', 'accordion'], function ($) { $("#narrow-by-list").accordion({ openedState: 'active', // [option] ajoute une class 'active' aux éléments ouverts collapsible: true, multipleCollapsible: true // [option] plusieurs accordéons peuvent être ouverts simultanément }).accordion("activate"); // [méthode] ouvre par défaut TOUS les accordéons au chargement de la page $('.filter-options-collapsible-trigger', '#narrow-by-list').on("click", function(e){ e.preventDefault(); }); }); </script> |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<dl class="filter-options" id="narrow-by-list" data-mage-init='{ "accordion":{ "openedState": "active", "collapsible": "true", "multipleCollapsible": "true" }}'> <?php $wrapOptions = true; endif; ?> <?php if ($filter->getItemsCount()): ?> <dt data-role="collapsible" aria-level="3" class="filter-options-title"> <a class="filter-options-collapsible-trigger" href="#" data-role="trigger"> <?= $block->escapeHtml(__($filter->getName())) ?> </a> </dt> <dd data-role="content" class="filter-options-content"> <?= /* @escapeNotVerified */ $block->getChildBlock('renderer')->render($filter) ?> </dd> <?php endif; ?> <?php endforeach; ?> <?php if ($wrapOptions): ?> </dl> |
Dans les deux cas on n’oublie pas de lancer un cache:clean
en console!