Spring Form Binding w/Select multiple="multiple"

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Spring Form Binding w/Select multiple="multiple"

Martin
Hello again,

I am not winning w/this one form element;

With the following template:
<select id="multiSelectElementsSelected"
  name="multiSelectElementsSelected"
  multiple="multiple"
  th:field="*{chosenElements}">
    <option th:each="element,row : *{chosenElements}"
      th:value="${element.id}"
      th:text="${element.description}"></option>
</select>

which produces markup along the lines of:
<select name="chosenElements" multiple="multiple" id="multiSelectElementsSelected">
  <option value="1">Shelter for all</option>
  <option value="2">Respect and dignity for all</option>
  <option value="3">Parents empowered</option>
  <option value="4">Good mental health</option>
</select>
<input type="hidden" value="1" name="_chosenElements">


I'm failing to get the bound model object to incorporate the selected elements from this multi-select?
Also not found anything specific to multi select in the documentation. Is there a chance that a sample could be about to aide me here?

.m
Reply | Threaded
Open this post in threaded view
|

Re: Spring Form Binding w/Select multiple="multiple"

danielfernandez
Administrator

Hi,

Something looks wrong here: a select like this usually needs two things:

1. A property in your form backing bean containing the collection of selected values, with its corresponding getter and setter methods. In your case it isn't really clear, but it seems to be called "chosenElements". This is the one that should go in the "th:field" in <select>, like <select th:field="*{chosenElements}" ...>

2. A collection holding all the possible values for this property, for each of which elements an <option> tag will be displayed. Thymeleaf will automatically mark as "selected" those options with a "value" attribute contained in your "chosenElements".

The problem is that you are iterating "chosenElements" to create the options, which should bring you only the currently selected and would anyway not work OK because the use of *{chosenElements} in th:field at the <select> tag makes Thymeleaf suppose that chosenElements is a collection of integers (because that is what appears on the "value" attributes of the <option> tags). And it isn't.

Something like this would look much better:

<select id="multiSelectElementsSelected"
            name="multiSelectElementsSelected"
            multiple="multiple"
            th:field="*{chosenElements}">

    <option th:each="element,row : *{allElements}"
                th:value="${element.id}"
                th:text="${element.description}"></option>

</select>

Being "allElements" a List<Element> and "chosenElements" a List<Integer>, for example.

Regards,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: Spring Form Binding w/Select multiple="multiple"

Martin
Hello Daniel,

Thank you so much for you time sir,

Ja -- I was perhaps not clear enough. It was late.
I actually do have it as you described. On the template I have two multi-select lists and then some javascript to allow "Add" and "Remove" type effect. Workflow is thus

- Select (1..*) in the Available list (populated as you described using a list of all elements and an th:each on the options
- Press button which fires JS to copy from the above list to the 'chosen' list.

The chosen list is backed as you say in the FBO with a list and the template uses the code for th:field="*{chosenElements}"> also.

The full code in my template (sans JS) is as follows:

<code>
                            <form id="applicationform" name="applicationform" method="POST"
                                action="#" th:object="${simulationModel}" th:action="@{/simulation/step2}">
                                <fieldset class="control-group" th:classappend="${#fields.hasErrors('elements')}? 'error'">
                                    <label for="multiSelectElementsAvailable" class="control-label">Select Elements</label>
                                    <div class="controls">
                                        <select id="multiSelectElementsAvailable"
                                                name="multiSelectElementsAvailable"
                                                multiple="multiple"> 
                                            <option th:each="element : *{allElements}"
                                                    th:value="${element.id}"
                                                    th:text="'['+ ${element.sequence} +']  ' + ${element.description}"></option>
                                            <option th:remove="all">Shelter for all</option>
                                            <option th:remove="all">Respect and dignity for all</option>
                                            <option th:remove="all">Parents empowered</option>
                                            <option th:remove="all">Good mental health</option>
                                            <option th:remove="all">Social support for women</option>
                                        </select>
                                        <select id="multiSelectElementsSelected"
                                            name="multiSelectElementsSelected"
                                            multiple="multiple"
                                            th:field="*{chosenElements}">
                                            <option th:each="val : *{chosenElements}"
                                                    th:value="${val.id}"
                                                    th:text="${val.description}"></option>
                                        </select>
                                    </div>
                                </fieldset>
                                <fieldset class="control-group">
                                    <div class="controls">
                                        Add 
                                        Remove
                                    </div>
                                </fieldset>
                            </form>
</code>
Reply | Threaded
Open this post in threaded view
|

Re: Spring Form Binding w/Select multiple="multiple"

Martin

Doh!... I see the error of my ways.

Clearly this would not work as the elements would have to be *selected* also before being bound back into the form (which works).

Ignore this please. Resolved now.

Thank you.