Magento 2 – Custom Fields Checkout Checkbox Toggle Required

checkoutknockoutjsmagento2magento2.2magento2.2.3

in the Magento 2 checkout I added 3 custom fields, a checkbox that shows the customer two password fields that are used to create an account.

enter image description here

Since the checkbox toggles if the fields are visible or hidden with JavaScript I want the password fields to be required when visible and not required when hidden.

How could I achieve something like this?

I'm creating the fields like this in LayoutProcessor.php

$jsLayoutResult['components']['checkout']['children']['steps']['children']['shipping-step']['children']
    ['shippingAddress']['children']['customer-email']['children']['additional-login-form-fields']['children']['create_account_checkbox'] = [
        'component' => 'Magento_Ui/js/form/element/abstract',
        'config' => [
            'customScope' => 'shippingAddress.custom_attributes',
            'template' => 'ui/form/field',
            'elementTmpl' => 'BB_Checkout/form/element/checkbox-overwrite'
        ],
        'provider' => 'checkoutProvider',
        'dataScope' => 'shippingAddress.custom_attributes.create_account_checkbox',
        'description' => __('I would like to create an account'),
        'sortOrder' => '1004',
        'validation' => [
            'required-entry' => false,
        ]
    ];

    $jsLayoutResult['components']['checkout']['children']['steps']['children']['shipping-step']['children']
    ['shippingAddress']['children']['customer-email']['children']['additional-login-form-fields']['children']['create_account_password'] = [
        'component' => 'Magento_Ui/js/form/element/abstract',
        'config' => [
            'customScope' => 'shippingAddress.custom_attributes',
            'customEntry' => null,
            'template' => 'ui/form/field',
            'elementTmpl' => 'BB_Checkout/form/element/password-overwrite'
        ],
        'dataScope' => 'shippingAddress.custom_attributes.create_account_password',
        'label' =>  __('Password'),
        'provider' => 'checkoutProvider',
        'validation' => [
            'validate-password' => true,
            'required-entry' => true
        ],
        'options' => [],
        'filterBy' => null,
        'customEntry' => null,
        'visible' => true,
        'sortOrder' => '1005'
    ];

    $jsLayoutResult['components']['checkout']['children']['steps']['children']['shipping-step']['children']
    ['shippingAddress']['children']['customer-email']['children']['additional-login-form-fields']['children']['create_account_password_confirm'] = [
        'component' => 'Magento_Ui/js/form/element/abstract',
        'config' => [
            'customScope' => 'shippingAddress.custom_attributes',
            'customEntry' => null,
            'template' => 'ui/form/field',
            'elementTmpl' => 'BB_Checkout/form/element/password-overwrite-confirm-password'
        ],
        'dataScope' => 'shippingAddress.custom_attributes.create_account_password_confirm',
        'label' => __('Confirm password'),
        'provider' => 'checkoutProvider',
        'validation' => [
            'required-entry' => true
        ],
        'options' => [],
        'filterBy' => null,
        'customEntry' => null,
        'visible' => true,
        'sortOrder' => '1006'
    ];

And i'm currently hiding and showing them like this:

create-account.js

require([
'jquery'
], function ($) {
return togglePasswordFields = function () {
    if($('input[name*="create_account_checkbox"]:checked').length && 
 $('.form-login .hidden-fields:visible').length != 1) {

 $('div[name*="create_account_password"]').css('display','block'); $('div[name*="create_account_password_confirm"]').css('display','block');

$('div[name*="create_account_password"]').setAttribute('aria-required', true);

$('div[name*="create_account_password_confirm"]').setAttribute('aria-required', true); 

$('div[name*="create_account_password"]').css('display','none');


$('div[name*="create_account_password_confirm"]').css('display','none');
        $('div[name*="create_account_password"]').setAttribute('aria-required', false);

 $('div[name*="create_account_password_confirm"]').setAttribute('aria-required', false);
    }
}
});

The aria-required, true/ doesn't do a thing right now.

Thanks!

Best Answer

I ended up replacing 'required-entry' with a custom validator that checks if the checkbox is checked first.

validation-mixin.js

 define([
'jquery',
'Magento_Ui/js/lib/validation/utils'
], function ($, utils) {
"use strict";

return function (validator) {
    var hiddenLoginFields = $('.form-login .hidden-fields');
    var createAcccountCheckbox = $('input[name*="create_account_checkbox"]');

 validator.addRule(
        'required-entry-if-create-account-checked',
        function (value) {
            if(hiddenLoginFields.is(':visible') || !$('input[name*="create_account_checkbox"]').is(":checked")) {
                    return true;
                } else {
                    return !utils.isEmpty(value);
                }
        },
        $.mage.__('This is a required field.')
    );
    validator.addRule(
        'validate-create_password',
        function (value) {
            if(hiddenLoginFields.is(':visible') || !$('input[name*="create_account_checkbox"]').is(":checked")) {
                return true;
            } else {
                var pass;

                if (value == null) {
                    return false;
                }

                pass = $.trim(value);

                if (!pass.length) {
                    return true;
                }

                return !(pass.length > 0 && pass.length < 6);
            }
        },
        $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')
    );
    validator.addRule(
        'validate-confirm_password',
        function (value) {
            if(hiddenLoginFields.is(':visible') || !$('input[name*="create_account_checkbox"]').is(":checked")) {
                return true;
            } else {
                return $('input[name*="create_account_password"]').val() === $('input[name*="create_account_password_confirm"]').val();
            }
        },
        $.mage.__('Please enter the same value again.')
    );
return validator;
}
 });
Related Topic