Do we need to add custom validation just before order placement? Is it possible? Yes, absolutely; Magento 2 is flexible and provides a mechanism to add our custom validation before placing orders.
We often need to validate the order before proceeding, for example. We must validate the postal code, shipping address, billing address, and selected shipping or payment method.
I’d like to see how to add custom validation before placing an order in this post.
Magento 2: Add Custom Validation Before Order Placement
Firstly, we must extend the layout file of the checkout. We need to create checkout_index_inex.xml inside the layout of the front end of the view directory of the custom module.
We can also extend the checkout_index_inex.xml file in the theme. First, however, we will extend the layout file inside our custom module.
So, Let’s create checkout_index_index.xml
<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="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="custom-validatation" xsi:type="array">
<item name="children" xsi:type="array">
<item name="custom-validator" xsi:type="array">
<item name="component" xsi:type="string">Vendor_ModuleName/js/view/customValidator</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
As we can see, we must add a component validator in the payment section of the billing step.
It’s time to create a JS file, which we have added as a component validator in the layout. Next, we must inject model validation JS into it.
define(
[
'uiComponent',
'Magento_Checkout/js/model/payment/additional-validators',
'Vendor_Module/js/model/customValidator'
],
function (Component, additionalValidators, customValidator) {
'use strict';
additionalValidators.registerValidator(customValidator);
return Component.extend({});
}
);
We must write the business logic inside the model validator component file we injected in the above component file.
define(
[
'jquery',
'mage/translate',
'Magento_Ui/js/model/messageList',
'Magento_Checkout/js/model/quote'
],
function ($,$t, messageList, quote) {
'use strict';
return {
validate: function () {
// business logic
if(!condtion) {
return false;
}
return true;
}
}
}
);
That’s it. Isn’t it pretty easy? It’s Easy.
So, let’s check out a real-world example of validation. First, we will restrict the PO Box address from placing the order. In other words, we will put validation before order placement, which validates the shipping address selected or entered by the customer; if we find the street of the shipping address with a PO BOX number, we will throw an error; otherwise, we will allow the customer to place the order.
So let’s go ahead and implement it.
Restrict shipping addresses with a PO Box number.
- checkout_index_index.xml
<?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="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="validate-postal-code-with-shippingadress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="postal-validator" xsi:type="array">
<item name="component" xsi:type="string">SbDevBlog_Checkout/js/view/postalValidator</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
- postalValidator.js to inject the model component.
/**
* @copyright Copyright (c) sbdevblog (http://www.sbdevblog.com)
*/
define(
[
'uiComponent',
'Magento_Checkout/js/model/payment/additional-validators',
'SbDevBlog_Checkout/js/model/postalValidator'
],
function (Component, additionalValidators, postalValidator) {
'use strict';
additionalValidators.registerValidator(postalValidator);
return Component.extend({});
}
);
- postalValidator.js to validate shipping addresses with PO Box numbers.
/**
* @copyright Copyright (c) sbdevblog (http://www.sbdevblog.com)
*/
define(
[
'jquery',
'mage/translate',
'Magento_Ui/js/model/messageList',
'Magento_Checkout/js/model/quote'
],
function ($,$t, messageList, quote) {
'use strict';
return {
validate: function () {
if (window.checkoutConfig.pobox_validation_enabled){
let isValidated = $.map(quote.shippingAddress().street, function (value, index)
{
if(/((((p[\s\.]?)\s?[o\s][\.]?)\s?)|(post\s?office\s?)|(postal\s?)|(post\s?))((box|bin|b\.?)?\s?((num|number|no|#)\.?)?\s?\d+)/igm.test(value))
{
return value;
}
}
)
if(isValidated.length > 0){
messageList.addErrorMessage({message: $t('We do not ship to PO BOX address.')});
}
return isValidated.length === 0;
}
return true;
}
}
}
);
Please take a look at the output.
We have allowed the admin to enable or disable validation from the configuration by accessing the admin configuration in JS.
Please subscribe and share this post with your connections. Also, please use the comment box to share your feedback. Thank you for reading the post-Magento 2: Add Custom Validation Before Order Placement.
Note: Please verify the code of this blog and the relevant git repository before using it in production.
🙂 HAPPY CODING 🙂
2 thoughts on “Magento 2: Add Custom Validation Before Order Placement”