PDA

View Full Version : Binding the value of a selected item from a drop down list


sherihan
Jan 23rd, 2005, 10:23 AM
Hi,
How could I bind the value of the selected item from a drop down list?

Would u plz, add the <spring:bind> for this example.
<select name="cutomerList">
<c:forEach var="customer" items="${customers}" >
<option value=${customer.id}>${customer.firstName}</option>
</c:forEach>
</select>

Thanks.
Sherihan

ATTA
Jan 23rd, 2005, 10:54 AM
Hi there,

I won't change your code, instead will show you mine :)


<spring:bind path="youFormBackingObject.state">
<select name="${status.expression}" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${states}" var="state">
<option value="${state.value}"${state.value == status.value ? ' selected' : ''}>${state.label}</option>
</c:forEach>
</select>
</spring:bind>


HTH,

ATTA

Hi,
How could I bind the value of the selected item from a drop down list?

Would u plz, add the <spring:bind> for this example.
<select name="cutomerList">
<c:forEach var="customer" items="${customers}" >
<option value=${customer.id}>${customer.firstName}</option>
</c:forEach>
</select>

Thanks.
Sherihan

sherihan
Jan 24th, 2005, 08:59 AM
Hi Atta,
Thanks for you help.
When I tried the code you sent I got the following error.

Failed to convert property value of type [java.lang.String] to required type [com._4s_.invoice.model.Customer] for property 'customer'

Note: customer is an Object of class Customer.

Thanks in Advance.

ATTA
Jan 24th, 2005, 10:04 AM
hello again,

can you please post the code? what is your formBackingObject?


<spring:bind path="yourFormBackingObject.customerId">
<select name="${status.expression}" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${states}" var="state">
<option value="${state.value}"${state.value == status.value ? ' selected' : ''}>${state.label}</option>
</c:forEach>
</select>
</spring:bind>


note that your bind path is "yourFormBackingObject.customerId"; you need the your object name and the property that you want to set for the selected customer from the dropdown.

HTH.

ATTA

Hi Atta,
Thanks for you help.
When I tried the code you sent I got the following error.

Failed to convert property value of type [java.lang.String] to required type [com._4s_.invoice.model.Customer] for property 'customer'

Note: customer is an Object of class Customer.

Thanks in Advance.

sherihan
Jan 24th, 2005, 10:18 AM
Hi Atta,
Here is the code of the form Controller:
package com._4s_.invoice.web.action;



import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.CustomDa teEditor;
import org.springframework.beans.propertyeditors.CustomNu mberEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBin der;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormCont roller;
import org.springframework.web.servlet.view.RedirectView;

import com._4s_.invoice.model.Invoice;
import com._4s_.invoice.service.CustomerManager;
import com._4s_.invoice.service.InvoiceManager;

/**
* @author smagied
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class AddInvoiceFormController extends SimpleFormController {
private static Log log = LogFactory.getLog(AddInvoiceFormController.class);

private InvoiceManager mgr = null;
private CustomerManager customerManager = null;

public void setInvoiceManager(InvoiceManager invoiceManager){
this.mgr = invoiceManager;
}

public InvoiceManager getInvoiceManager(){
return this.mgr;
}

public void setCustomerManager(CustomerManager customerManager){
this.customerManager = customerManager;
}

public CustomerManager getCustomerManager(){
return this.customerManager;
}

/**
* *Set up a custom property editor for converting Longs
*
*/
public void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder){
NumberFormat nf = NumberFormat.getNumberInstance();
binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(Long.class, nf,true));

binder.registerCustomEditor(Date.class,null, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}


public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response,
Object command, BindException errors)
throws Exception{
if (log.isDebugEnabled()){
log.debug("entering 'onSubmit' method....");
}

Invoice invoice = (Invoice) command;
mgr.saveInvoice(invoice);
/*request.getSession().setAttribute("message",
getMessageSourceAccessor().getMessage("invoice.saved",
new Object[] {invoice.getInvoiceNumber().toString() +
' ' + invoice.getCustomer() +
' ' + invoice.getDate()}));*/

return new ModelAndView(new RedirectView(getSuccessView()));
}

