Validate a custom form in Magento 2

Validate a custom form in Magento 2

This article will cover the fundamentals of validating any form in Magento 2.

The contact form on Contact us page will be used and modified for the purpose of the article. The form itself can be found in the following paths, depending on the type of installation you are using:

  • app/code/Magento/Contact/view/frontend/templates/form.phtml
  • vendor/magento/module-contact/view/frontend/templates/form.phtml

In order to demonstrate how to get the forms to be validated, let’s create a validation-free form with some fields. Copy the file from one of the paths above and paste it into your theme:

  • app/code/VENDOR/THEME/Magento_Contact/frontend/templates/form.phtml

Next, paste the following code inside of it:

<form class="form contact-inchoo" action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>" id="contact-form" method="post" data-hasrequired="* Required Fields">
	<fieldset class="fieldset">
		<div class="field name required">
			<label class="label" for="field1"><span>Field 1 (using data-validate)</span></label>
			<div class="control">
                		<input name="field1" id="field1" title="Field 1" value="" class="input-text" type="text" />
			</div>
		</div>
	        <div class="field name required">
			<label class="label" for="field2"><span>Field 2 (using attribute)</span></label>
			<div class="control">
                		<input name="field2" id="field2" title="Field 2" value="" class="input-text" type="text" />
			</div>
		</div>
        	<div class="field name required">
            		<label class="label" for="field3"><span>Field 3 (using classname)</span></label>
            		<div class="control">
                		<input name="field3" id="field3" title="Field 2" value="" type="text" class="input-text" />
            		</div>
        	</div>
        	<div class="field name required">
            		<label class="label" for="field4"><span>Field 4 (using data-mage-init)</span></label>
            		<div class="control">
                		<input name="field4" id="field4" title="Field 4" value="" class="input-text" type="text" />
            		</div>
        	</div>
	        <?php echo $block->getChildHtml('form.additional.info'); ?>
	</fieldset>
	<div class="actions-toolbar">
	        <div class="primary">
            		<input type="hidden" name="hideit" id="hideit" value="" />
            		<button type="submit" title="Submit" class="action submit primary">
                		<span>Submit</span>
            		</button>
        	</div>
    	</div>
</form>

Your form should look like this one:

If you click the “Submit” button, the form would be submitted.

Step 1: add the validation component

Add this attribute on the form tag:

data-mage-init='{"validation":{}}'

This one data attribute tells Magento that the form must be validated before submit and that  validation alias should invoke some particular file using RequireJS. If you take a look at the page source of the compiled file RequireJS config file (found in pub/static/frontend/VENDOR/THEME/LOCALE/requirejs-config.json), you should be able to find the following snippet:

var config = {
	map: {
		"*": {
			...
			"validation": "mage/validation/validation",
			...
		}
	}
	...
};

The string on the right of the validation alias matches the lib/web/mage/validation/validation.js file that will load entire validation logic and take care of your input fields.

Step 2: add some validation rules to your input fields

By looking at the code of validation logic, Magento made it possible to set validation rule names by using one of the following methods listed here:

  1. method #1 – by setting data-validate attribute on the input field:
    <input data-validate='{"required":true}'name="field1" id="field1" ... />
  2. method #2 – by setting the rule names as attributes:
    <input required="true" name="field2" id="field2" ... />
  3. method #3 – by setting the rule names as classnames:
    <input class="input-text required" name="field3" id="field3" ... />
  4. method #4 – by setting the rules inside of the data-mage-init attribute on the form tag
    <form ... data-mage-init='{
    	"validation":{
    		"rules": {
    			"field4": {
    				"required":true
    			}
    		}
    	}
    }'>

Now when you submit your form, all of the fields should be invalid, like on the image:

Rules with arguments

If you have to use a rule that requires a parameter (for example, minlength, maxlength and many other) you can use one of the following three methods, which ever you prefer:

  • method #1
    data-validate='{
    	"required":true,
    	"minlength":10
    }'
  • method #2
    required="true" minlength="15"
  • method #4 – you have to manually specify name attribute of each input field which rules are applied (which is already taken care of if you use it inline with data-validate attribute)
    data-mage-init='{
    	"validation":{
    		"rules": {
    			"field4": {
    				"required":true,
    				"minlength":20
    			}
    		}
    	}
    }'

List of form validation rules

