Reputation: 908
I am doing a kind of calculator where it is necessary for the client to enter data to perform the calculation.
I am validating the information from the client side but I would also like to do it from the server side. This is the example I'm following but I do not know how to make it compatible with my problem.
@RestController
@RequestMapping(value = "/api")
public class CalculationController {
...
@RequestMapping(value = "calculate", method = RequestMethod.POST)
public double[] calculate(@ModelAttribute("calcForm") @Validated CalculationForm form,
BindingResult result,
final RedirectAttributes redirectAttributes) {
double[] ans = new double[4];
// Calculate and fill ans
return ans;
}
My AJAX POST:
function calculate() {
if ($('#zone').val() === '' || $('#roofArea').val() === '' || $('#roofType').val() === '') {
alert("Missing data");
} else {
var dataIn = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "api/calculate",
data: dataIn,
dataType: "json",
success: function (data) {
// Update labels in page
},
error: function (e) {
alert("Error: " + e);
},
done: function (msg) {
alert("Done: " + msg);
},
async: false
});
return false;
};
Ànd my validator:
@Component
public class BasicValidator implements Validator {
private Pattern pattern;
private Matcher matcher;
private static final String AREA_PATTERN = "^\\d+(\\.\\d{1,2})?$";
@Override
public boolean supports(Class<?> clazz) {
return CalculationForm.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
CalculationForm form = (CalculationForm) target;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "zone", "You must select a city or area of the map.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "roofArea", "You must enter the roof area.");
pattern = Pattern.compile(AREA_PATTERN);
matcher = pattern.matcher(String.valueOf(form.getRoofArea()));
if (!matcher.matches())
errors.rejectValue("roofArea", "You must enter a valid number.");
}
}
I am using AJAX because I need when the form is completed only the values of some particular labels are updated, so I can not reload the page.
The problem is that, if everything is correct, /api/calculate
returns an array of doubles that I use to populate the page. But if an error occurs (does not fill in the required fields), I need you to tell me where the error occurred in order to display the corresponding message.
Upvotes: 0
Views: 487
Reputation: 8396
You need to use following domain object to send response:
public class JsonResponse {
private String status = null;
private Object result = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
It contain two properties, “status” and “result”. “status” field is of type String and will contain “FAIL” or “SUCCESS”. “result” will contain the other data that are to be send back to the browser.
Now change your controller method to return JsonResponse for both success and fail cases.
@RequestMapping(value = "calculate", method = RequestMethod.POST)
public JsonResponse calculate(@ModelAttribute("calcForm") @Validated CalculationForm form,
BindingResult result,
final RedirectAttributes redirectAttributes) {
JsonResponse res = new JsonResponse();
if(!result.hasErrors()) {
double[] ans = new double[4];
-----------------------------
-----------------------------
res.setResult(ans);
res.setStatus("SUCCESS");
res.setResult(userList);
} else {
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
Now inside your ajax success function check for validation.
success: function (data) {
if(data.status == "SUCCESS") {
// Update labels in page
} else {
errorInfo = "";
for(i =0 ; i < data.result.length ; i++) {
errorInfo += "<br>" + (i + 1) +". " + data.result[i].code;
}
//add a div with id error to show errors.
$('#error').html("Please correct following errors: " + errorInfo);
}
},
Upvotes: 2