jquery - Recommended way to handle Thymeleaf Spring MVC AJAX Forms and their error messages -
what recommended way handle ajax forms , error messages on thymeleaf side of things?
i have spring controller returns json overview of fields , respective error messages, having resort using handwritten jquery (or regular javascript) feels bit wrong, , slow; because of large amount of forms intend have in application.
what replace entire form when error occurs. following super primitive example. i'm not going use ton of fragments rendering form... keeping simple.
this written in spring 4.2.1 , thymeleaf 2.1.4
a basic class representing user info form: userinfo.java
package myapp.forms; import org.hibernate.validator.constraints.email; import javax.validation.constraints.size; import lombok.data; @data public class userinfo { @email private string email; @size(min = 1, message = "first name cannot blank") private string firstname; }
the controller: usersajaxcontroller.java
import myapp.forms.userinfo; import myapp.services.userservices; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.ui.model; import org.springframework.validation.bindingresult; import org.springframework.web.bind.annotation.*; import javax.transaction.transactional; @controller @transactional @requestmapping("/async/users") public class usersajaxcontroller { @autowired private userservices userservices; @requestmapping(value = "/saveuserinfo", method = requestmethod.post) public string saveuserinfo(@valid @modelattribute("userinfo") userinfo userinfo, bindingresult result, model model) { // if errors, re-render user info edit form if (result.haserrors()) { return "fragments/user :: info-form"; } // let service layer handle saving of validated form fields userservices.saveuserinfo(userinfo); return "fragments/user :: info-success"; } }
the file used render form , success message: fragments/user.html
<div th:fragment="info-form" xmlns:th="http://www.thymeleaf.org" th:remove="tag"> <form id="userinfo" name="userinfo" th:action="@{/async/users/saveuserinfo}" th:object="${userinfo}" method="post"> <div th:classappend="${#fields.haserrors('firstname')}?has-error"> <label class="control-label">first name</label> <input th:field="*{firstname}" type="text" /> </div> <div th:classappend="${#fields.haserrors('first')}?has-error"> <label class="control-label">email</label> <input th:field="*{email}" ftype="text" /> </div> <input type="submit" value="save" /> </form> </div> <div th:fragment="info-success" xmlns:th="http://www.thymeleaf.org" th:remove="tag"> <p>form submitted</p> </div>
the js code submit form url provided in form action attribute. when response returned js callback, check errors. if there errors, replace form 1 response.
(function($){ var $form = $('#userinfo'); $form.on('submit', function(e) { e.preventdefault(); $.ajax({ url: $form.attr('action'), type: 'post', data: $form.serialize(), success: function(response) { // if response contains errors, replace form if ($(response).find('.has-error').length) { $form.replacewith(response); } else { // in case can replace form // response well, unless want // show success message different way } } }); }) }(jquery));
again, basic example. mentioned in comments above, there no right or wrong way go this. isn't preferred solution either, there few tweaks do, general idea there.
note: there's flaw in js code well. if replace form 1 response, form submit handler not applied newly replaced form. need ensure reinitialize form handler after replacing form, if going route.
Comments
Post a Comment