Frontend

Moving the validation error message, this time globally

Moving the validation error message, this time globally

This blog post is a follow up to my previous blog post, which explained how to manage the display of error message on A2C section. By adding one mixin, you will be able to manage the position of error message on any form on any page. Let’s get the show on the road!

There is a proverb, “Life is full of surprises”. I would like to add, so is Magento 2. 😀

While trying some things out on the newsletter form, I noticed it would be great to change the position of the error message on the newsletter email field. I made another custom element #custom-newsletter-error in app/design/frontend/YOUR_VENDOR/YOUR_THEME/Magento_Newsletter/Templates/subscribe.phtml that should contain the error message…

<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>

However, the error message still appears in the default place, after the input field.

This means, there must be something specific on the product page, which makes it work in A2C section, but not elsewhere. In other words, it’s time to start digging through the code. After spending some finding what is where and putting all the pieces of the puzzle together, I was able to identify why it worked on product page only.

It is not nice to point fingers, but…. grouped product.

First thing that caught my attention was the custom data-errors-message-box attribute, which I thought had something to do with it. By searching the vendor/magento folder, the string was used in the following files:

  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, so grouped product has the custom  <div id="validation-message-box"></div>, but I need to know where and how is the JavaScript file loaded on the page. After some additional search in the modules files, I found that it’s used as a RequireJS dependency in  vendor/magento/module-catalog/view/frontend/web/js/validate-product.js

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

Which is loaded 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>

Improve the validation method!

With all the key information at hand, it is possible now to enhance the native validation process and provide this feature globally. First of all, create app/design/frontend/YOUR_VENDOR/YOUR_THEME/requirejs-config.js file and setup a mixin of main validation file:

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

Next logical step is to create the app/design/frontend/YOUR_VENDOR/YOUR_THEME/web/mage/validation-mixin.js , which will override the native options errorPlacement keh  with the following content (actual modification is wrapped with comment, see snippet below):

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;
    }
});

Now, if you refresh the page, the validation of newsletter email field should be placed into the configured HTML element

And there you have it! 🙂 You should now be able to customize where the error message will be displayed on any page on any field.

To test this, I tried to make something very silly – to set the email error on H1 tag on Forgot Password page located in app/design/frontend/YOUR_VENDOR/YOUR_THEME/Magento_Customer/templates/form/forgotpassword.phtml file with the following change:

<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>

This is how it looks like before submitting the form:

And this is how it looks like when submitting the form:

Read more

Add static content in Magento Checkout address form

static content m2 checkout inchoo feat

If you are reading this, you are probably looking for an easy way to add static content to the Checkout address fieldset.

If you open the Magento Checkout module, you will notice technology complexity of the Magento Checkout. When you consider Knockout, HTML, PHTML, XML, JS – such a mix of technologies can often make a simple straightforward task seem super complicated.

Usually, if you need to edit something on the Checkout, you need to create a custom module, which will override the Layout Processor. This approach makes sense if the Checkout modification is complex and there needs to be some kind of a dynamic.

But for simple tasks, such as updating input placeholders, adding the notes to the inputs or adding the text between inputs – custom modules are an overkill.

Let me share with you a simple frontend solution for situations when we need to add some text or an image banner, for example between the Last Name input and the Company input.

Read more

Moving the Add to Cart validation error message on product page

Moving the Add to Cart validation error message on product page

One quite often overlooked, but very important issue might happen because of design changes in the Add to Cart section on the Product Detail Page (PDP) in Magento 2.

This section is very likely to vary from project to project, but regardless of the scope of work and the volume of these changes, error validation on the Quantity field must not cause any issues whatsoever.

In this article, I will show you what needs to be done in such a case, which should be very easy and straightforward to implement in your custom theme.

Read more

Lazy load your images and iframes

lazyload images and iframes

Lazy loading is an effective way to improve your frontend performance. And that’s especially important on eCommerce websites. In this article, you will read (and learn) how to reduce page load time by loading your

  1. images on scroll and
  2. iframes on demand.

Let’s get started with lazy load!

Read more

How did we standardize Magento 2 frontend development?

How did we standardize Magento 2 frontend development?

