1

On checkout I want users to be able to use 0-9 + and - in the phone field. I'm trying to add a custom validator in my module but I can't seem to get it to work. I followed the steps in this tutorial but in the text is says it's only for the second checkout step but I need it for the first.

How would I get this to work for the phone field? Thanks in advance.

I currently have this:

checkout_index_index

<?xml version="1.0"?>
  <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
  xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceBlock name="checkout.root">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="checkout" xsi:type="array">
                        <item name="children" xsi:type="array">
                            <item name="steps" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="shipping-step" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <item name="shippingAddress" xsi:type="array">
                                                <item name="children" xsi:type="array">

                                                    <item name="shipping-address-fieldset" xsi:type="array">
                                                        <item name="children" xsi:type="array">

                                                            <item name="telephone" xsi:type="array">
                                                                <item name="validation" xsi:type="array">
                                                                    <item name="validate-phonenumber"
                                                                          xsi:type="string">true
                                                                    </item>
                                                                    <item name="stripped-min-length"
                                                                          xsi:type="string">10
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>

                                            </item>
                                        </item>
                                    </item>
                                    <item name="billing-step" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <item name="payment" xsi:type="array">
                                                <item name="children" xsi:type="array">

                                                    <item name="additional-payment-validators" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="validate-phonenumber" xsi:type="array">
                                                                <item name="component" xsi:type="string">
                                                                    BB_Checkout/js/view/validate-phonenumber
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</body>

model/validate-phonenumber.js

define(
[],
function () {
    'use strict';
    return {
        /**
         * Validate something
         *
         * @returns {boolean}
         */
        validate: function() {
            return utils.isEmptyNoTrim(value) || !/[^\d\+\-]/.test(value);
        }
    }
}
 );

view/validate-phonenumber.js

define(
[
    'uiComponent',
    'Magento_Checkout/js/model/payment/additional-validators',
    'BB_Checkout/js/model/validate-phonenumber'
],
function (Component, additionalValidators, validatePhonenumber) {
    'use strict';
    additionalValidators.registerValidator(validatePhonenumber);
    return Component.extend({});
}
 );
1
  • I ended up overwriting rules.js like the answer in this topic.
    – Sanne
    May 9, 2018 at 12:48

2 Answers 2

6

I ended up overwriting rules.js.

I added the following:

'validate-phonenumber': [
        function(value) {
            if (value.length < 10) {
                return false;
            } else {
                return utils.isEmptyNoTrim(value) || !/[^\d\+\-\(\) ]/.test(value);
            }
        },
        $.mage.__('Voer een geldig telefoonnummer in bijvoorbeeld: 0612345678.')
    ],

checkout_index_index.xml

<item name="telephone" xsi:type="array">
      <item name="validation" xsi:type="array">
            <item name="validate-phonenumber"
                     xsi:type="boolean">true
         </item>
    </item>
</item>

And in requirejs-config.js I added this:

   'Magento_Ui/js/lib/validation/rules': 'BB_Checkout/js/lib/validation/rules-overwrite',
2
  • 1
    thanks for sharing. works great.. :)
    – Ask Xah
    Jan 9, 2020 at 14:44
  • i wish you could write this answer in detail to simply understand
    – Mujahidh
    Apr 28, 2021 at 6:43
0

I know that is old post but I had this problem now.

The other solution is prepare custom UI Component and override the validate method. Then You avoid to override whole rules file.

app/code/NAMESPACE/Checkout/view/base/web/js/form/element/text-phone.js

define([
  'mageUtils',
  'Magento_Ui/js/form/element/abstract',
  'Magento_Ui/js/lib/validation/validator'
], function (utils, Abstract, validator) {
  'use strict'

  return Abstract.extend({
    defaults: {
      visible: true,
      label: '',
      error: '',
      uid: utils.uniqueid(),
      disabled: false,
      links: {
        value: '${ $.provider }:${ $.dataScope }'
      }
    },

/**
 * Has service
 *
 * @returns {Boolean} false.
 */
hasService: function () {
  return false;
},

/**
 * Has addons
 *
 * @returns {Boolean} false.
 */
hasAddons: function () {
  return false;
},

/**
 * Calls 'initObservable' of parent
 *
 * @returns {Object} Chainable.
 */
initObservable: function () {
  this._super()
    .observe('disabled visible value');

  return this;
},

/**
 * Validates itself by it's validation rules using validator object.
 * If validation of a rule did not pass, writes it's message to
 * 'error' observable property.
 *
 * @returns {Object} Validate information.
 */
validate: function () {
  var value = this.value(),
    result = validator(this.validation, value, this.validationParams),
    message = !this.disabled() && this.visible() ? result.message : '',
    isValid = this.disabled() || !this.visible() || result.passed;

  if(isValid){
    var regex = /^[0-9./\-()+ ]+$/;
    isValid = !value || regex.test(value);
    if(!isValid){
      message = 'YOUR MESSAGE';
    }
  }

  this.error(message);
  this.error.valueHasMutated();
  this.bubble('error', message);

  if (this.source && !isValid) {
    this.source.set('params.invalid', true);
  }

  return {
    valid: isValid,
    target: this
  };
}

  })
})

You can override it using plugin and afterMerge method

app/code/NAMESPACE/Checkout/Plugin/AttributeMerger.php

 public function afterMerge(parentAttributeMerger $subject, array $result): array
    {

    if (array_key_exists('telephone', $result)) {
        $result['telephone']['component'] = 'NAMESPACE_Checkout/js/form/element/text-phone';
    }

    return $result;
}

app/code/NAMESPACE/Checkout/etc/frontend/di.xml

<type name="\Magento\Checkout\Block\Checkout\AttributeMerger">
        <plugin name="namespace_attribute_merger" type="\NAMESPACE\Checkout\Plugin\AttributeMerger"/>
    </type>
2
  • Hi, I had tried your solution but validation is not done by the plugin. Can you please help me with this?
    – Ask Xah
    Jan 9, 2020 at 13:00
  • @AskBytes has you added also custom component? Clear the whole caching, rebuild the statics? Jan 10, 2020 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.