TagFoundation 6

[Foundation 6] Exploiter le composant Drilldown et jQuery pour créer un product finder wizard

Un product finder wizard qui pose une série de questions pour aider l’utilisateur à trouver le bon produit en fonction de ses besoins. La fonctionnalité est constituée de:

  • le Drilldown de Foundation 6 pour la mise en place du wizard <ul class="vertical menu drilldown product-finder-tree">
  • des boutons de navigation Précédent, Réinitialiser et Suivant <div class="product-finder-actions">
  • un fil d’Ariane qui se constitue à la volée en fonction des choix précédents de l’utilisateur <div id="productFinderBreadcrumb" class="product-finder-breadcrumb"></div>

Partie PHTML

Le code HTML qui constitue le menu n’est autre qu’une liste non-ordonnée d’éléments imbriqués. Il est conforme au markup générique fourni par Zurb pour la démo du composant Drilldown aux exceptions près que:

  • les éléments <a> portent une classe .question
  • les éléments <li> ont un ID questionID_ (généré via PHP dans notre exemple)

Partie jQuery

Nous utilisons plusieurs méthodes natives du composant Drilldown de Foundation 6:

  • _hideAll pour réinitialiser le menu à son état initial.

    Attention: cette méthode semble bugguée. Je l’ai peut-être aussi mal exploitée, mais j’ai dû écrire un fix; voir ci-dessous:

  • _showMenu pour rediriger l’utilisateur vers un choix précédent dans le DOM du menu (lorsqu’il clique sur le bouton Précédent).

    Attention: il est important de pointer un élément UL (dans mon exemple, sur la classe .submenu) pour que cette méthode fonctionne!

  • _show pour rediriger l’utilisateur plus en avant dans ses choix dans le DOM du menu (lorsqu’il clique sur le bouton Suivant).

    Attention: il est important de pointer un élément LI (dans mon exemple, sur l’ID questionID_ se trouvant sur les LI) pour que cette méthode fonctionne!

[Foundation 6] Un lien parent cliquable qui renvoie vers une page dans le menu Drilldown

Source: Foundation 6 Drilldown clickable parent link with sub-menu

HTML

CSS

JS

[Magento 2] Un menu de navigation drilldown en mobile avec Foundation 6 à partir du Topmenu.php natif

Côté app/code, création d’un module Topmenu spécifique

En ligne de commande pour créer et activer un module qui s’appelle Topmenu:

…puis:

Créer un module et étendre le Block Topmenu.php

Référence: [Magento 2] Surcharger un Block ou un Model natif.

Les seuls fichiers à conserver après la création du module sont (depuis app/code/<MyNamespace>/Topmenu/):

  • /Block/Html/Topmenu.php (qu’on va créer juste après)
  • /etc/di.xml
  • /etc/module.xml
  • /registration.php

Modifier app/code/<MyNamespace>/Topmenu/etc/di.xml:

Modifier app/code/<MyNamespace>/Topmenu/etc/module.xml:

On déclare hériter de <module name="Magento_Theme" />:

Créer app/code/<MyVendor>/Topmenu/Block/Html/Topmenu.php:

Dans notre exemple, il s’agit du fichier vendor/magento/module-theme/Block/Html/Topmenu.php que nous allons surcharger comme suit dans app/code/<MyNamespace>/Topmenu/Block/Html/Topmenu.php. Nous y ajoutons les classes CSS nécessaires au fonctionnement du composant Drilldown de Foundation 6:

Côté app/design/frontend/<MyVendor>/<MyTheme> (theme)

Créer app/design/frontend/<MyVendor>/<MyTheme>/Sm_Venuse/templates/html/mobile/nav-mobile.phtml:

Référence: [Magento 2] Ajouter le framework Foundation 6 for sites dans un thème et rendre ses widgets javascript disponibles avec RequireJS.

Dans notre exemple, il s’agit du fichier app/design/frontend/Sm/venuse/Sm_Venuse/templates/html/mobile/nav-mobile.phtml que nous allons surcharger comme suit dans app/design/frontend/<MyVendor>/<MyModule>/Sm_Venuse/templates/html/mobile/nav-mobile.phtml:

Gestion des styles

On peut éclater les styles de Foundation en deux fichiers distincts qu’on va consigner dans un dossier components:

app/design/frontend/<MyVendor>/<mytheme>/web/css/source/components/_foundation_menu.less

app/design/frontend/<MyVendor>/<mytheme>/web/css/source/components/_foundation_drilldown.less

On ajoute les deux composants dans _extend.less

…ou ailleurs dans une feuille de style de votre thème. Il faut juste que les deux fichiers soient importés. Veiller également à ce que les variables concernant les couleurs soient accessibles pour la compilation. Dans mon exemple, @store_base-color.

Gestion des JS

