Tagjavascript

[Magento 2] Etendre un mixin existant

Etendre une extension de widget existante dans Magento 2 n’est pas possible. Il faut obligatoirement surcharger l’extension existante en déclarant l’extension initiale à false dans le fichier requirejs-config.js du module (pouvant être différent) qui contient la nouvelle extension:

Notes:

  • la bonne pratique consiste à placer les extensions de widgets dans des modules (app/code/...) plutôt que dans un thème.

[javascript] L’équivalent ES6/vanilla JS de la méthode .eq() de jQuery

Source: Pure JS equivalent of Jquery eq().

La méthode .eq() de jQuery

La même chose en ES6/vanilla JS

[javascript] Corriger l’erreur « Uncaught TypeError: Cannot read property ‘getData’ of undefined » (ou ‘setData’) en déclarant un addEventListener correctement

Source: Ondragstart Attribute doesn’t appear when created dynamically.

En essayant de convertir la génération d’un élément TD dans le DOM avec jQuery en code vanilla JS, je me suis heurté aux erreurs suivantes:

Uncaught TypeError: Cannot read property ‘getData’ of undefined
Uncaught TypeError: Cannot read property ‘setData’ of undefined

Le code jquery de départ:

Version vanilla JS/ES6

On commence par créer l’élément TD:

Puis on lui assigne de multiples attributs (id, title, class) (source: Setting multiple attributes for an element at once with JavaScript):

(pour n’ajouter qu’un seul attribut: $row.setAttribute("class", "is-row");)

Mais pour ajouter des attributs relatifs à des événements (ondrop, ondragover, …), il faut utiliser la méthode addEventListener:

[Magento 2] Utiliser les Mutation Observers de javascript pour détecter les changement dans le DOM suite à une action utilisateur

Attention: Ces sources concernent l’observation de modifications dans le DOM une fois que la page est chargée et/ou qu’un utilisateur effectue des actions. Voir aussi l’article qui consiste à tester la présence de certains éléments dans le DOM au chargement de la page.

Attention #2: bien que préfixé Magento 2, cette astuce fonctionnera également en dehors de la solution e-commerce d’Adobe. Dans mon cas, c’est de cette manière que j’ai dû la mettre en place donc c’est comme ça que je la documente. Donc lisez le billet, car vous êtres peut-être quand même au bon endroit 🙂

Source: https://developer.mozilla.org/fr/docs/Web/API/MutationObserver.

La problématique:

Au chargement de la fiche produit d’un produit configurable dans Magento 2, la référence par défaut s’affiche sous le libellé produit alors qu’aucune option n’a encore été sélectionnée par l’utilisateur.

Ce dernier à la possibilité de changer (la couleur du produit dans notre exemple ci dessous) via une liste de sélection <select>.

Nous cherchons à masquer l’affichage de la référence jusqu’à ce qu’une option ait été sélectionnée par l’utilisateur.

La solution:

Surcharge d’un fichier PHTML pour y ajouter un observer via les Mutation Observers de Javascript

Nous allons surcharger, dans notre thème custom, le fichier vendor/magento/module-catalog/view/frontend/templates/product/view/attribute.phtml qui contient le markup permettant l’affichage de la référence dans la fiche produit.

Exemple de chemin vers le fichier surchargé: app/design/frontend/MyVendor/mytheme/Magento_Catalog/templates/product/view/attribute.phtml.

Rajout d’une classe CSS et d’un ID

Par rapport au fichier original, nous rajoutons la classe CSS is-hidden-if-product-is-configurable à la ligne <div class="product attribute <?= $block->escapeHtmlAttr($_className) ?>"> et un ID productRef à la ligne <div  class="value" <?= /* @noEscape */ $_attributeAddAttribute ?>><?= /* @noEscape */ $_attributeValue ?></div>.

Rajout de l’observer JS

En toute fin de fichier:

Le reste du fichier demeure inchangé.

Le style qui va venir masquer la référence au chargement de la page

