Drupal 8 Ajax validations for Custom Form.
Updated: Jul 20, 2022
If God be for us, who can be against Us!?
Recently while creating a custom form for a project, I came across few scenarios where it was mentioned to implement validations that validates while you are filling the form(long term for Ajax validations).
I started looking for help on google and was checking if there is any contributed module that has already implemented this , so that I can take help from the module and implement it on my custom form.
I came across a solution which provides ajax validations when you are done editing the value in the field and move to fill the next field. Without much talking lets straight move to the code.
Created a simple password field in the form and added a ajax validation callback as follows :
Next step is to create a callback function to perform ajax validation.
Thats it!?? It's Done! I guess so!!
With this I was succesfully able to see the Ajax Validation message while entering the password field. But the catch here is, that even though this throws a validation message , it does not really validates!!. There is no check while submitting the form and you can simply bypass the validation and move ahead in the form.
To add the validation, I added the validateForm hook :
Now with this, I was able to avoid form submission with incorrect password generation.
Let's dive deep into the Ajax Response methods used above to display the messages and try to find out various use cases where different methods can be used.
Drupal core ajax library consists of various classes that implements CommandInterface interface to render the ajax element in different manner (as required). Some of the commonly used methods are as follows :
AjaxResponse: JSON response object for AJAX requests.
HtmlCommand: AJAX command for calling the jQuery html() method.
InvokeCommand: AJAX command for invoking an arbitrary jQuery method.
AddCssCommand: An AJAX command for adding CSS to the page via ajax.
PrependCommand: AJAX command for calling the jQuery insert() method.
AfterCommand : AJAX command for calling the jQuery after() method.
BeforeCommand : AJAX command for calling the jQuery before() method.
To go through all the methods, head towards :
In the example above, I have implemented HtmlCommand() method and specified the <selector> where I want to place the validation message. The HtmlCommand() method replaces the content under class ".password-validation" with the new message everytime the element is changed.
For example :
The content inside the div with class ' password-validation ' will be replaced with whatever text i return along with the HtmlCommand() method. Even if it is a field HTML.
I came across a use case, where the message was to be displayed inside the field <div> instead of placing it in a <prefix>. With the example above, the message is displayed before the field html starts as we have used <prefix> to display message.
To display the message inside the div, I made following changes to the code.
Removed the <prefix> from the form element.
Used the class/id of the <input> element to place the message before <input> area and just inside field div.
With this, I was able to get the message displayed inside field div. But the message was being added everytime the field was being changed. To make the message display only once, I made the following change :
Added RemoveCommand() method, to remove the previously added div using it's class name.
This is how the final implementation looks like :
Now I was successfully able to display validation message only once, inside field div and without using <prefix> or <suffix> .
So to summarize, I used Ajax callback method to diplay the validation message while I was entering data in the field and also added a check to avoid user to submit the incorrect password without fulfilling complete requirements.
Thank You. !!