protected Object formBackingObject (HttpServletRequest request)
throws ServletException{
String invoiceId = request.getParameter("id");

if ((invoiceId != null) && !invoiceId.equals("")) {
Invoice invoice= mgr.getInvoice(new Long(request.getParameter("id")));
if (invoice == null) {
return new Invoice();
}
return invoice;
}else {
return new Invoice();
}
}

protected Map referenceData(HttpServletRequest request)
throws ServletException {
Map model = new HashMap();
model.put("customers", customerManager.getCustomers());
return model;
}
}

Thanks a lot.
Sherihan

klr8
Jan 24th, 2005, 12:53 PM
Take a look at the spring:transform tag, that allows you to do this kind of thing. Here is an example: http://www.springframework.org/docs/taglib/tag/TransformTag.html.

Erwin

sherihan
Jan 25th, 2005, 03:08 AM
Hi Atta,
Sorry for the disturbance but I still have a problem with binding objects.
I'll tell you the details of my problem. Hope u could help me.
I have two classes Invoice and Customer.
The Invoice class contains a property named customer of type Customer.
I have a form that adds a new invoice.
The user should select a customer for this invoice from a drop down list.
I added a method referenceData in the addInvoiceFormController in which I get the list of available customers .

I added the binding of this property in the jsp page:

<spring:bind path="invoice.customer">
<select name="${status.expression}" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${customers}" var="customer">
<option value="${customer.id}"${customer.id == status.value ? ' selected' : ''}>${customer.firstName}</option>
</c:forEach>
</select>
</spring:bind>

When I try submitting the form I get the following error message:
Failed to convert property value of type [java.lang.String] to required type [com._4s_.invoice.model.Customer] for property 'customer'

I don't know where is the mistake.
Is there something wrong in the JSP?
Should I create a property editor? If yes, would you plz tell me how.
Should I create a formBackingObject for the customer in the addInvoiceFormController?

Sorry for this long message.
Thanks a lot for your help.
Sherihan.

ATTA
Jan 25th, 2005, 08:09 AM
Well Sherihan, the dorpdown's selected value is a String. Of course, for request processor there is no way to convert a String into Customer. Hence the exception. Or at least that's what I think is going on. Now if you have an id attribute for customer, I'm sure this should work:

<spring:bind path="invoice.customer.id">

this will set the 'id' property of customer object in invoice object and is equivilant to calling:

invoice.getCustomer().setId("blah");

Now I'm not sure if that's what you want? That's you just want to set the Id of the customer for this invoice?

Otherwise, probably you should have a another property on your form backing object called something like customerId and you should bind the value of dropdown to this property.

if that's not possible, you may want to try to get it from request;

String customerId = request.getParameter("customerId");

and then:

Customer c = someManager.getCustomer(customerId);
invioce.setCustomer(c);

I hope this would help. Please don't hesitate to ask more questions if you think this is helping at all :)

ATTA

Hi Atta,
Sorry for the disturbance but I still have a problem with binding objects.
I'll tell you the details of my problem. Hope u could help me.
I have two classes Invoice and Customer.
The Invoice class contains a property named customer of type Customer.
I have a form that adds a new invoice.
The user should select a customer for this invoice from a drop down list.
I added a method referenceData in the addInvoiceFormController in which I get the list of available customers .

I added the binding of this property in the jsp page:

<spring:bind path="invoice.customer">
<select name="${status.expression}" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${customers}" var="customer">
<option value="${customer.id}"${customer.id == status.value ? ' selected' : ''}>${customer.firstName}</option>
</c:forEach>
</select>
</spring:bind>

When I try submitting the form I get the following error message:
Failed to convert property value of type [java.lang.String] to required type [com._4s_.invoice.model.Customer] for property 'customer'

I don't know where is the mistake.
Is there something wrong in the JSP?
Should I create a property editor? If yes, would you plz tell me how.
Should I create a formBackingObject for the customer in the addInvoiceFormController?

Sorry for this long message.
Thanks a lot for your help.
Sherihan.

sherihan
Jan 25th, 2005, 08:35 AM
Thanks a lot Atta.
It works correctly now.
Sherihan.

ATTA
Jan 25th, 2005, 09:07 AM
My pleasure! Just what did you wanted and what did you to get it? Can you please write few words, if you time, that is! I'm interested how did you get right Customer object to current invoice? :)

ATTA

Thanks a lot Atta.
It works correctly now.
Sherihan.

sherihan
Jan 25th, 2005, 10:45 AM
Hi,
Here is the FormController' code. The code in red solved the problem.

