Het validatiefoutbericht verplaatsen, dit keer globaal

Deze blogpost is een vervolg op mijn vorige blogpost, waarin werd uitgelegd hoe u de weergave van een foutmelding in de A2C-sectie kunt beheren. Door één mixin toe te voegen, kunt u de positie van de foutmelding op elk formulier op elke pagina beheren. Laten we de show op de weg krijgen!

 

Er is een spreekwoord: “Het leven zit vol verrassingen”. Ik zou graag willen toevoegen, evenals Magento 2. 😀

Terwijl ik wat dingen uitprobeerde op het nieuwsbriefformulier, merkte ik dat het geweldig zou zijn om de positie van de foutmelding in het nieuwsbrief-e-mailveld te veranderen. Ik heb nog een aangepast element gemaakt #custom-newsletter-error in app/design/frontend/YOUR_VENDOR/YOUR_THEME/Magento_Newsletter/Templates/subscribe.phtml dat zou de foutmelding moeten bevatten …

<div class="block newsletter">
    ...
    <p id="custom-newsletter-error"><?= $block->escapeHtml('Newsletter error should appear here.') ?></p>
    ...
    <input name="email" type="email" id="newsletter"
           placeholder="<?= $block->escapeHtmlAttr(__('Enter your email address')) ?>"
           data-mage-init="{"mage/trim-input":{}}"
           data-validate="{required:true, 'validate-email':true}"
           data-errors-message-box="#custom-newsletter-error"
    />
    ...
</div>

De foutmelding verschijnt echter nog steeds op de standaardplaats, na het invoerveld.

Dit betekent dat er iets specifieks op de productpagina moet staan, waardoor het in de A2C-sectie werkt, maar niet elders. Met andere woorden, het is tijd om door de code te spitten. Nadat ik wat tijd had besteed aan het vinden van wat waar is en alle puzzelstukjes in elkaar had gezet, kon ik vaststellen waarom het alleen op de productpagina werkte.

Met de vinger wijzen is niet leuk, maar…. gegroepeerd product.

Het eerste dat mijn aandacht trok, was de gewoonte data-errors-message-box attribuut, waarvan ik dacht dat het er iets mee te maken had. Door te zoeken op de vendor/magento map, werd de tekenreeks gebruikt in de volgende bestanden:

  1. vendor/magento/module-catalog/view/frontend/web/product/view/validation.js
  2. vendor/magento/module-grouped-product/view/frontend/templates/product/view/type/grouped.phtml

Ok, dus gegroepeerd product heeft de gewoonte <div id="validation-message-box"></div>, maar ik moet weten waar en hoe het JavaScript-bestand op de pagina wordt geladen. Na wat extra zoeken in de modulebestanden, ontdekte ik dat het wordt gebruikt als een RequireJS-afhankelijkheid in vendor/magento/module-catalog/view/frontend/web/js/validate-product.js

define([
    'jquery',
    'mage/mage',
    'Magento_Catalog/product/view/validation',
    'catalogAddToCart'
], function ($) {
    ...
});

die is geladen in vendor/magento/module-catalog/view/frontend/templates/product/view/addtocart.phtml

...
<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "Magento_Catalog/js/validate-product": {}
        }
    }
</script>

Verbeter de validatiemethode!

Met alle belangrijke informatie bij de hand, is het nu mogelijk om het native validatieproces te verbeteren en deze functie wereldwijd aan te bieden. Maak eerst app/design/frontend/YOUR_VENDOR/YOUR_THEME/requirejs-config.js bestand en stel een mixin van het hoofdvalidatiebestand in:

var config = {
    config: {
        mixins: {
            'mage/validation': {
                'mage/validation-mixin': true
            },
        }
    }
};

De volgende logische stap is het maken van de app/design/frontend/YOUR_VENDOR/YOUR_THEME/web/mage/validation-mixin.js , die de native . zal overschrijven options errorPlacement keh met de volgende inhoud (werkelijke wijziging is verpakt met commentaar, zie fragment hieronder):

define([
    'jquery',
    'jquery-ui-modules/widget'
], function ($) {
    'use strict';
 
    var enhancedMageValidation = {
        /**
         * @param {*} error
         * @param {*} element
         */
        options: {
            errorPlacement: function (error, element) {
                var errorPlacement = element,
                    fieldWrapper,
                    messageBox;
 
                /* added snippet - start */
                // use custom element to display error message
                if (element.attr('data-errors-message-box')) {
                    messageBox = $(element.attr('data-errors-message-box'));
                    messageBox.html(error);
 
                    return;
                }
                /* added snippet - end */
 
                // logic for date-picker error placement
                if (element.hasClass('_has-datepicker')) {
                    errorPlacement = element.siblings('button');
                }
                // logic for field wrapper
                fieldWrapper = element.closest('.addon');
 
                if (fieldWrapper.length) {
                    errorPlacement = fieldWrapper.after(error);
                }
                //logic for checkboxes/radio
                if (element.is(':checkbox') || element.is(':radio')) {
                    errorPlacement = element.parents('.control').children().last();
 
                    //fallback if group does not have .control parent
                    if (!errorPlacement.length) {
                        errorPlacement = element.siblings('label').last();
                    }
                }
                //logic for control with tooltip
                if (element.siblings('.tooltip').length) {
                    errorPlacement = element.siblings('.tooltip');
                }
                //logic for select with tooltip in after element
                if (element.next().find('.tooltip').length) {
                    errorPlacement = element.next();
                }
                errorPlacement.after(error);
            }
        }
    }
 
    return function (mageValidation) {
        $.widget('mage.validation', mageValidation, enhancedMageValidation);
 
        return $.mage.validation;
    }
});

Als u nu de pagina vernieuwt, moet de validatie van het e-mailveld voor de nieuwsbrief in het geconfigureerde HTML-element worden geplaatst

En daar heb je het! 🙂 U zou nu in staat moeten zijn om aan te passen waar het foutbericht op elke pagina in elk veld wordt weergegeven.

Om dit te testen, heb ik geprobeerd iets heel doms te maken – om de e-mailfout in te stellen op de H1-tag op de pagina Wachtwoord vergeten in app/design/frontend/YOUR_VENDOR/YOUR_THEME/Magento_Customer/templates/form/forgotpassword.phtml bestand met de volgende wijziging:

<form class="form password forget"
      action="<?= $block->escapeUrl($block->getUrl('*/*/forgotpasswordpost')) ?>"
      method="post"
      id="form-validate"
      data-mage-init="{"validation":{}}">
    ...
    <input
        type="email"
        name="email"
        alt="email"
        id="email_address"
        class="input-text"
        value="<?= $block->escapeHtmlAttr($block->getEmailValue()) ?>"
        data-mage-init="{"mage/trim-input":{}}"
        data-validate="{required:true, 'validate-email':true}"
        data-errors-message-box="h1 span"
    />
</form>

Zo ziet het eruit voordat u het formulier verzendt:

En zo ziet het eruit bij het indienen van het formulier:

badges

Let’s connect

We hebben altijd zin in nieuwe en uitdagende projecten. We gaan graag met je in gesprek!