Announcement Announcement Module
Collapse
No announcement yet.
form:select binding a map Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • form:select binding a map

    All,
    I have a model of with two properties of MyObject. I want to bind each one to a <form:select tag populated with a map of Map<Integer, MyObject>.

    In older versions of SWF I was able to bind without using a custom binder. The value would be the key, the text would be some property on the 'value' object in the Map. The binder would automatically pick the bound object by key and set it into the model.

    Does anyone have a working example of this in SWF2? I can't find an example anywhere.

    Thanks!

    Jon

    SWF2
    MVC 3.0

  • #2
    Have you tried something like this:
    Code:
    <form:select path="selectedObject" items="${objectMap}" itemValue="key" itemLabel="value.someProperty" />

    Comment


    • #3
      Yes, I have tried everything. The Key is an Integer and the target property on the value object is a string. SWF still wants a custom converter. Apparently either A) there are no more default Map<> converters for options using key,value or B) this is broken in SWF 2.0.8 due to some of the other conversion service issues.

      Anyone have any ideas before I file a JIRA?

      Jon

      Comment


      • #4
        SOLVED!

        This is what I found. The binding operation to the model does NOT need the conversion service to emit the entire object. It just needs the value that the binder can use to equate the object to an object in the map. I was under the impression that the conversion had to emit a 'complete' object which was why I was confused.

        This JSTL works fine:
        Code:
        <form:form modelAttribute="unitConversion">
            <fieldset>
                <legend>Edit Unit Conversion</legend>
                <form:errors path="*" cssClass="errorBox"/>
                <form:select path="from" items="${unitSystems}" itemLabel="name"/><br/>
                <form:select path="to" items="${unitSystems}" itemLabel="name"/><br/>
                <form:label path="scaling" title="Scaling" for="scaling">Scaling</form:label>
                <form:input path="scaling"/><br/>
                <input type="submit" value="Save" name="_eventId_save" id="submitButton"/>
            </fieldset>
        </form:form>
        With this conversion service:
        Code:
        public class UnitSystemToString extends StringToObject {
            public UnitSystemToString() {
                super( UnitSystem.class );
            }
        
            @Override
            protected Object toObject(String string, Class targetClass) throws Exception {
                final UnitSystem us = new UnitSystem();
                us.setUnit( Integer.parseInt( string ) );
                return us;
            }
        
            @Override
            protected String toString(Object object) throws Exception {
                return String.valueOf( ( (UnitSystem) object ).getUnit() );
            }
        }
        I think the documentation could do a slightly better job explaining how the custom object binding works and what the requirements are for a object to string converter.

        Thanks!

        Comment


        • #5
          I spoke too soon! The bound object turned out to be the object emitted from the binding operation, NOT the object from the list backing the select drop down! This appears to be a bug.

          Here is the jira
          http://jira.springframework.org/browse/SWF-1215
          Last edited by jonnio; Mar 21st, 2010, 09:41 AM.

          Comment


          • #6
            What about something like this?
            I don't know if it makes sense, cause you could do the same in you controller, but... Maybe this is want you want.
            Code:
            public class StringToMapElement extends Converter {
            
            	private Class objectClass;
            
            	Map<String, Object> map;
            
            	public StringToMapElement(Class objectClass, Map<String, Object> map) {
            		this.objectClass = objectClass;
            		this.map = map;
            	}
            
            	public final Class getSourceClass() {
            		return String.class;
            	}
            
            	public final Class getTargetClass() {
            		return objectClass;
            	}
            
            	public final Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
            		String string = (String) source;
            		if (map != null && string != null && string.length() > 0) {
            			return toObject(string, targetClass);
            		} else {
            			return null;
            		}
            	}
            
            	public Object toObject(String string, Class objectClass) throws Exception {
            		Integer key = Integer.valueOf(string);
            		return map.get(key);
            	}
            }

            Comment


            • #7
              That would work, of course, but how do I get the Map injected during the binding process when using spring web flow?

              Comment


              • #8
                For those of you following this...I updated the JIRA with some research.

                Jon

                Comment

                Working...
                X