I'm doing a java web application using jsp and servlets.
I have a form and I retrieve different values from my db to populate an option. This is my form:
<form class="form" action ="<%=request.getContextPath()%>/aggiungiLibro" method ="post">
<div class="form__group">
<input type="text" placeholder="Titolo" class="form__input" name = "titolo"/>
</div>
<div class="form__group">
<input type="text" placeholder="Quantità disponibile" class="form__input" name="quantita" />
</div>
<div class="form__group">
<select class="form__input" name="autore">
<c:forEach items="${listaAutori}" var = "autore" >
<option value="${autore.idAutore}"><c:out value="${autore.nome} ${autore.cognome}" /></option>
</c:forEach>
</select>
</div>
<button class="btn btn-light" type="submit">Inserisci nuovo libro</button>
</form>
In the servlet I retrive my data with
String titolo = request.getParameter("titolo");
int quantita = Integer.parseInt(request.getParameter("quantita"));
int autore = Integer.parseInt(request.getParameter("autore"));
I get right values for 'titolo' and 'quantita' but I get the string '${autore.nome}' for 'autore'.
It seems like it doesn't replace the string with the actual value.
The field idAutore is spelt right.
(In the jsp page I see the correct values for ${autore.nome} ${autore.cognome})
Anyone can help me please? What I'm doing wrong?
I solved replacing this:
<option value="${autore.idAutore}">
with this:
<option value="<c:out value='${autore.idAutore}' />">
Related
I'm getting trouble trying to update my Object in the back-end via a front-end template.
This is my template, it uses ThymeLeaf
<form id="formUpdate" method="put">
<div class="row">
<div class="col s12">
<h2> Modificar Gustos</h2>
</div>
</div>
<div class="divider"></div>
<div class="row">
<label for="selectGusto">Nombre del gusto a cambiar</label>
<select name="gustos" id="selectGusto">
<option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
<option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
</select>
</div>
<label for="newName">Nuevo Nombre</label>
<input type="text" name="newName" id="newName" />
<div class="row">
<label for="selectCat">Elegir nueva Categoria</label>
<select name="newCat" id="selectCat">
<option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
<option value="Dulces de Leche">Dulce de Leche</option>
<option value="Cremas">Cremas</option>
<option value="Chocolates">Chocolates</option>
<option value="Frutales">Frutales</option>
</select>
</div>
<button type="submit" id="btn-submit" class="button">Modificar</button>
</form>
This is my JS linked to the template:
var newCatId;
var idGusto;
var newName;
$('#selectCat').on('change', () => {
var value = $('#selectCat').val();
if(value === "Dulces de Leche") {
newCatId = 1;
}
else if(value === "Cremas") {
newCatId = 2;
}
else if(value === "Chocolates") {
newCatId = 3;
}
if(value === "Frutales") {
newCatId = 4;
}
console.log('newCatId: ' + newCatId);
console.log('idGusto ' + idGusto);
console.log('newName: ' + newName);
});
$('#selectGusto').on('change', function() {
idGusto = $(this).val();
});
newName = $('#newName').val();
$('#btn-submit').on('submit', (e) => {
e.preventDefault();
var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
$('#formUpdate').attr('action', url);
});
And this is the Spring controller that should handle the request:
#RequestMapping(value = "/gustos/{id}/edit/{newName}/{newIdCat}")
public String updateGustoById(#PathVariable("id") int id, #PathVariable("newIdCat") int newIdCat, #PathVariable("newName") String newName){
Gusto gusto = gustoService.findGustoById(id);
gusto.setNombre(newName);
gusto.setIdCategoria(newIdCat);
gustoService.update(gusto);
return "redirect:/gustos/edit";
}
Ok !! This code doesn't breaks anywhere but when I click on the submit button the variables in the JS travel in the URL as a Query String, that's not what I want to.
Example of my URL after clicking the form's submit button:
http://localhost:8080/gustos/edit?gustos=106&newName=Dulce+de+Leche+Granizado&newCat=Dulces+de+Leche
This is my first time making a Spring App!
My question is, how can I send the information to the controller in the right way? How do people normally update an Object if is not like this? :(
EDIT: The expected values are OK, that means the JS is working OK. The problem is sending the values to the back-end !! The form is sending them as a Query String and that's not what I need, neither the assigned values on the Query String are fine
In Your Scenario, Your trying to form path param URL
1.Instead of path params you can directly specify the action attribute in form element
<form id="formUpdate" method="GET" action="http://localhost:8080/gustos/edit">
method attribute can be GET or POST according to your need.
And newCat Select box like
<select name="newCat" id="selectCat">
<option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
<option value="1">Dulce de Leche</option>
<option value="2">Cremas</option>
<option value="3">Chocolates</option>
<option value="4">Frutales</option>
</select>
In Backend you can use #RequestParam to get paramter values
#RequestMapping(value = "/gustos/edit")
public String updateGustoById(#RequestParam(value="gustos") int id, #RequestParam(value="newCat")
int newIdCat, #RequestParam(value="newName") String newName)
{
Gusto gusto = gustoService.findGustoById(id);
gusto.setNombre(newName);
gusto.setIdCategoria(newIdCat);
gustoService.update(gusto);
return "redirect:/gustos/edit";
}
2.Another approach, Construct a JSON string with form field values (like you did for path params), While Submitting the form send this JSON string to back end through ajax call.
On your service layer keep this JSON String as Java beans (Spring Boot bind JSON values with the bean fields through #RequestBody annotation, if bean structure matched with the JSON).
I would recommend using th:object in your form. This creates an object of a given type instantly when you submit your form. So, let's say your object is of type Gusto. If you want to create a new entity from scratch, you could add this method in your controller that will return a new entity of type Gusto.
New Model Attribute
// In order to use th:object in a form, we must be able to map a new entity to that form.
// In this case we return a Gusto entity.
#ModelAttribute(value = "newGusto")
public Gusto newGusto() {return new Gusto();}
Form
So now, you can use this entity in a form using th:object="${newGusto}". This will create a new entity for you, which you might mapped fields to it.
In order to do so you would need to add following one elements to your form.
<form action="/gustos/edit/" id="formUpdate" method="put" th:object="${newGusto}">
<div class="row">
<div class="col s12">
<h2> Modificar Gustos</h2>
</div>
</div>
<div class="divider"></div>
<div class="row">
<label for="selectGusto">Nombre del gusto a cambiar</label>
<select th:field="*{id}" name="gustos" id="selectGusto">
<option value="-1" selected="selected" disabled="disabled">Lista de Gustos</option>
<option th:each="gusto : ${gustos}" th:text="${gusto.nombre}" th:value="${gusto.id}"> </option>
</select>
</div>
<label for="newName">Nuevo Nombre</label>
<input th:field=*{nombre} type="text" name="newName" id="newName" />
<div class="row">
<label for="selectCat">Elegir nueva Categoria</label>
<select th:field="*{categoria} name="newCat" id="selectCat">
<option value="-1" selected="selected" disabled="disabled">Nueva Categoria</option>
<option value="Dulces de Leche">Dulce de Leche</option>
<option value="Cremas">Cremas</option>
<option value="Chocolates">Chocolates</option>
<option value="Frutales">Frutales</option>
</select>
</div>
<button type="submit" id="btn-submit" class="button">Modificar</button>
</form>
The only difference you will find with your current code, is the added th:field elements in your selects and inputs and the th:object. Each one of these inputs and selects, will automatically mapped each field to the new entity you just created in your form.
Controller
Now for your controller you would need to change it for the following.
#RequestMapping(value = "/gustos/edit/")
public String updateGusto(#ModelAttribute("newGusto") Gusto gustoToUpdate){
Gusto gusto = gustoService.findGustoById(gustoToUpdate.getId());
gusto.setNombre(gustoToUpdate.getNombre());
gusto.setIdCategoria(gustoToUpdate.getCategoria());
gustoService.update(gusto);
return "redirect:/gustos/edit";
}
Of course, in your case, it is important that you change your jquery. We don't want to change the URL now. We just want to submit the form. So the following code, would have to be removed.
$('#btn-submit').on('submit', (e) => {
e.preventDefault();
var url = idGusto + " '/edit' + '/' "+ newName + '/' + newCatId;
$('#formUpdate').attr('action', url);
});
in GET method I'm adding these to the model:
model.addAttribute("team", team);
model.addAttribute("players", team.getPlayers());
model.addAttribute("inviting", new InvitingPlayerToTeam());
And a fragment of view with this model:
<div id="news" th:fragment="playerList">
<span>Nazwa: </span>
<span th:text="${team.name}">nazwa teamu</span>
<br>
<span th:each="player : ${players}" th:utext="${player.username} + '</br>'">-</span>
<br><br>
<form method="POST" th:action="#{/team/invitePlayer}" th:object="${inviting}">
Nazwa <input type="text" th:field="*{username}">
<input type="hidden" th:field="*{teamId}" th:value="${team.id}">
<br>
<input type="submit" value="Zaproś">
</form>
</div>
What is wrong? In post method field inviting.username has good value, but inviting.teamId is 0. Where is the problem?
Just remove th:value="${team.id}". You do not need to set this value again.
You should set up your form backing bean with the correct values in your controller.
inviting.setTeamId(...)
I have a dropdown which consist the language names. I am setting the value and displaying name of the dropdown by using a hashmap.
<form action="TextTranslation" method="post" class="form" role="form" >
<div class="row">
<div id = "imageView" class="col-lg-8 center-block ">
<div class="btn-group">
<select name="country">
<%
Map<String,String> langCode = x.getCountryList();
for( Object key :langCode.keySet() )
{%>
<option value="<%=(String)key%>"><%=langCode.get(key) %> </option>
<%
System.out.println((String)key);
}
String name = request.getParameter("country");
request.setAttribute("code", name);
%>
</select>
</div>
<input type="submit" class= "btn btn-image" value="Translate">
Search Text
</div>
</div>
</form>
Values are passed correctly to dropbox as it print all the values in console. the set attribute is accessed in the particular servlet. But it gives a null value. Do you have any idea?Thank you in advance
UPDATED
<select name="country">
<%
Map<String,String> langCode = x.getCountryList();
for( Object key :langCode.keySet() )
{%>
<option value="<%=(String)key%>"><%=langCode.get(key) %> /option>
<% System.out.println((String)key);
}
String name = request.getParameter("country");
%>
</select>
<input type="hidden" name="code" value = <%= name%>/> .
In the servlet I used,
request.getParameter("code");
update your jsp likewise,
<form...>
...
<input type="hidden" name="code" value = <%= name%>/>
....
</form>
then get it from your servlet likewise,
request.getParameter("code"); // will return value of code
NOTE :
Remove from your jsp-code if above solution you gonna implement then,
request.setAttribute("code", name);
I have this code in one jsp and i want to sent to the another and display selected value and correct answer. In the first page i have this code:
<form method="post" action="result.jsp" >
<p>choose answer</p>
<select name="fill">
<option value="0">Fill</option>
<option value="1">England</option>
<option value="2">China</option>
<option value="3">France</option>
</select>
<input type="submit" name="sent" />
</form>
and then the second jsp:
<body>
<jsp:declaration>
String s = "";
</jsp:declaration>
<jsp:scriptlet>
s = request.getParameter("fill");
</jsp:scriptlet>
<h1>Your answer is <jsp:expression>s </jsp:expression>and correct is England</h1>
</body>
And it returns null, why?
I have the following UI:
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-1 control-label"> <b><font size="4">Brand:</font></b>
</label>
<div class="col-sm-4">
<select class="form-control">
<option value="one">-</option>
<option value="two">BrandOne</option>
<option value="three">BrandTwo</option>
<option value="four">BrandThree</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label"> <b><font size="4">Price:</font></b>
</label>
<div class="col-sm-4">
<select class="form-control">
<option value="one">-</option>
<option value="two">1000 - 10000</option>
<option value="three">10000 - 50000</option>
<option value="four">50000 - 100000</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label"> <b><font size="4">Miles:</font></b>
</label>
<div class="col-sm-4">
<select class="form-control">
<option value="one">-</option>
<option value="two">0 - 1000</option>
<option value="three">1000 - 20000</option>
<option value="four">20000 - 100000</option>
</select>
</div>
</div>
</form>
<button type="button" id="searchBtn" class="btn btn-default">Search</button>
I want to do the following: After pressing the search-button, the choosen values of the three forms (Brand, Price, Miles) should be submitted. After some processing I want to return a List of Strings, iterating through the list and display the values in the result-list (see below).
I have two questions:
1. How can I submit the three choosen values?
2. How can I return the List, iterate through it and store the strings in the result-list?
<div class="well">
<ul class="list-group" id="resultList">
<!-- result should be here -->
</ul>
</div>
Thanks for any help!
All you POST params received can be obtained in the controller in this way:
Map<String,String[]> params = request().body().asFormUrlEncoded();
To debug what you actually receive I use such action:
public static Result outputPostParams(){
Map<String,String[]> params = request().body().asFormUrlEncoded();
StringBuilder sb = new StringBuilder();
for(String s: params.keySet()){
sb.append(s).append("\n");
for(String subs:params.get(s)){
sb.append("- ").append(subs).append("\n");
}
}
return ok(sb.toString());
}
In order to make it work don't forget to define a route in routes file:
POST /brands controllers.Application.outputPostParams()
And to add the route to form action:
<form method="POST" action="#routes.Application.outputPostParams()" class="form-horizontal" role="form">