[Javascript] Une alternative ES6+ à la méthode .remove() de jQuery avec querySelectorAll et parentNode.removeChild

Source: Pure JavaScript alternative to jQuery’s .remove()

Instruction initiale (en jQuery):

Boucle for:

Sous forme de fonction

[javaScript] Rechercher si une valeur est déjà présente dans un tableau bi-dimensionnel

[Magento 2] Afficher un lien vers la fiche produit depuis la quickview en exploitant le localStorage

edit: je me suis rendu compte que la solution #1 n’était pas fonctionnelle. En effet, à l’utilisation, le local storage (clé: product_data_storage) était vide/n’avait aucune valeur!

Solution #2 (fonctionnelle)

app/design/frontend/Vendor/theme/Magento_Catalog/templates/product/list.phtml: au clic sur un item produit (parce qu’au clic sur le trigger de la quickview, il ne se passait rien), on cherche dans le markup enfant le lien vers la fiche produit cible et on le stocke dans le local storage via window.localStorage.setItem('clé', valeur);.

app/design/frontend/Vendor/theme/Magento_Catalog/templates/product/view/product-url.phtml: au clic sur le lien « voir la fiche produit », on récupère l’URL dans le local storage (clé quickviewRelatedProductURL):

Le layout XML et les styles de la solution #1 restent valables. Merci de vous y référer.


Solution #1 (pas focntionnelle)

Quickview rattachée au module CartQuickPro fourni avec le thème Venuse.

La quickview s’affiche en cliquant sur un item produit dans le listing produit (page catégorie) du site Magento 2. Elle affiche, dans une iFrame, une partie des éléments de la fiche produit (c’est le même code qui est utilisé pour la quickview et la fiche produit).

Le fichier template PHTML:

  • Objectif: placer un lien vers la fiche produit dans la page.
  • On récupère l’URL de la fiche produit en consultation dans le localStorage (clé: product_data_storage) sous forme de chaîne JSON. Il faut convertir cette chaîne JSON en objet JavaScript pour pouvoir l’exploiter.
  • On récupère l’ID du produit dans le DOM.
  • Au clic sur l’élément a#currentlyViewedProductURL (le lien « Voir la fiche produit »)…
    • …on fait une redirection JS dans la fenêtre parente de l’iFrame (la quickview) qui contient une partie de la fiche produit
    • …et seulement ensuite, on simule le click sur la croix de fermeture de la quickview.

app/design/frontend/Vendor/theme/Magento_Catalog/templates/product/view/product-url.phtml

Bonus:

(inutile pour ce qu’on essaye de faire, mais bon à savoir) Récupérer la première clé d’un objet JSON sans connaître le libellé de cette clé:

Le fichier layout XML:

On s’en sert pour positionner le template PHTML dans la page.

app/design/frontend/Vendor/theme/Magento_Catalog/layout/catalog_product_view.xml

Les styles:

[Magento 2] Mise à jour du prix final dans une fiche produit lorsqu’on vide dynamiquement via javascript une option sous forme de champ texte

Je me suis retrouvé dans un cas extrêmement particulier dans lequel l’utilisateur pouvait, depuis une fiche produit, rajouter des options en cascade: il pouvait en premier lieu choisir une couleur de papier cadeau (+2,00 €).

Une fois le papier cadeau sélectionné (et seulement à cette condition), il pouvait choisir d’ajouter une étiquette avec un prénom (+0,50 €).

Ce champ étiquette était limité à 14 caractères. La fonctionnalité était gérée via un widget remaining-characters.js fourni dans Magento 2.

Problème: lorsque l’utilisateur avait renseigné choisi un papier cadeau et renseigné un prénom, le prix total s’incrémentait de la somme des deux options (+2,00 € +0,50 €). Mais lorsque l’utilisateur décidait finalement de ne pas prendre de papier cadeau en décochant l’option de couleur, seul le prix du papier se décrémentait (-2,00 €) et le prix total comprenait encore celui de l’option étiquette (+0,50 €).

