Form binding back with List of multiple select options - java

I'am trying to bind model in spring form multiple select using Select2 jquery library
but selected options are always null,
first i display form correctly with the available options, then user can update (add or remove) other choice which i fetch them remotely with an ajax request.
i am using next dto to bind form data :
DTO :
#Setter
#Getter
public class MyDto{
private List<Contact> agences;
private Contact banque;
spring mvc form to display avaliable user option :
...
<form:select path="agences" items="${MyDto.agences}" itemValue="id" itemLabel="name" />
...
select2 initialization to format and fetch additional options with an ajax request
Select 2 :
$("#agences").select2({
language: "fr",
multiple: true,
width: '100%',
ajax: {
url: "/fetchData.html",
method: "POST",
dataType: 'json',
delay: 250,
data: function (params) {
return {
query: params.term,
banque : $("#IdBanque").val()
};
},
processResults: function (data, params) {
return {
results: $.map(data, function (item) {
return {
"id" : item.id,
"text" : item.name,
}
})
};
}
}
});
Controllor
#RequestMapping(method = RequestMethod.POST, value = "/update")
#ResponseBody
public ResponseEntity<?> updateIntranet(#ModelAttribute(value = "myDto") myDto, BindingResult result, HttpServletRequest zRequest) throws JSONException {
....
the problem is when i receive the request i can't find selected options and the List is null
how i can binding back the dto which include list of element using spring mvc

Related

Spring MVC #ModelAttribute is not getting populated with AJAX Post request [duplicate]

I'm trying to make a form that will post a CardRequestResource:
public class CardRequestResource extends ResourceSupport{
private Long cardRequestId;
private String deliveryMethod;
private String address;
private boolean isHomeDelivery;
private String requestDate;
private String expectedDate;
private String comments;
private Long statusId;
private PersonResource person;
//Getters and Setters
}
In my controller, I first load the JSP and add an empty CardRequestResource to the ModelMap:
#RequestMapping(value = { "", "/approval" }, method = RequestMethod.GET)
public String getApproval(ModelMap map) {
map.put("cardRequestResource", new CardRequestResource());
return "cardoffice/approval";
}
My JSP builds the form with the cardRequestResource model attribute:
<form:form id="detailForm" name="detailForm" modelAttribute="cardRequestResource">
<form:input path="statusId" type="hidden" id="statusId" name="statusId" />
<form:textarea path="comments" name="comments" id="commentTextarea" rows="7" cols="81" style="font-style: normal;"/>
</form:form>
A Javascript function makes an AJAX call to populate the form values:
function getCardRequestDetails(cardRequestUrl) {
$.ajax({
type : "GET",
url : cardRequestUrl,
dataType : "json",
success : function(response) {
loadCardRequestDetails(response);
},
error : function(response) {}
});
};
function loadCardRequestDetails(cardRequest) {
$("#statusId").attr("value", cardRequest.statusId);
$("#commentTextarea").val(cardRequest.comments);
}
At this point a user may update the comment text area, and the hidden input may change conditionally on what the user enters in the field. Then when the form is submitted, I call the following Javascript function:
function postCardRequest(url) {
var serialized = $("#detailForm").serialize();
alert(serialized);
$.ajax({
type: "POST",
url: url,
data: serialized,
contentType: "application/json",
dataType: "json"
});
}
The alert shows that the fields are populated correctly with the data that was either originally loaded by AJAX/Javascript, or by the user. However when I get to the handler in my controller that processes the post, the CardRequestResource is non-null, but EVERY SINGLE field in it is NULL!
Handler code:
#RequestMapping(value = "/approval/submit", method = RequestMethod.POST)
public #ResponseBody Map<String, Object> postCardRequest(#ModelAttribute(value = "cardRequestResource") CardRequestResource cardRequestResource) {
Map<String, Object> responseMap = new HashMap<String, Object>();
final String success = "success";
Boolean isSuccessful = Boolean.FALSE;
if(cardRequestResource != null){
isSuccessful = Boolean.TRUE;
}
//TODO
System.out.println("Status: " + cardRequestResource.getStatusId() + ", Comments: " + cardRequestResource.getComments());
responseMap.put(success, isSuccessful);
return responseMap;
}
So I think I found the perp!
This lil' guy right here in the POST AJAX call:
contentType: "application/json",
I was originally sending JSON to my controller, then I learned that Spring MVC had that nifty ModelAttribute annotation, so I wouldn't have to worry about converting to/from JSON during my POST. Unfortunately, I didn't think to remove that contentType line, and one would think that it would throw an error or something with it still in there... apparently not. Just NULL values in the binding and hours of fruitless debugging...
After I removed that line, I started getting data in the CardRequest attributes instead of NULLs!
Try to put the following code in the aplication-context.xml. This could be the solution if you are having your form encType='multipart/form-data'.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000"/>
</bean>

How display Java Object by ajax calls

I have Spring 4 MVC web app, I would like to do a GET call with Ajax that returns a list of simple object. Suppose that the object is something like this:
class Categories {
String name;
}
and calls is like this:
function getCategories() {
$.ajax({
type: "GET",
url: "categoryFilter.html",
dataType: "json",
success: function (result) {
alert(result);
},
error: function (result) {
alert("error");
}
});
}
Than I would like to display this object inside a Spring form like this:
<form:form method="post" action="searchShop.html" modelAttribute="Categories">
<c:forEach var="cat" items="${result}">
<span><form:input path="nome" value="${cat.name}" /></span>
</c:forEach>
</form:form>
I googling around and I see that I can append the result into a div or something similar but I can do something like that?
Thanks for your reply. My controller is:
#RequestMapping("/categoryFilter")
public Response showCategory() {
List<Categoria> categoryList = categoryService.getAllCategories();
Response response = new Response("Done", categoryList);
return response;
}
and the Object response:
public class Response {
private String status;
private Object data;
....
}
I have tried many different ways, with #GetMapping and so on.. but I always received 404 bad request.
Thanks a lot
Yes yes my question was how convert the pojo automatically with jackson library but after Spring 3 I needs a lot of bean configuration and than I modify my controller as follows:
#ResponseBody
#RequestMapping("/categoryFilter")
public String showCategory() {
List<Categoria> catList = categoryService.getAllCategories();
JSONArray json = new JSONArray(catList);
return json.toString();
}
Your code:
var resObjs= JSON.stringify(result);
var cats= JSON.parse(resObjs);
$("#category-form").append('<form:form method="post" action="searchShop.html" modelAttribute="Categoria">');
$.each(JSON.parse(cats), function(i, obj) {
$("#category-form").append('<form:input path="nome" value="'+obj.nome+'" />' + obj.nome); // this line
});
$("#category-form").append('<input type="submit" value="Submit"/>');
$("#category-form").append('</form:form>');
Please take a look to the line inside the $.each, that line visualiza an input type with value the string +obj.name+ follows by the effective value of variable (the name of category).. why I can't put dinamically value right there?? I'm going mad..
Thank you
yes you can append the json values to a div, this is what i did for populating selection dropdown with json data, something similar can be done for forms as well.
success: function (responseJson) {
var responseObjects= JSON.stringify(responseJson);
var categories= JSON.parse(responseObjects);
$('#divid').empty();
$('#divid').append($('<option value="0">').text("Select Variant"));
$.each(categories, function(i, obj) { $("#divid").append(('<option>
</option>').val(obj.id).html(obj.value));});
}

get Data from DB using Spring MVC to show in dropdown list like Country, state, city

I have 3 Drop Down list which are dependent on each other as Specific country contain Certain States and those states contain specific City,
all These Country, state and City have a Service call to DAO to get data from DB how i can manage Drop Down with the Help of Spring MVC to display proper Country and state and city in Drop down List of each
Create a REST Call to produce JSON Country object has a list of State Objects
#RequestMapping(value= "/countryState", produces = MediaType.APPLICATION_JSON_VALUE)
public List< CountryStateCity> retrieveCountryState() {
return ddlService.retrieveCountryState();
}
Create another Rest call to get the City base on Country and State
#RequestMapping(value= "/city", produces = MediaType.APPLICATION_JSON_VALUE)
public List< CountryStateCity> retrieveCity(String country,String state) {
return ddlService.retrievecity(country,state);
}
I used AJAX/jquery in this example To
//Fill first Dropdown
$.ajax({
type: "GET",
url: "http://192.168.33.60:8080/countryStateCity?callback=?",
dataType: "jsonp",
jsonpCallback: 'jsonCallback',
cache:false,
success: function(data) {
var dataToStore = JSON.stringify(data);
localStorage.setItem('jsonResults', dataToStore);//Store json to browser local storage
$("#country").get(0).options.length = 0;
$("#country").get(0).options[0] = new Option("Select Country", "0");
$.each(data, function(index, item) {
$("#country").get(0).options[$("#country").get(0).options.length] = new Option(item.mfrname, item.countryId);
});
},
error: function(e) {
// alert("Error Loading Manufactures");
}
});
$("#country").on("change", function (event) { //Change event on country Drop down clear State and City Dropdowns
var countryId=$("#country").val();
var stateId=$("#state").val();
$('#City').find('option').remove().end(); //clear City dropdown and add only select
$("#City").get(0).options[0] = new Option("--Select--", "0");
$('#state').find('option').remove().end();
$('#category').find('option').remove().end();
resetTables();
var localData = JSON.parse(localStorage.getItem('jsonResults'));// Go to local storage and get state values
var i = null;
for (i = 0; localData.length > i; i += 1) {
if (localData[i].countryId === countryId) {
$.each(localData[i].states, function(index, value) {
$("#state").get(0).options[$("#state").get(0).options.length] = new Option(value.description, value.code);
});
}
}
});
$("#state").on("change", function (event) {//State change event clear city then go to
var countryId=$("#country").val();
var stateId=$("#state").val();
// alert(countryId!="0"&&stateId!="0");
$('#City').find('option').remove().end();
$("#City").get(0).options[0] = new Option("--Select--", "0");
$('#category').find('option').remove().end();
resetTables();
if(countryId!="0"&&stateId!="0"){
//now call the citys Rest call
$.ajax({
type: "GET",
url: "http://192.168.33.60:8080/cities?countryId="+countryId+"&stateId="+stateId+"&callback=?",
dataType: "jsonp",
jsonpCallback: 'jsonCallback',
cache:false,
success: function(data) {
jsonResults=data;
$.each(data, function(index, item) {
$("#City").get(0).options[$("#City").get(0).options.length] = new Option(item.description, item.code);
});
},
error: function(e) {
// alert("Error Loading cities");
}
});
} else{
$("#City").get(0).options[0] = new Option("--Select--"+countryId, "0");
}
I made this from existing code and have not tried it but you should get the gist
At first, you should get familiar with MVC concept.
The data you get from service by controller will act as the M. And the data will be passed to the view(V). Then you can use the data and creat a V. Normally, the View is created by using HTML and JSP. In your case, you can use JSP or any other template frameworks to creat three dropdown lists using the data.

Fill in Bootstrap table after Ajax request (JSP and Spring MVC)

Hi I try to fill in my tables in my JSP view after having send a variable into an Ajax function.
<script type="text/javascript">
function filterByDate() {
var count = 680;
$.ajax({
url : 'filterOnDate',
data : {
"count" : count
}, //here you send the daterange over an Ajax request and by default it's sended with a GET method
success : function(data) {
//alert(data); //here you will see an alert displaying the callback result coming from your spring controller
console.log("Request succeeded!");
console.log(data);
},
error : function(xhr, ajaxOptions, thrownError) {
if (xhr.status == 404) {
alert(thrownError);
}
}
});
}
</script>
This Ajax request is send to a UserController who receive this variable and send it to the Model for performing an Hibernate search criteria in database.
#RequestMapping(value = "/eblinb2b/filterOnDate", method = RequestMethod.GET)
public #ResponseBody List<EblInvB2B> filterByDate(Model model, #RequestParam("count") int count) {
// Fetch data from the DAO
List<EblInvB2B> eblinb2b_filter_counting = accountSservice.findByDateRangeEB2B(count);
// We add to the model (JSP page the list of EBLINVB2B)
model.addAttribute("eblinb2b_filter_counting", eblinb2b_filter_counting);
return eblinb2b_filter_counting;
}
I already checked if the hibernate query retrieve the information from the COLUMN table after I put a Debug breakpoint i see my List with objects.
This is the DAO method with Hibernate criteria:
#SuppressWarnings("unchecked")
#Override
public List<EblInvB2B> findDateRange(int count) {
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("count", count));
return (List<EblInvB2B>) criteria.list();
}
What i'd like to do is to fill my table with a response to my Ajax only with the rows where i applied the criteria which is count that comes from my Ajax request it is equal to 680 it is an integer and should fill in my jsp table with only one row.
Just for information: I have a Different JSP view where I have and Update Button for populating mySql database it is in fact a batch that unmarshall XML files and put them into database. This is the usercontroller method :
#RequestMapping(value = "/eblinb2b/OutInCompare", method = RequestMethod.GET)
public String eblinb2bOutInCompare(Model model) {
// Fetch data from the DAO
List<EblInvB2B> eblinb2b_list = accountSservice.findAllEblInvB2B();
// We add to the model (JSP page the list of EBLINVB2B)
model.addAttribute("eblinb2b_list", eblinb2b_list);
return "eblinb2bCompare";
}
Here i want to display in my view the list passed by my Controller method onto my JSP view. I don't know if it is correct? : BOOTSTRAP PAGE
https://jsfiddle.net/eaL38ejr/
Thanks to all for your help!
You should've load the bootstrap table again after getting data from ajax.
<script type="text/javascript">
function filterByDate() {
var count = 680;
$.ajax({
url : 'filterOnDate',
type: 'GET',
dataType:'json',
data : {
"count" : count
}, //here you send the daterange over an Ajax request and by default it's sended with a GET method
success : function(data) {
//alert(data); //here you will see an alert displaying the callback result coming from your spring controller
console.log("Request succeeded!");
console.log(data);
$('#tableID').bootstrapTable('load', data);
},
error : function(xhr, ajaxOptions, thrownError) {
if (xhr.status == 404) {
alert(thrownError);
}
}
});
}
</script>
Or do a refresh,
$('#tableID').bootstrapTable('refresh', {
url: 'filterOnDate?count='+count
});
Edit
Ajax 406 indicates your request is not acceptable, hence you need to update your controller method like below.
#RequestMapping(value = "/eblinb2b/OutInCompare", method = RequestMethod.GET,
headers="Accept=*/*",produces = "application/json")
public #ResponseBody List<EblInvB2B> filterByDate(Model model, #RequestParam("count") int count) {
// Fetch data from the DAO
List<EblInvB2B> eblinb2b_filter_counting = accountSservice.findByDateRangeEB2B(count);
// We add to the model (JSP page the list of EBLINVB2B)
model.addAttribute("eblinb2b_filter_counting", eblinb2b_filter_counting);
return eblinb2b_filter_counting;
}
As well include type and dataType parameter's in your ajax request. Let me know if it helps.

How to manipulate jQuery AJAX JSON data in a controller in spring MVC

How many ways are to pass JSON data to a spring controller?
I followed this tutorial and they pass the data using the following syntax:
data: "{\"name\":\"hmkcode\",\"id\":2}",
This works but since I need to retrieve the data from a user using a text input I don't know how to put my variable in that string.
I tried doing using the following syntax:
data: "{\"name\":\name\}"
But it returns the following error:
status: parsererror er:SyntaxError: Unexpected tokken a
I have seen other sites that uses the following syntax:
data: {"name":name}
But that gives me the same error.
This works but I don't know if is the best approach.
var json = {"name" : name};
...
data: JSON.stringify(json),
I manage to pass the JSON string to one of my controllers but I get the string like this:
{"name": Joe, "lastname": Smith}
Is there a way to only get that info in a Person Object or at least get only Joe in a string and Smith in another one?
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript">
function doAjaxPost()
{
// get the form values
var name = $('#name').val();
var lastname = $('#lastname').val();
var json = {"name" : name, "lastname" : lastname};
//console.log(json);
$.ajax(
{
type: "POST",
url: "formShow",
data: JSON.stringify(json),
//data: "{\"name\":name}",
//data: {"name":name},
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
beforeSend: function(xhr)
{
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
},
success: function(data)
{
//console.log(data);
console.log(data.name);
//var data = $.parseJSON(JSON.stringify(response));
//alert(data);
alert( "name: "+data.name);
//$('#name').val('');
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
/* error: function (xhr, ajaxOptions, thrownError)
{
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
}*/
});
}
</script>
<fieldset>
<legend>Name in view</legend>
Name in view: <input type="text" id="name" name="name">
<br>
Last Name in view: <input type="text" id="lastname" name="lastname">
<br>
Show modify name in view: <input type="text" id="modifyname" name=""modifyname"">
<br>
<input type="button" value="Add Users" onclick="doAjaxPost()">
</fieldset>
<br>
And these are my controllers:
#RequestMapping(value = "formShow", method = RequestMethod.GET)
public String formularioIncidencia (Model model) {
return "formShow";
}
#RequestMapping(value = "formShow", method = RequestMethod.POST)
public #ResponseBody String getTags(#RequestBody String name)
{
String variableAjax= name;
System.out.println("controller variable is " + variableAjax);
//that prints me this "{name: Joe, lastname: Smith}"
return variableAjax;
}
EDITED****
this is my User class
public class Userimplements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String lastname;
public User(){}
}
I edited my controllers to the following
#RequestMapping(value = "formShow", method = RequestMethod.GET)
public String formShow(Model model) {
return "formShow";
}
#RequestMapping(value = "formShow", method = RequestMethod.POST)
public #ResponseBody User getTags(#RequestBody final User user, Model model)
{
//what should i do here parse my user to JSON how??
user.setName("name changed");
model.("modifyname", user.getName() );
return User;
}
From Ajax you can also pass data as data:'name='+ name+'&lastname='+ lastname,
And at controller end you can make use of #RequestParam annotation to get this value passed from ajax call.
Ajax code looks as follows:
$.ajax({
type: 'POST',
url:'your controller url',
data:'name='+ name+'&lastname='+ lastname,
success: function(msg){
alert('wow' + msg);
}
});
Controller code:
#RequestMapping(value = "formShow", method = RequestMethod.POST)
public String getTags(#RequestParam("name") String name, RequestParam("lastname") String lastname)
{
System.out.println("name: " + name+ " lastname: "+lastname);
String fullName = name + lastname;
return fullName;
}
Hope this helped you.
Cheers:)
For sending the input data to controller, you don't have to necessarily use json as a format. You can simply pass them as request param and extract it on controller using #RequestParam annotation. If you want to post json data you can use JSON.stringify(json). if you to bind object to your model object, try using #Modelattribute on controller and pass the data in your ajax post. There are plenty of examples for this.
Use #RequestParam or #RequestBody to get your data on your controller based on what approach you choose based on point 1.
Use #ResponseBody to send the data back and if you send json data back, use Json.parseJson to convert to js object or if you send a Map, you would get a JS object back in your ajax handler. You can use Dot notation to populate the data.
A few observations will be enlighten ( i hope ).
In JAVA: it is always better to specify your "request" object and your response object like this:
#RequestMapping(method = RequestMethod.POST, value = "/rest/path/to/action",
consumes = "application/json", produces = "application/json")
#ResponseStatus(value = HttpStatus.OK)
public #ResponseBody
List<?> action(#RequestBody List<?> requestParam) {
List<String> myret = new ArrayList<String>();
for (int i=0; i < requestParam.size() ;i++){
myret.add(requestParam.get(i).toString());
}
}
In this case i defined the same object "List" as my request and my response object, but that it's up to your definitions. If you want to represent a user object, you must define your user object and specify the fields u want with Jackson lib. It is a little tricky, but once you got it, you can pass any object you want.
And then you can just pass your data in AJAX as defined in your controller. So in this case would be:
var postData = ["Somedata", "Someotherdata"];
$.ajax(
{
type: "POST",
url: "/rest/path/to/action",
data: postData, // i can do this, because it is defined this way in my controller
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
//etc etc
I hope it helps :)
Cheers

Categories

Resources