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({});
}
 );
  • I ended up overwriting rules.js like the answer in this topic. – Sanne May 9 '18 at 12:48
5

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',
| improve this answer | |
  • 1
    thanks for sharing. works great.. :) – Ask Bytes Jan 9 at 14:44
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>
| improve this answer | |
  • Hi, I had tried your solution but validation is not done by the plugin. Can you please help me with this? – Ask Bytes Jan 9 at 13:00
  • @AskBytes has you added also custom component? Clear the whole caching, rebuild the statics? – K. Maliszewski Jan 10 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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