Solution: le plug-in qui compte le nombre de caractères présents dans le champ écoute les événements change keyup paste:

Lorsqu’un utilisateur décoche l’option papier cadeau, on vide l'input text de l’option étiquette avec la méthode .val(''), mais de cette manière le plug-in qui écoute les événements change keyup paste n’a pas « capté » que le champ a été vidé et, de ce fait, ne remet pas le pric total à jour correctement.

Pour lui signifier que le champ a été vidé de manière dynamique, il faut chaîner notre déclaration avec la méthode .trigger() qui contient en argument l’événement change:

Le code complet pour gérer les deux options en cascade

La deuxième contrainte était de faire fonctionner des checkboxes un peu comme des boutons radio (un seul des x checkboxes devait pouvoir être sélectionné à la fois), mais de pouvoir n’en sélectionner aucune.

[Magento 2] Comment inclure et utiliser un fichier JS custom placé dans un thème depuis un template PHTML avec data-mage-init

C’est par ici: [Magento 2] Vérifier qu’un utilisateur client est connecté à son compte et afficher son prénom dans un template PHTML.

Voir aussi: [Magento 2] Comment inclure et utiliser un fichier JS custom avec requireJS.

[Magento 2] Vérifier qu’un utilisateur client est connecté à son compte et afficher son prénom dans un template PHTML

Quelques ressources pour comprendre:

  • Customer Data Management in Magento 2 – récupérer des infos sur le customer en cache (local storage) via l’objet customer déclaré dans le composant JS Magento_Customer/js/view/customer.
  • Sections in Magento 2 – Magento sets customer related data in local storage of browser in key value pair. Each key is known as section. In this post we will see How we can create custom section in our module and use the data in the section in our template file.

Choisissez votre méthode:

Avec javascript (pour afficher le prénom de l’utilisateur)

Source: Magento 2: get customer().lastname in header.phtml (le titre n’étant pas tout-à-fait juste puisqu’on récupère bien le firstName du customer.

Pas besoin de créer un module et de faire de l’injection de dépendances (comme on le voit sur les 36 fils de discussion stack overflow ou sur les 52 blogs qui sont proposés dans les premiers résultats Google…).

Dans votre fichier PHTML, initialisez votre JS sur un élément (span dans mon exemple, mais utilisez l’élément qui vous arrange):

…puis créez un fichier app/design/frontend/VotreVendor/votretheme/web/js/customerGreeting.js et mettez-y ceci:

…et en fait, bin, ça fonctionne 🙂

Pour détecter si l’utilisateur est connecté, créer un Block et le déclarer dans un Layout

app/code/MyVendor/MyModule/Block/ThemeHeader.php:

app/design/frontend/MyVendor/mytheme/Magento_Theme/layout/default.xml:

app/design/frontend/MyVendor/mytheme/Magento_Theme/layout/default.xml:

En en-tête de votre fichier PHTML:

Dans le même fichier PHTML, à l’endroit où vous souhaitez afficher le prénom lorsque l’utilisateur est connecté:

MAUVAISE PRATIQUE La même chose via l'objectManager:

La création du Block et la déclaration de celui-ci dans un Layout comme vu plus haut est inutile si on invoque l'objectManager. Invoquer constamment l’objectManager va poser des problèmes de performances.

En en-tête de votre fichier PHTML:

Vous allez trouver beaucoup de solutions proposant d’utiliser l’objectManager sur le net (stack overflow, autres…). Si elles ne sont pas optimales, elles peuvent quand-même vous apporter une information intéressante à savoir le Model à utiliser si vous souhaitez faire ça bine et créer un Block (dans notre exemple: Magento\Customer\Model\Session. Regardez dans le code du block, plus haut dans ce billet, comment ce Model est déclaré puis exploité).

© 2020 devfrontend.info

Theme by Anders NorénUp ↑