How to collect form data and convert them json format and send back to server in spring mvc - ajax

I have form and I want to grab the data inserted by users and then convert them json format.
So first here is my form—
<form id="patient_form" action="#" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="firstName"> First Name<em>*</em></label>
<div class="controls">
<input type="text" id="firstName" class="required" maxlength="100"
placeholder="First Name" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="middleNameInitial">
Middle Name Initial</label>
<div class="controls">
<input type="text" id="middleNameInitial"
placeholder="Middle Name Initial" class="input-small"
maxlength="1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="lastName"> Last Name <em>*</em></label>
<div class="controls">
<input type="text" id="lastName" placeholder="Last Name"
class="required" maxlength="100" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="dateOfBirth"> Date Of
Birth</label>
<div class="controls">
<input type="text" id="dateOfBirth" class="required" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="button" class="btn btn-primary"
onclick="savePatientInfo()">Save Changes</button>
<button type="button" class="btn"
onclick="cancelPatientInfoForm()">Cancel</button>
</div>
</div>
</form>
And then I want to send back them to server. And for server side code, I’m using spring mvc and client side I’m using JQuery.
Now how can I do it? I need two things basically,
Ajax call (JavaScript function to which will basically do 3 things, one- grab the form data and convert them into json and then ajax call)
Sever side method to consume ajax call (Controller method as I’m
suing spring mvc.)
Any help is much appreciated.

First of all you need to perform ajax call from the JSP as below:
$.post("${pageContext.servletContext.contextPath}/ajaxTestData",
{
firstName:$("#firstName").val(),
middleNameInitial:$("#middleNameInitial").val(),
<other form data>
},
function(j)
{
<j is the string you will return from the controller function.>
});
Now in the controller you need to map the ajax request as below:
#RequestMapping(value="/ajaxTestData", method=RequestMethod.POST)
#ResponseBody
public String calculateTestData(#RequestParam("firstName") String firstName, #RequestParam("middleNameInitial") String middleNameInitial, HttpServletRequest request, HttpServletResponse response){
<perform the task here and return the String result.>
return "xyz";
}
I have not used the JSON input and result in this way but I think if you return the Pojo then it might converts the same in the json format automatically. Just check that.
Hope this helps you. Cheers.

Related

.netcore client-side validation for different onPost handlers (multiple events)

In my .nercore razor page project I have a number of forms with multiple onPost handlers - different buttons for different events (eg. add / copy / edit / delete)
My problem is - I do not understand how I can differentiate client-side validation depending on the button pressed.
EDIT
Let's assume, I have the following .cshtml which defines two input data fields and two buttons. By pressing one button (Add) the first Field A should be validated, by pressing the second (copy) - another one (Field B):
#page "{id:int}/{modeR:int}"
#model MyProject.Pages.MyProjectDB.AddRecordModel
#{
ViewData["Title"] = "Add Record";
}
<div class="row">
<div class="col-md-7">
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="myClass.FieldA" class="control-label"></label>
<input asp-for="myClass.FieldA" class="form-control" />
<span asp-validation-for="myClass.FieldA" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="myClass.FieldB" class="control-label"></label>
<input asp-for="myClass.FieldB" class="form-control" />
<span asp-validation-for="myClass.FieldB" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" value="Add" class="btn btn-success">Add Record)</button>
<button type="submit" value="Copy" class="btn btn-warning">Edit Record</button>
</div>
</form>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
at the end of my .cshtml page, but it runs always when onPost is called.
I need to run validation "in groups": for one button set of one fields and ignore others, for another - another set and so on like written above
Is there any way to achieve it without writing custom javascript or do it on server side?..
ANOTHER EDIT
The answer was provided for the case where we have clear separation of input fields / buttons. But how can we handle this if we have two input fields and one button. Validation should NOT be fire if either of them is filled in and should fire if both are null. I understand, this sounds a bit strange, but in my example I have one input field and one dropdown-list. So, either a field should be filled-in or an item should be selected from the list, but for code simplicity let's stay with two input fields (Filed A and Field B, one of them should be filled) and one button:
#page "{id:int}/{modeR:int}"
#model MyProject.Pages.MyProjectDB.AddRecordModel
#{
ViewData["Title"] = "Add Record";
}
<div class="row">
<div class="col-md-7">
<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="myClass.FieldA" class="control-label"></label>
<input asp-for="myClass.FieldA" class="form-control" />
<span asp-validation-for="myClass.FieldA" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="myClass.FieldB" class="control-label"></label>
<input asp-for="myClass.FieldB" class="form-control" />
<span asp-validation-for="myClass.FieldB" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" value="Add" class="btn btn-success">Add Record)</button>
</div>
</form>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Thanks in advance!
By pressing one button (Add) the first Field A should be validated, by pressing the second (copy) - another one (Field B) should be validated
You can try to put them in separate <form> and specify handler method via the asp-page-handler attribute, like below.
<h1>Go Add Handler</h1>
<form method="post">
<div class="form-group">
<label asp-for="myClass.FieldA" class="control-label"></label>
<input asp-for="myClass.FieldA" class="form-control" />
<span asp-validation-for="myClass.FieldA" class="text-danger"></span>
</div>
<div>
<button type="submit" value="Add" class="btn btn-success" asp-page-handler="Add">Add Record</button>
</div>
</form>
<hr />
<h1>Go Copy Handler</h1>
<form id="myform" method="post">
<div class="form-group">
<label asp-for="myClass.FieldB" class="control-label"></label>
<input asp-for="myClass.FieldB" class="form-control" />
<span asp-validation-for="myClass.FieldB" class="text-danger"></span>
</div>
<div>
<button type="submit" value="Copy" class="btn btn-warning" asp-page-handler="Copy">Edit Record</button>
</div>
</form>
#section scripts{
#await Html.PartialAsync("_ValidationScriptsPartial")
}
Test Result

