I'm trying to load values to a select (or likebobox) dynamically from the server side with Spring Boot. I am also validating this form with the help of Hibernate Validator.
I'm having a very annoying problem that I can't explain why it's happening. In my form I have two comboboxes (or select), the first one is setting the values, while the second one (the dynamic one) is not. I even tried to put everything manually, but the annoying problem persists.
<form:form id="form" modelAttribute="nuevoEvento" method="POST">
<div class="containerLeft">
<table>
<tbody>
<tr>
<td><Label>Nombre del evento</Label></td>
<td><form:input type="text" path="titulo" /></td>
</tr>
<tr><td colspan=2 style="text-align:center;color:#84FCFF;"><form:errors path="titulo"/></td></tr>
<tr>
<td><Label>Tipo de Evento</Label></td>
<td><form:select class="combobox" path="tipoEvento">
<form:option value="N/A">Seleccione el tipo</form:option>
<form:option value="Importante">Importante</form:option>
<form:option value="Informativo">Informativo</form:option>
<form:option value="Privado">Privado</form:option>
</form:select></td>
</tr>
<tr><td colspan=2 style="text-align:center;color:#84FCFF;"><form:errors path="tipoEvento"/></td></tr>
<tr>
<td><Label>Salon del evento</Label></td>
<td>
<form:select class="combobox" path="salonId">
<form:options items="${listaSalones}"></form:options>
</form:select>
</td>
</tr>
<tr><td colspan=2 style="text-align:center;color:#84FCFF;"><form:errors path="salonId"/></td></tr>
<tr>
<td><Label>Dia del evento</Label></td>
<td><form:input type="text" path="fechaEvento" id="txtfecha" readonly="readonly"/></td>
</tr>
<tr><td colspan=2 style="text-align:center;color:#84FCFF;"><form:errors path="fechaEvento"/></td></tr>
</tbody>
</table>
<input type="hidden" name="usuario" value="${principal.name}" />
The model class of this form is the following:
@TimeRangeConstraints.List({
@TimeRangeConstraints(
fechaEvento="fechaEvento",
horaInicio="horaInicio",
horaCulminacion="horaCulminacion"
)
})
public class NuevoEvento {
@NotEmpty(message="Como se llamara el evento?")
@Size(max=40, message="Titulo invalido")
private String titulo;
@StringComboBoxConstraints
private String tipoEvento;
private String salonId;
private String url;
@NotEmpty(message="Seleccione la fecha del evento")
private String fechaEvento;
@NotEmpty(message="A que hora inicia el evento?")
private String horaInicio;
@NotEmpty(message="A que hora termina el evento?")
private String horaCulminacion;
public NuevoEvento() {}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getTipoEvento() {
return tipoEvento;
}
public void setTipoEvento(String tipoEvento) {
this.tipoEvento = tipoEvento;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getFechaEvento() {
return fechaEvento;
}
public void setFechaEvento(String fechaEvento) {
this.fechaEvento = fechaEvento;
}
public String getHoraInicio() {
return horaInicio;
}
public void setHoraInicio(String horaInicio) {
this.horaInicio = horaInicio;
}
public String getHoraCulminacion() {
return horaCulminacion;
}
public void setHoraCulminacion(String horaCulminacion) {
this.horaCulminacion = horaCulminacion;
}
public String getSalonId() {
return salonId;
}
public void setSalon(String salon) {
this.salonId = salon;
}
}
The attribute that is bothering is salonId... now, how am I loading those elements? Here they are, from the controller:
@Controller
@RequestMapping("/usuarios")
public class UserController {
@Autowired
SalonRepository salon;
@Autowired
UsuarioSalonRepository userSalon;
@GetMapping("/home")
public String goHome(Model model, Principal principal) {
System.out.println(principal.getName() + " HA INICIADO SESION!!!");
User logueado = (User)((Authentication)principal).getPrincipal();
String userInfo = WebUtils.toString(logueado);
model.addAttribute("userInfo",userInfo);
model.addAttribute("principal",principal);
return "/basics/home";
}
@GetMapping("/crearEvento")
public String irCrear(Model model, Principal principal) {
model.addAttribute("nuevoEvento",new NuevoEvento());
model.addAttribute("principal",principal);
model.addAttribute("listaSalones",getSalones());
return "/Usuarios/crearEvento";
}
@PostMapping("/crearEvento")
public String crearEvento(@Valid NuevoEvento nuevoEvento, BindingResult result,
Model model, Principal principal) {
System.out.println("CONTROLSITO: " + nuevoEvento.getSalonId());
System.out.println("Nombre: " + nuevoEvento.getTitulo());
System.out.println("Tipo: " + nuevoEvento.getTipoEvento());
System.out.println("Id Salon: " + nuevoEvento.getSalonId());
System.out.println("Dia: " + nuevoEvento.getFechaEvento());
System.out.println("Hora Inicio: " + nuevoEvento.getHoraInicio());
System.out.println("Hora Fin: " + nuevoEvento.getHoraCulminacion());
System.out.println("URL: " + nuevoEvento.getUrl());
if(result.hasErrors()) {
model.addAttribute("principal",principal);
return "/Usuarios/crearEvento";
}else
return "index";
}
@RequestMapping("/misEventos")
public String misEventos(Model model, Principal principal) {
return "/Usuarios/misEventos";
}
@RequestMapping("/editarEvento")
public String irEditar(Model model, Principal principal) {
return "/Usuarios/editarEvento";
}
@RequestMapping("/borrarEvento")
public String irBorrar(Model model, Principal principal) {
return "/Usuarios/borrarEvento";
}
public Map<Integer,String> getSalones(){
Map<Integer,String> salones = new LinkedHashMap<Integer,String>();
Iterable<Salon> ls = salon.findAll();
salones.put(0, "Seleccione un salon");
int i = 1;
for(Salon salon: ls) {
salones.put(i, salon.getNombre());
i++;
}
return salones;
}
}
If I submit, you can view the data that you enter, but not that of that "salonId" select...
It must be a silly mistake, but believe me I can't see where this is wrong
In your bean you have
Which means that, at the bean level, what you have is a property
salonId
that is readonly (it has no setter ). The is methodsetSalon
is ignored, since the getter is always used to identify the properties.What I don't understand is that I would expect this to give you a warning in the log that the property
salonId
is readonly .