To wrap up this article, a list of validation rule names is provided here as a quick reference toward the official documentation:

  1. jQuery rules:
    1. required,
    2. remote,
    3. email,
    4. url,
    5. date,
    6. dateISO,
    7. number,
    8. digits,
    9. creditcard,
    10. equalTo,
    11. maxlength,
    12. minlength,
    13. rangelength,
    14. range,
    15. max,
    16. min
  2. Magento rules:
    1. max-words
    2. min-words
    3. range-words
    4. letters-with-basic-punc
    5. alphanumeric
    6. letters-only
    7. no-whitespace
    8. zip-range
    9. integer
    10. vinUS
    11. dateITA
    12. dateNL
    13. time
    14. time12h
    15. phoneUS
    16. phoneUK
    17. mobileUK
    18. stripped-min-length
    19. email2
    20. url2
    21. credit-card-types
    22. ipv4
    23. ipv6
    24. pattern
    25. allow-container-className
    26. validate-no-html-tags
    27. validate-select
    28. validate-no-empty
    29. validate-alphanum-with-spaces
    30. validate-data
    31. validate-street
    32. validate-phoneStrict
    33. validate-phoneLax
    34. validate-fax
    35. validate-email
    36. validate-emailSender
    37. validate-password
    38. validate-admin-password
    39. validate-customer-password
    40. validate-url
    41. validate-clean-url
    42. validate-xml-identifier
    43. validate-ssn
    44. validate-zip-us
    45. validate-date-au
    46. validate-currency-dollar
    47. validate-not-negative-number
    48. validate-zero-or-greater
    49. validate-greater-than-zero
    50. validate-css-length
    51. validate-number
    52. required-number
    53. validate-number-range
    54. validate-digits
    55. validate-digits-range
    56. validate-range
    57. validate-alpha
    58. validate-code
    59. validate-alphanum
    60. validate-date
    61. validate-date-range
    62. validate-cpassword
    63. validate-identifier
    64. validate-zip-international
    65. validate-one-required
    66. validate-state
    67. required-file
    68. validate-ajax-error
    69. validate-optional-datetime
    70. validate-required-datetime
    71. validate-one-required-by-name
    72. less-than-equals-to
    73. greater-than-equals-to
    74. validate-emails
    75. validate-cc-type-select
    76. validate-cc-number
    77. validate-cc-type
    78. validate-cc-exp
    79. validate-cc-cvn
    80. validate-cc-ukss
    81. validate-length
    82. required-entry
    83. not-negative-amount
    84. validate-per-page-value-list
    85. validate-per-page-value
    86. validate-new-password
    87. required-if-not-specified
    88. required-if-all-sku-empty-and-file-not-loaded
    89. required-if-specified
    90. required-number-if-specified
    91. datetime-validation
    92. required-text-swatch-entry
    93. required-visual-swatch-entry
    94. required-dropdown-attribute-entry
    95. Validate-item-quantity
    96. validate-grouped-qty
    97. validate-one-checkbox-required-by-name
    98. validate-date-between
    99. validate-dob

Congratulations, you have reached the end of this article! If you have any questions, feel free to post a comment below.

Related Inchoo Services

You made it all the way down here so you must have enjoyed this post! You may also like:

3 best open-source eCommerce platforms in 2021 Zrinka Antolovic
Zrinka Antolovic, | 8

3 best open-source eCommerce platforms in 2021

Moving the validation error message, this time globally Danijel Vrgoc
, | 0

Moving the validation error message, this time globally

Add static content in Magento Checkout address form Mladen Ristic
, | 2

Add static content in Magento Checkout address form

16 comments

  1. I do understand that this article has focus on frontend validation, but form_key needs to be part of html form, like so

  2. 1-
    app/code/Magento/Contact/view/frontend/templates/form.phtml
    2-
    vendor/magento/module-contact/view/frontend/templates/form.phtml

    I do not find all the components of this direction so must I create them ?

  3. Hello,
    I want to apply pattern validation so how can I check to validate?

    i tried `data-msg-pattern=”Invalid firstname”` but nothing happned.

    Please Help me.

  4. What if the part of the form that needs to be required is a Select? Pretty much no info out there on select drop downs.

  5. Hi Danijel,
    The form only validate when we hit submit. Can we customize as user type in input field?

  6. I strongly recomend using form_key in custom forms! I do understand that this article has focus on frontend validation, but form_key needs to be part of html form, like so:

    <input name="form_key" type="hidden" value="<?php echo $block->getFormKey();?>" />

    For custom modules – form_key validation in server side (controller) is achieved using method validate of object \Magento\Framework\Data\Form\FormKey\Validator. Build-in controllers checks form_key on default.

  7. I’m struggling to find any example of regex pattern rule and how to pass it as css class on admin field form.

  8. Hello ,
    Is there any way to add custom validation message for each input in magento 2 ?

    1. you can add messages following the same structure as on rules:
      “validation”:{
      “rules”: {
      “field4”: {
      “required”:true,
      “minlength”:20
      }
      },
      “messages”: {
      “field4”: {
      “required”: “error message 1”,
      “minlength”: “error message 2”
      }
      }
      }

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.