Announcement Announcement Module
Collapse
No announcement yet.
Problems binding an object to form:options Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems binding an object to form:options

    Hi!

    I need to design a JSP page with two lists to add elements from one to the other and after this, send the second list in the submit action, but I can't find a way to do this.

    My first approach was creating an object with two list of LabelValue (a simple object with to attributes to represent the label and tha value ) to put in them the elements to show in the jsp page (and avoiding put them in the request and direct access them from the command object).

    This object, FormData , would be like this :

    Code:
    public class FormData
    {
            private List<LabelValue> availableElements;
    	private List<LabelValue> currentElements;
    
    ...
    }
    In the controller, something like this is done:
    Code:
    FormData formData = new FormData();
      < set lists >
    
    model.addAttribute("formData",formData);
    and in the jsp :

    Code:
    <form:form method="POST" modelAttribute="formData" >
    	
    	<table class="addRemoveElements">
    	<tr>
    		<td>
    			<form:select id="availableElements" path="" size="15">
                	<form:options items="${availableElements}" itemLabel="label" itemValue="value"/>       	
            	</form:select>
    		</td>
    		
    		<td>
    			<input type="button" value="-->" onclick="javascript:addElement(availableElements,currentElements)"/> 
    			<br/>
    			<br/>
    			<input type="button" value="<--" onclick="javascript:removeElement(currentElements,availableElements)"/> 
    		</td>
    		
    		<td>
    			<form:select id="currentElements" path="currentElements" size="15">
               		<form:options items="currentElements" />       	
            	</form:select>		
    		</td>
    		
    		<td>
    			<input type="button" value="Subir" onclick="javascript:moveElementUp(currentElements)"/>
    			<br/>
    			<br/>
    			<input type="button" value="Bajar" onclick="javascript:moveElementDown(currentElements)"/> 
    		</td>
    		
    	<tr>
    	</table>
    	
    	<br/>
    
    	<div class="button"> 
    		<input type="submit" value="<spring:message code="Buttons.done"/>" />           	
       	</div>
    Trying to do this (and also using spring:bind surrounding the form:select), the given error is:

    Code:
    Caused by: javax.servlet.jsp.JspException: Type [java.lang.String] is not valid for option items
    Any idea about the way of do this?

    Also I want to do this in this way because I need to send the elements in the list when the form is submitted, but I don't know the way to do it (perhaps this approach is incorrect). Any suggestions?

    A lot of thanks.

  • #2
    Property editors

    If you want to bind your LabelValues, you have to provide a property editor for that class (or property).

    If you want the controller to use that property editor, you have to override the initBinder method and register the custom editor to the binder.

    Code:
    binder.registerCustomEditor(LabelValue.class, myFirstLabelValueEditor);

    Comment


    • #3
      Thanks for your reply commer.

      Thinking in the possibilities about using PropertyEditors, I want to know if this situation could be resolved using them:

      Suposse that we have an Entity with some attributes, like this:

      Code:
      public class Researcher implements Serializable
      {
      	private Integer researcherID;
      	...
      	private String signature;
      
              ...
      }
      (Attribute researcherID is the primary key (identifier) in database)

      So, in the same situation explained in my first post (two list of elements to move elements from the left one to the right one and viceversa), suppose that I want to display in the form: options the researchers using:

      Label --> signature
      Value --> researcherID

      ┐Could be possible to define a CustomPropertyEditor to solve this situation? I try to do it, but the same error that I explained before appears.

      Also, if is possible to do this, ┐ could be possible to send the information on the target list, and through the PropertyEditor convert automatically the value of the option to the corresponding Researcher to access them on the controller?


      I try this:

      Form to contain the two list of Researchers
      Code:
      public class ResearcherAddRemoveForm
      {
      	private List<Researcher> availableElements;
      	private List<Researcher> currentElements;
              ...
      }

      CustomPropertyEditor
      Code:
      public class ResearcherPropertyEditor extends PropertyEditorSupport
      {
      
      	@Autowired
      	private ResearcherService researcherService;
      	
      	public ResearcherPropertyEditor(){}
      	
      	
      	
      	@Override
      	public String getAsText() 
      	{
      		Researcher r = (Researcher)getValue();
      		
      		return r.getSignature();
      	}
      	
      	
      	@Override
      	public void setAsText(String text)
      	{
      		Researcher rese;
      		
      		try
      		{
      			rese = researcherService.getResearcher(Integer.parseInt(text));
      			setValue(rese);
      		} 
      		catch (NumberFormatException e)
      		{
      			setValue("");
      		}
      		catch (InstanceNotFoundException e)
      		{
      			setValue("");
      		}
      		
      
      	}
      }

      Binding Initializer
      Code:
      public class LBDPortalBindingInitializer implements WebBindingInitializer 
      {
      	@InitBinder
      	public void initBinder(WebDataBinder binder, WebRequest request)
      	{
      		binder.registerCustomEditor(Researcher.class, new ResearcherPropertyEditor() );
      	}
      
      }

      XML servlet configuration
      Code:
         	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
                 <property name="webBindingInitializer">
      			<bean class="es.udc.lbd.portal.http.controller.propertyeditors.LBDPortalBindingInitializer"/>
      		</property>
      	</bean>

      ┐Any ideas? Perhaps I am not understanding correctly the meaning of getAsText and setAsText...

      The real thing I want to do is, when the form is submitted, send a list of researchers to the controller in the command object attribute "currentWriters". In a simple way, perhaps sending all values of the form: options to the controller things would be easy, but I don't know how to do it!
      Last edited by bLaDe00; Aug 28th, 2008, 08:18 AM.

      Comment


      • #4
        Well, I finally got how to represent Researchers into form: options (no PropertyEditor needed ), but now the second problem appears:

        ┐how can I send all elements in the second form: options to access them from the controller? In post " @RequestParam with Lists" (in Web forum), the problem is very similar to my situation, but I'm trying to use <spring: bind> but no working at all :S


        P.D. The way to represent Researcher :

        Code:
        <form:form method="POST" commandName="addRemoveElementsForm">
        
        	<form:select id="availableElements" path="" size="15">
                    	<form:options items="${addRemoveElementsForm.availableElements}" itemLabel="signature" itemValue="researcherID"/>       	
                </form:select>
        
        ...
        Last edited by bLaDe00; Aug 28th, 2008, 12:39 PM.

        Comment


        • #5
          Can you post updated JSP code? It looks like in this last iteration you have dropped the path binding from the form:options tag. Have you done that for the second list box as well?

          Comment


          • #6
            Finally got it, but with "tricks" (using javascript )

            The final JSP code:

            Code:
            <form:form id="form" method="POST" commandName="addRemoveElementsForm" modelAttribute="selectedElements"  action="${submitAction}">
            
            	
            	<table class="addRemoveElements">
            	<tr>
            		<td>
            			<form:select id="availableElements" path="" size="15">
                        	<form:options items="${addRemoveElementsForm.availableElements}" itemLabel="signature" itemValue="researcherID"/>       	
                    	</form:select>
            		</td>
            		
            		<td>
            			<input type="button" value="-->" onclick="javascript:addElement(availableElements,currentElements)"/> 
            			<br/>
            			<br/>
            			<input type="button" value="<--" onclick="javascript:removeElement(currentElements,availableElements)"/> 
            		</td>
            		
            		<td>
            				<form:select id="currentElements" path="selectedElements" size="15" multiple="true">
                       				<form:options items="${addRemoveElementsForm.currentElements}" itemLabel="signature" itemValue="researcherID"/>  	
                    		</form:select>		
            		</td>
            		
            		<td>
            			<input type="button" value="Subir" onclick="javascript:moveElementUp(currentElements)"/>
            			<br/>
            			<br/>
            			<input type="button" value="Bajar" onclick="javascript:moveElementDown(currentElements)"/> 
            		</td>
            		
            	<tr>
            	</table>
            	
            	<br/>
            
            	<div class="button"> 
            		<input type="submit" value="<spring:message code="Buttons.done"/>" onclick="javascript:selectAllOptions(currentElements)"/>           	
               	</div>
               	
            
            </form:form>
            The trick is using in the "target" list a multiple select and simply add elements to it... but when submitting the form, the javascript method selectAllOptions selects all elements in the list and send them associated with model attribute selectedElements. The code :


            Code:
            public class ElementListSelection
            {
            
            	public List<String> selectedElements;
            	
            
            	public ElementListSelection(){}
            
            	
            	
            	public List<String> getSelectedElements()
            	{
            		return selectedElements;
            	}
            
            
            	public void setSelectedElements(List<String> selectedElements)
            	{
            		this.selectedElements = selectedElements;
            	}
            }
            and in the JSP:

            Code:
            model.addAttribute("selectedElements", new ElementListSelection());

            Hope this would help more people in similar cases (but perhaps a more elegant solution exits..., jeje)

            Comment

            Working...
            X