package com._4s_.invoice.web.action;



import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.CustomDa teEditor;
import org.springframework.beans.propertyeditors.CustomNu mberEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBin der;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormCont roller;
import org.springframework.web.servlet.view.RedirectView;

import com._4s_.invoice.model.Customer;
import com._4s_.invoice.model.Invoice;
import com._4s_.invoice.service.CustomerManager;
import com._4s_.invoice.service.InvoiceManager;

/**
* @author smagied
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class AddInvoiceFormController extends SimpleFormController {
private static Log log = LogFactory.getLog(AddInvoiceFormController.class);

private InvoiceManager mgr = null;
private CustomerManager customerManager = null;

public void setInvoiceManager(InvoiceManager invoiceManager){
this.mgr = invoiceManager;
}

public InvoiceManager getInvoiceManager(){
return this.mgr;
}

public void setCustomerManager(CustomerManager customerManager){
this.customerManager = customerManager;
}

public CustomerManager getCustomerManager(){
return this.customerManager;
}

/**
* *Set up a custom property editor for converting Longs
*
*/
public void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder){
NumberFormat nf = NumberFormat.getNumberInstance();
binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(Long.class, nf,true));

binder.registerCustomEditor(Date.class,null, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}


public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response,
Object command, BindException errors)
throws Exception{
if (log.isDebugEnabled()){
log.debug("entering 'onSubmit' method....");
}
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<onSubmit:>>>>>>>>>>>>>>>>>>>>>>>>>>>");

Invoice invoice = (Invoice) command;

String customerId = request.getParameter("selectCustomer");
Customer customer = customerManager.getCustomer(customerId);
invoice.setCustomer(customer);

mgr.saveInvoice(invoice);


return new ModelAndView(new RedirectView(getSuccessView()));
}

protected Object formBackingObject (HttpServletRequest request)
throws ServletException{
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<formBackingObject:>>>>>>>>>>>>>>>>>>>>>>>>>>>");

String invoiceId = request.getParameter("id");

if ((invoiceId != null) && !invoiceId.equals("")) {
Invoice invoice= mgr.getInvoice(new Long(invoiceId));
return invoice;
}else {
return new Invoice()
}
}

protected Map referenceData(HttpServletRequest request)
throws ServletException {
Map model = new HashMap();
model.put("customers", customerManager.getCustomers());
return model;
}
}

Here is the JSP page:

<%@ include file="/taglibs.jsp"%>
<html>
<title>Add Invoice</title>

<spring:bind path="invoice.*">
<c:if test="${not empty status.errorMessages}">
<div class="error">
<c:forEach var="error" items="${status.errorMessages}">
<c:out value="${error}" escapeXml="false"/><br />
</c:forEach>
</div>
</c:if>
</spring:bind>

<p>Please fill in the invoice details:</p>

<form method="POST">

<spring:bind path="invoice.id">
<input type="hidden" name="id" value="${status.value}"/>
</spring:bind>

<table>
<tr>
<td>Invoice-Number:</td>
<td>
<spring:bind path="invoice.invoiceNumber">
<input type="text" name="invoiceNumber" value="${status.value}"/>
</spring:bind>
</td>
</tr>

<tr>
<td>Date:</td>
<td>
<spring:bind path="invoice.date">
<input type="text" name="date" value="${status.value}"/>
</spring:bind>
</td>
</tr>

<tr>
<td>Customer:</td>
<td>
<spring:bind path="invoice.customer">
<select name="selectCustomer" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${customers}" var="customer">
<option value="${customer.id}"${customer.id == status.value ? ' selected' : ''}>${customer.firstName}</option>
</c:forEach>
</select>
</spring:bind>
</td>
</tr>

<tr>
<td>Total Price:</td>
<td>
<spring:bind path="invoice.totalPrice">
<input type="text" name="totalPrice" value="${status.value}"/>
</spring:bind>
</td>
</tr>

</table>

<p><input type="submit" name="submit" value="Submit"/>
</form>
</html>


Hope it's helpful.
Thanks a lot for your help.
Sherihan.

ATTA
Jan 25th, 2005, 10:43 PM
Allright! Now I see the red and it all makes sense for me. why didn't you go the way of adding another property for customerId to your form? just wondering?

ATTA

