As a little bonus, client-side validation has become very easy nowadays with the HTML5 form validation specification. If your target browsers are Internet Explorer 10 and above, adding client-side validation is as easy as specifying the correct input type instead of just using text.
By adding the client-side validation, we can prevalidate the form and avoid overloading the server with requests that we know are incorrect. More information on the client-side validation specification is available at http://caniuse.com/#search=validation.
We can modify our inputs to enable simple client-side validation. The previous inputs, as shown in the following code:
<input th:field="${profileForm.twitterHandle}" id="twitterHandle" type="text" th:errorclass="invalid"/> <input th:field="${profileForm.email}" id="email" type="text" th:errorclass="invalid"/> <input th:field="${profileForm.birthDate}" id="birthDate" type="text" th:errorclass="invalid"/> <input type="text" th:field="*{tastes[__${rowStat.index}__]}" th:placeholder="#{taste.placeholder}"/>
This becomes:
<input th:field="${profileForm.twitterHandle}" id="twitterHandle" type="text" required="required" th:errorclass="invalid"/> <input th:field="${profileForm.email}" id="email" type="email" required="required" th:errorclass="invalid"/> <input th:field="${profileForm.birthDate}" id="birthDate" type="text" required="required" th:errorclass="invalid"/> <input type="text" required="required" th:field="*{tastes[__${rowStat.index}__]}" th:placeholder="#{taste.placeholder}"/>
With this method, your browser will detect when the form is submitted and validate each attribute according to its type. The required
attribute forces the user to enter a nonblank value. The email
type enforces basic e-mail validation rules on the corresponding field.
Other types of validators also exist. Take a look at http://www.the-art-of-web.com/html/html5-form-validation.
The downside of this method is that our add taste and remove taste buttons will now trigger validation. To fix this, we need to include a script at the bottom of the default layout, right after the jQuery declaration.
However, it would be best to include it only on the profile page. To do this, we can add a new fragment section in the layout/default.html
page, just before the end of the body tag:
<script type="text/javascript" layout:fragment="script"> </script>
This will allow us to include an additional script on each page if needed.
Now, we can add the following script to our profile page, just before closing the body tag:
<script layout:fragment="script"> $('button').bind('click', function(e) { if (e.currentTarget.name === 'save') { $(e.currentTarget.form).removeAttr('novalidate'); } else { $(e.currentTarget.form).attr('novalidate', 'novalidate'); } }); </script>
Form validation won't be triggered when a novalidate
attribute is present on the form. This little script will dynamically remove the novalidate
attribute if the action of the form is named save
if the name of the input is different, the novalidate
attribute will always be added. Validation will thus be triggered only by the save button.