Many Frontend developers in the Magento community felt a certain level of pain when they started working on their first Magento 2 project. So did we! “This is just a start. I will be faster on the next one“, was a common statement. However, new projects arrived and frontend development was still not as fast as it was with Magento 1.

To improve the speed, efficiency, joy of work and team synergy, our frontend team decided to refine our development processes. After a few completed projects, we got an idea of how to do things better and quicker. Modernizing the approach we’ve been using.

Read more

Magento PWA Studio: Routing and Root Components

Magento PWA Studio: Routing and Root Components

Routing in React is quite complex, and trying to adapt it to work with Magento 2 can be a very challenging task, considering how many URL-related functionalities (like URL rewrites) Magento 2 offers. Luckily, Magento PWA Studio comes with a built-in solution for handling Magento 2 URL-s which is very flexible. In this article, we are going to take a look at the Magento PWA Studio routing and Root Components concept.

Read more

Review: Reacticon – Power to the front-end developers!

PWA Reacticon

Ever since Magento announced their PWA (Progressive Web App) Studio and PWA solutions like Deity started gaining traction, people were more than eager to learn more about how PWA would affect Magento platform and the world of eCommerce in general. Reacticon sought to provide some more in depth information about technologies that will become integral part of our workflow in the near future.

Read more

Sticky Sidebar in Magento

Sticky sidebar

An idea for writing this blog post inspired me for implementing this feature on two Magento 1 projects, on first project it was one of many changes that were part of A/B testing, on the second one it was part of creating a new visual identity for clients store.

So, what basically is sticky sidebar and why should it be used to improve your conversion rate? Well, just like sticky header, the purpose of sticky sidebar is to have the sidebar element displayed in the viewport at all times (or an at least, when some conditions are met). This is ideal place to move the product options (configurable dropdowns, image swatches etc), add to cart button or any other element that is important for your product. With this being said, your customer is free to browse all of the content on your product and once the decision has been made to purchase the product, the add to cart button is just waiting to be clicked on!

Read more

Reorder input fields on Shipping and Billing step in Magento 2

Reorder input fields on Shipping and Billing step in Magento 2

With time we are becoming more and more familiar with Magento 2 Checkout. And we are trying to build our knowledge furthermore. Hopefully, this article will help you in that process. With this article, we’ll learn how to change inputs fields ordering on the Checkout page.

If you ever tested Magento 2 you are familiar with default Magento 2 Checkout and the default fields sort ordering. If you wish to want to recall it, check this screenshot:

Read more

Create a multi-language store in Magento 2 – Part 2

Create a multi-language store in Magento 2 Part 2

In the first post from this series, we’ve focused more on theory and technical background behind multi-language Magento2 store. Now, we’ll create Magento2 store with additional French language. First thing is to go to the administration and create a new store view. Before we proceed, please check documentation where is explained a difference between store view, store and website, old but still relevant, http://docs.magento.com/m1/ce/user_guide/store-operations/stores-multiple.html.

Read more

How to improve usability for Magento 2 add to cart process

How to improve usability for Magento 2 add to cart process

Magento 2 introduced a new and improved way for adding products to the cart. The system now offers complete asynchronous (ajax) process, although the process itself is not activated in default application state. It requires some manual adjustments in the script call inside the templates. Someone would think, ok, we will simply modify the template script calls and that’s it! We successfully improved the process. Unfortunately, not so fast! There is still more room left for improvement. If you’re interested, let’s find out what’s left on the table.

Read more

Magento 2 Widgets – gallery widget explained – client testimonials showcase

Magento 2 Widgets – gallery widget explained – client testimonials showcase

Further to our previous post about Magento gallery widget (in which we explained how to build image gallery) we’d like to show another possible use of this widget. Because it’s based on Fotorama plugin, gallery widget is able to work not just with images but with other HTML content as well. And we’ll demonstrate how by building a client testimonials gallery which we’re going to display in the footer of our web shop.

Read more

Adding Voice Search to Magento 2

Adding Voice Search to Magento 2

Introduction of Web Speech API to Chrome and Firefox opens up some new possibilities in general interaction with websites and, more importantly, accessibility. Web Speech API includes two main components: Speech Recognition and Voice Synthesis. In this article, we are going to use the Speech Recognition API to implement basic Voice Search in Magento 2 header search.

Read more