Dans mon exemple, je n’ai pas eu besoin de modifier le JS natif de Foundation. Je l’importe donc via le dossier vendor: app/design/frontend/<MyVendor>/<mytheme>/web/js/vendor/ (si vous avez bien suivi les directives données dans cet autre billet).

Ne pas oublier de créer app/design/frontend/<MyVendor>/<mytheme>/requirejs-config.js

[Magento 2] Ajouter le framework Foundation 6 for sites dans un thème et rendre ses widgets javascript disponibles avec RequireJS

Pour ce tuto, nous allons intégrer la version 6.5.3 de Foundation for sites. Le pre-processing des assets se fait avec Webpack et Gulp (contre Grunt dans Magento 2) et les fichiers source sont fournis au format SASS pour les styles et ES5, jQuery (version 3+) pour les javascripts, ce qui les rend inexploitables de base avec Magento 2 (LESS pour les styles et version de jQuery 1.12 pour les javascripts). Nous utiliserons donc les versions déjà compilées (CSS et javascript « vanilla ») qui se trouvent dans le dossier dist du repository Git.

Les styles

Créer un dossier app/design/<Vendor_name>/<theme_name>/web/css/vendor/foundation/ dans lequel nous allons copier/coller l’intégralité des fichiers se trouvant dans le chemin dist/css du Git.

Dans app/design/<Vendor_name>/<theme_name>/web/css/source/_theme.less:

A noter: le code CSS final du framework n’étant pas éclaté en différents fichiers, il faudra probablement que vous ré-éditiez ce fichier pour retirer les styles qui entrent en conflit avec ceux de votre thème. Vous pouvez importer foundation.min.css si vous souhaitez conserver le fichier en l’état.

Les scripts

Joindre l’intégralité des widgets

Solution la plus simple: la version minifiée dans l’intégralité du code JS du framework tient en 171ko.

Créer un dossier app/design/<Vendor_name>/<theme_name>/web/js/vendor/foundation/ dans lequel nous allons copier/coller l’intégralité des fichiers se trouvant dans le chemin dist/js du Git.

Dans app/design/<Vendor_name>/<theme_name>/requirejs-config.js:

Dans un fichier *.phtml (ou *.js pour la partie entre <script />):

Problématiques:

Modifier un paramètre du composant et inclure une chaîne de traduction i18n

Avant d’instancier un nouvel objet, on modifier un ou plusieurs paramètres par défaut. La traduction se fait par la méthode PHP de Magento 2 (et pas par la méthode Javascript).

[Foundation 6] Habiller proprement un input type= »file »

Source: Adding Filename Feedback to (Stylized) Foundation File Upload Buttons sur Foundation forum.

The Problem:

Foundation has support for stylizing file inputs by adding a label element — but currently — after the user chooses a file from his/her system, there is no feedback that shows that a file was selected. The button’s text remains the same (e.g. « Upload File ») and doesn’t display the filename the user selected, causing the user to wonder if the file was actually selected.

The Solution:

To add feedback, you can add a small amount of JS code. Here’s an example that targets all input files using the example that Foundation uses on their Forms page.

HTML:

JS:

Tested working in Foundation 6.3.0

(Note: If using this code, you may want to use a named function instead of recreating an anonymous function in each iteration of the for loop.)

You may want to do some quick validation on this.files before setting the label’s innerHTML or leave the label’s innerHTML alone to keep the button as is and write the file name in another div next to it. There are also other things to consider such as multiple file uploads (in which you could signify the number of files as feedback for that use-case). It would be great if Foundation could possibly add this feature in the future.

Hope this helps,

Roy

[Foundation 6] Astuces, bonnes pratiques, ressources en ligne

Thèmes

  • SD UI Foundation Themes – Free themes for the most advanced responsive front-end framework in the world (merci Gilles).

[Foundation 6] Une grille flexbox aux largeurs de colonnes custom avec les mixin flex-grid-size

Doc Foundation 6 – Flex Grid – @mixin flex-grid-size

Une rangée basée sur 8 colonnes

[Foundation 6] Customiser le libellé du lien « Back » (retour) du composant Drilldown

2 solutions possibles, mais le truc à savoir c’est qu’il faut également préciser quel markup HTML va venir englober le libellé. Si on précise uniquement un libellé, le markup englobant mis par défaut (et le lien de retour qui va avec) disparaîtront.

Via javaScript

Avant d’initialiser vos plug-ins Foundation:

Via un data-attribute HTML

Pas testé; pose probablement un problème de caractères ", '.

[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)) :

[Foundation 6] Erreur « Error: Syntax error, unrecognized expression: ##panel2 » avec le composant Tabs

Si vous avez cette erreur en utilisant le code de base du composant Tabs de Foundation 6 for Sites :

…il faut retirer l’attribut data-tabs-target="#panel2" du code qui est donné en exemple. C’est lui qui fout la m*&$e.

© 2020 FrontEndDeveloper

Theme by Anders NorénUp ↑