Hi,
Here is the FormController' code. The code in red solved the problem.

package com._4s_.invoice.web.action;



import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.CustomDa teEditor;
import org.springframework.beans.propertyeditors.CustomNu mberEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBin der;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormCont roller;
import org.springframework.web.servlet.view.RedirectView;

import com._4s_.invoice.model.Customer;
import com._4s_.invoice.model.Invoice;
import com._4s_.invoice.service.CustomerManager;
import com._4s_.invoice.service.InvoiceManager;

/**
* @author smagied
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class AddInvoiceFormController extends SimpleFormController {
private static Log log = LogFactory.getLog(AddInvoiceFormController.class);

private InvoiceManager mgr = null;
private CustomerManager customerManager = null;

public void setInvoiceManager(InvoiceManager invoiceManager){
this.mgr = invoiceManager;
}

public InvoiceManager getInvoiceManager(){
return this.mgr;
}

public void setCustomerManager(CustomerManager customerManager){
this.customerManager = customerManager;
}

public CustomerManager getCustomerManager(){
return this.customerManager;
}

/**
* *Set up a custom property editor for converting Longs
*
*/
public void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder){
NumberFormat nf = NumberFormat.getNumberInstance();
binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(Long.class, nf,true));

binder.registerCustomEditor(Date.class,null, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}


public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response,
Object command, BindException errors)
throws Exception{
if (log.isDebugEnabled()){
log.debug("entering 'onSubmit' method....");
}
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<onSubmit:>>>>>>>>>>>>>>>>>>>>>>>>>>>");

Invoice invoice = (Invoice) command;

String customerId = request.getParameter("selectCustomer");
Customer customer = customerManager.getCustomer(customerId);
invoice.setCustomer(customer);

mgr.saveInvoice(invoice);


return new ModelAndView(new RedirectView(getSuccessView()));
}

protected Object formBackingObject (HttpServletRequest request)
throws ServletException{
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<formBackingObject:>>>>>>>>>>>>>>>>>>>>>>>>>>>");

String invoiceId = request.getParameter("id");

if ((invoiceId != null) && !invoiceId.equals("")) {
Invoice invoice= mgr.getInvoice(new Long(invoiceId));
return invoice;
}else {
return new Invoice()
}
}

protected Map referenceData(HttpServletRequest request)
throws ServletException {
Map model = new HashMap();
model.put("customers", customerManager.getCustomers());
return model;
}
}

Here is the JSP page:

<%@ include file="/taglibs.jsp"%>
<html>
<title>Add Invoice</title>

<spring:bind path="invoice.*">
<c:if test="${not empty status.errorMessages}">
<div class="error">
<c:forEach var="error" items="${status.errorMessages}">
<c:out value="${error}" escapeXml="false"/><br />
</c:forEach>
</div>
</c:if>
</spring:bind>

<p>Please fill in the invoice details:</p>

<form method="POST">

<spring:bind path="invoice.id">
<input type="hidden" name="id" value="${status.value}"/>
</spring:bind>

<table>
<tr>
<td>Invoice-Number:</td>
<td>
<spring:bind path="invoice.invoiceNumber">
<input type="text" name="invoiceNumber" value="${status.value}"/>
</spring:bind>
</td>
</tr>

<tr>
<td>Date:</td>
<td>
<spring:bind path="invoice.date">
<input type="text" name="date" value="${status.value}"/>
</spring:bind>
</td>
</tr>

<tr>
<td>Customer:</td>
<td>
<spring:bind path="invoice.customer">
<select name="selectCustomer" value="${status.value}">
<option value="-1">-- Select --</option>
<c:forEach items="${customers}" var="customer">
<option value="${customer.id}"${customer.id == status.value ? ' selected' : ''}>${customer.firstName}</option>
</c:forEach>
</select>
</spring:bind>
</td>
</tr>

<tr>
<td>Total Price:</td>
<td>
<spring:bind path="invoice.totalPrice">
<input type="text" name="totalPrice" value="${status.value}"/>
</spring:bind>
</td>
</tr>

</table>

<p><input type="submit" name="submit" value="Submit"/>
</form>
</html>


Hope it's helpful.
Thanks a lot for your help.
Sherihan.

sherihan
Jan 26th, 2005, 01:47 AM
Hi,
I tried doing this but it didn't work.
sherihan.