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.