Thymeleaf = how to th:each adding value in tag input

so I want to make input income/outcome increase according to the income/outcome data that has been obtained from the controller
I have tried using th:each as follows to add income/outcome from each transaction
this is my form
<form class="form-horizontal" th:action="#{/report/create}" method="post">
<div th:each="transactions : ${transaction}">
<input type="hidden" name="income" th:value="${report.income + transactions.income}">
<input type="hidden" name="outcome" th:value="${report.outcome + transaction.outcome}">
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>
with that I only got the first income/outcome from the loop
Not sure how you implemented the backend, but your spelling for transactions isn't correct. Other than that, it should work as I've done something similar myself in the past. Typically you would have
#GetMapping("/my-page")
public String showAll(Model model) {
//....
model.addAttribute("report", report);
// however you define (a list) of transactions
model.addAttribute("transactions", transactions);
return "my-page";
}
then in your html
<div th:each="transaction : ${transactions}">
<input type="hidden" name="income" th:value="${report.income + transaction.income}">
<input type="hidden" name="outcome" th:value="${report.outcome + transaction.outcome}">

Send form in JSON using Thymeleaf and Spring boot

I'm using a form using Thymeleaf to send data to my Service.
Here is my Form:
<form th:object="${individualEntity}" th:action="#{/save}" method="post">
<div class="form-group">
<label>FirstName:</label>
<input type="text" class="form-control" th:field="*{individualName.givenName}"/>
</div>
<div class="form-group">
<label>LastName:</label>
<input type="text" class="form-control" th:field="*{individualName.surname}"/>
</div>
<div class="form-group">
<label>Address:</label>
<input type="text" th:field="*{address}"/>
</div>
<div class="row">
<button type="submit">Submit</button>
</div>
When I debug the request sent using this form it gives me this data : individualName.givenName=xxxx&individualName.surname=xxxxx&address=xxxx
However I want that it will be in JSON when sending because my microservice consumes JSON.
What should I do to correct that !
Here is my service:
#PostMapping(value = "save")
public String saveIndividual(Individual individual){
individualService.saveIndividual(individual);
return "redirect:/getIndividual/" + individual.getId();
}
Thanks

Creating an update page in Spring using Thymeleaf

I'm trying to create an update page for my spring project, When I try to open my edit page using localhost:8080/edit/1 I get
There was an unexpected error (type=Internal Server Error, status=500).
Could not parse as expression: "/edit/{stockNumber}" (editItem:78)
What can I do to solve this issue?
#GetMapping(path="edit/{stockNumber}")
public String editItemForm(#PathVariable Long stockNumber, Model model){
model.addAttribute("item",itemRepository.findOne(stockNumber));
return "editItem";
}
#PostMapping(path="edit/{stockNumber}")
public String editItem(#ModelAttribute Item item){
itemRepository.save(item);
return "redirect:/item";
}
<form action="#" th:object="${item}" th:action="/edit/{stockNumber}" method="post">
<div class="form-group">
<label for="txtItemDesc">Item Description</label>
<input type="text" th:field="*{itemDesc}" class="form-control" id="txtItemDesc" placeholder="item Description" />
</div>
<div class="form-group">
<label for="txtUnit">Unit</label>
<input type="text" th:field="*{unit}" class="form-control" id="txtUnit" placeholder="Unit" />
</div>
<div class="form-group">
<label for="txtAbc">ABC</label>
<input type="text" th:field="*{abc}" class="form-control" id="txtAbc" placeholder="ABC" />
</div>
<button type="submit" value="Submit" class="btn btn-default">Submit</button>
</form>
Your expression in th:action is incorrect. It should be
th:action="'/edit/'+ ${stockNumber}"

Cannot submit a form on SpringMVC

I am fairly new to SpringMVC and have a form that can not submit to the back-end. I created the form as following and when I submit it error 404 will be returned. I changed action to /MyProject/contact but did not work.
<form class="form-horizontal" role="form" method="post"
action="/contact">
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Name
</label> <input type="text" class="form-control" id="name"
name="name" placeholder="Your name" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Email
Address</label> <input type="email" class="form-control" id="email"
name="email" placeholder="Your email" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Phone
Number</label> <input type="number" class="form-control" id="phone"
name="phone" placeholder="Phone number" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Enquiry</label>
<textarea class="form-control" rows="4" name="message"
placeholder="Please enter your enquiry"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-2 " style="float: right;">
<input id="submit" name="submit" type="submit" value="Send"
class="btn btn-primary">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<! Will be used to display an alert to the user>
</div>
</div>
</form>
Controller
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
Error
HTTP Status 404 - /contact
type Status report
message /contact
description The requested resource is not available.
Its beacuse spring does not know how to pass the param Contact contact to your controller method. You need to do couple of things to make it work. Change your form to like below.
<form class="form-horizontal" role="form" method="post" modelAttribute="contact" action="/contact">
Your controller to take contact as model attribute.
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(#ModelAttribute Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
For a better understanding of what a model attribute does, there are plenty of samples and explanation online. Hope this helps.
I could solve the problem by help of minion's answer, following this tutorial and adding following link
#RequestMapping(value = "/contact", method = RequestMethod.GET)
public ModelAndView contactForm() {
System.err.println("here in GET");
return new ModelAndView("contact", "command", new Contact());
}

Resources