PDA

View Full Version : Multiple select value and spring:bind


fmourioux
08-17-2004, 07:22 AM
My question is very simple :

how can i use a select with multiple value and spring:bind ?

In fact i have a list of users, every user has N role, and i like to show/choose the list of the role with a select with the property mutiple="true".

<spring:bind path="utilisateur.roles">
<select name="idRoles" multiple="true" >
<c:forEach var="role" items="${roles}">
</c:forEach>
</select>
<span class="fieldError">${status.errorMessage}</span>
</spring:bind>

Anyone a sample ?

Fabien.

j2ux
08-17-2004, 08:16 AM
Below is an excerpt from the mailing list I once used for testing (and it worked!).
You may encounter the problem when working with "multi-select-boxes" that the request only contains the selected items.

Another reference you can check is AppFuse

https://appfuse.dev.java.net/

it contains a multi select box but without using "spring:bind" (but solves the problem of non-selected items).

Regards,
Lars

As this solution not only applies to checkboxes, but also to html <select> fields with multiple values allowed, I would suggest renaming "checkbox" to something else, "field" maybe?

For example:

<spring:bind path="recommendation.involvedMemberStates">
<input type="hidden" name="_checkbox.<c:out
value="${status.expression}"/>">
<select name="<c:out value="${status.expression}"/>" size="6"
multiple>
<c:forEach var="memberState" items="${status.value}">
<option value="<c:out
value="${memberState.memberStateCode}"/>">
<c:out value="${memberState.name}"/>
</option>
</c:forEach>
</select>
</spring:bind>

This renders a 6-line select box where you can select multiple values.
If none are selected, the parameter is not present in the request, and the "_checkbox" hidden field ensures the bean property is set to null.

This works fine, but the "checkbox" naming is a bit undesirable...

Kind regards,
Tom.

fmourioux
08-18-2004, 06:13 AM
I'am ok for displaying the selected roles.

But how can i retreive the roles selected in the list box when i submit the form ?

j2ux
08-18-2004, 06:46 AM
You can use the request, e.g.:

String[] userRoles = request.getParameterValues("userRoles");
if (userRoles != null) {
for (int i = 0; i < userRoles.length; i++) {
log.debug(userRoles[i]);
}
}

fmourioux
08-18-2004, 10:40 AM
Thanks a lot, again ! :D

uze
08-25-2004, 12:53 PM
I have problem with the same multi-select context. My model object has a property of type List containing objects binded to a list of checkboxes in a form. Now when I submit the form, what is the proper way to set that List property (ie to rebuild/add the List's property objects based on the form's checked boxes)???

Any help would be appreciated.

Uze

fmourioux
08-25-2004, 01:24 PM
Hi uze ! can u send us more information (small peice of your code for example) about your pb in order to solve it ?

Thanks,

Fabien.

uze
08-25-2004, 02:11 PM
Ok, I'll try to make it short:

I have a car class with a drivers List property like this:

Class Car{
public List drivers
...
}

Car is the command passed thru formBackingObject() and refererenced as myDataModel in the view:

<spring:bind path="myDataModel.drivers">

<c:forEach var="driver" items="${allDrivers}">
<INPUT class="checkbox" type="checkbox"
name='<c:out value="${status.expression}.${driver.id}" />'
<c:forEach var="d" items="${myDataModel.drivers}">
<c:if test="${d.Id==driver.Id}">CHECKED</c:if>
</c:forEach>>
<c:out value="${model.modelName}" />
<br/>
</c:forEach>

</spring:bind>

allDriver being a List of driver passed thru referenceData(). This will generate as much checkboxes as there is driver objects and check the ones that have a matching driver object in myDataModel.

When I post the form, I want myDataModel.drivers (which is a List) to be populated with the checked items only. Now, I could parse manually the request and create the required driver objects, but I am wondering if we can have something like the propertEditors to do the trick.

Any ideas???

Uze

fmourioux
08-25-2004, 03:32 PM
I have the same problem, i did it manually in the controller exactly in the onBind part. I don't find an example for propertyEditor for the moment.

I hope someone will help us, for this moment the classic solution works well and it can be upgraded later.

Fabien.

uze
08-27-2004, 03:14 PM
Now I really need help. I tried parsing the request in the onBind as Fabien mentionned but Spring trows me Failed to convert property value of type [java.lang.String] to required type [java.util.List] for property models

with this jsp:


<spring:bind path="reoDataModel.models">
<c:forEach var="model" items="${models}">
<INPUT class="checkbox" type="checkbox"
value='<c:out value="${model.programId}" />'
name='<c:out value="${status.expression}" />'
<c:forEach var="m" items="${reoDataModel.models}">
<c:if test="${m.programId==model.programId}">CHECKED</c:if>
</c:forEach> >
<c:out value="${model.modelName}" />
<br />
</c:forEach>
</spring:bind>

And this is the code in my form controller:

protected void onBind(HttpServletRequest request, Object command, BindException errors) {

ReoDataModel reo = (ReoDataModel) command;

//parse checked models from the request
List models=new LinkedList();
String[] reqModels = request.getParameterValues("models");
if (reqModels != null) {
for (int i = 0; i < reqModels.length; i++) {
models.add(Model.findById(reqModels[i]));
}
}

reo.setModels(models);
}


Do I have to remove the bind from the JSP? How can spring know I've actually handled this property of the command and how can I tell Spring to ignore it?

Any hint would help!

Uze

fmourioux
08-27-2004, 03:26 PM
In my jsp pages i just put a select without spring.

It works fine for me this is the old methode simple request parameters, convert in the bind methode to object,

Try it and tell me if it works ;-)

Fabien

uze
08-27-2004, 04:22 PM
This works, but I prefer to keep the <spring:bind> so I preceded the <input> names with a "_" so Spring does not see them while binding. This is not really elegant, but it works.

I think the Spring Team should modify the bind method to pass a string array to a custom editor when multiple form parameters with the same name are posted. Now we could do our stuff in regular propertyEditors.

Uze

fmourioux
08-27-2004, 04:30 PM
Agree !

I like to make a customeditor in order to avoid a string[] to objects and objects to string[] conversion (or encapsulate this conversion) ?

Do u kown a sample ?

I going to sleep now it's late... see u soon,

Fabien

fmourioux
12-21-2004, 06:26 AM
Hi,

Always no way for this ?

Thanks,

Fabien.

plethora
12-21-2004, 07:39 AM
This works, but I prefer to keep the <spring:bind> so I preceded the <input> names with a "_" so Spring does not see them while binding. This is not really elegant, but it works.

I think the Spring Team should modify the bind method to pass a string array to a custom editor when multiple form parameters with the same name are posted. Now we could do our stuff in regular propertyEditors.

Uze

Check out this JIRA issue:
http://opensource.atlassian.com/projects/spring/browse/SPR-552

olivier
12-21-2004, 07:48 AM
Here is a nice way to do that, all with pure spring tags :



you need a property checked (Boolean) in your driver object.


<c:forEach items="${myDataModel.drivers}" var="driver" varStatus="loopStatus">

<spring:bind path="myDataModel.drivers[${loopStatus.index}].checked">
<input class="checkbox" type="checkbox"
name ="<c:out values = "_${status.expression}"/>"
value = "true" <c:if test="${status.value}">CHECKED</c:if> >
</spring:bind>

</c:forEach>


That will bind directly to your list, the checkbox. [/code]

sjivan
12-21-2004, 09:08 AM
Thats for multiple checkboxes. Here's what I did to bind to the muliple select element.


<spring:bind path="equipmentGroupForm.selectedEquipmentGroups">
<select name="<c:out value="${status.expression}"/>" multiple>
<c:forEach var="equipmentGroup" items="${equipmentGroups}">
<c:out value="${status.value}" />
<%
String equipmentGroup = ((EquipmentGroup)pageContext.getAttribute("equipmentGroup")).getName();
EquipmentGroupForm form = (EquipmentGroupForm)request.getAttribute("equipmentGroupForm");
Boolean eg_selected =Boolean.valueOf(form.isEquipmentGroupSelected(equ ipmentGroup));
pageContext.setAttribute("eg_selected", eg_selected);
%>

<option <c:if test="${eg_selected}">selected</c:if> value="<c:out value="${equipmentGroup.name}"/>">
<c:out value="${equipmentGroup.name}"/>
</option>
</c:forEach>
</select>
</spring:bind>


Regards,
Sanjiv

xlancer
08-28-2007, 03:44 AM
Here is a nice way to do that, all with pure spring tags :



you need a property checked (Boolean) in your driver object.


<c:forEach items="${myDataModel.drivers}" var="driver" varStatus="loopStatus">

<spring:bind path="myDataModel.drivers[${loopStatus.index}].checked">
<input class="checkbox" type="checkbox"
name ="<c:out values = "_${status.expression}"/>"
value = "true" <c:if test="${status.value}">CHECKED</c:if> >
</spring:bind>

</c:forEach>


That will bind directly to your list, the checkbox.


May i know how u collect back those "checked" check boxes into controller and submit to JDBC?

filip.bauwens
05-22-2008, 04:03 AM
Hello,
I am having an issue binding 'format' elements in beneath code.


I have a double loop:
The first loop binds the attribute 'docbase_name' in the 'repository' loop:
docshifterReceiverConfig.configuration.repositorie s.repository[${loopStatusRepo.index}].docbase_name
Works fine.

The second nested loop:
docshifterReceiverConfig.configuration.repositorie s.repository[${loopStatusRepo.index}].dctm_formats.format[${loopStatusFormats.index}] ,
wants to bind 'format[${loopStatusFormats.index}]' elements, but this does not happen, although the parent object 'Dctm_formats' has a setter method:

public void setFormat(
final int index,
final java.lang.String vFormat) {
this._formatList.set(index, vFormat);
}

and ${status.value} displays the correct value on my jsp page, but when changing this value and submitting the jsp, I do not get the new value in 'docshifterReceiverConfig' object.


complete code:

<c:forEach items="${docshifterReceiverConfig.configuration.repositor ies.repository}" var="repos" varStatus="loopStatusRepo">

<spring:bind path="docshifterReceiverConfig.configuration.repositorie s.repository[${loopStatusRepo.index}].docbase_name">
<td width="40%">
<input name="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>">
</td>

</spring:bind>


<c:forEach items="${docshifterReceiverConfig.configuration.repositor ies.repository[loopStatusRepo.index].dctm_formats.format}" var="formats" varStatus="loopStatusFormats">
<spring:bind path="docshifterReceiverConfig.configuration.repositorie s.repository[${loopStatusRepo.index}].dctm_formats.format[${loopStatusFormats.index}]">
<tr>
<td width="40%">
<input type="text" name="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>">

</td>

</tr>
</spring:bind>
</c:forEach>

</c:forEach>

could anyone help me out on this issue, many thx

beginner
06-09-2008, 11:33 PM
I have the same situation. I want to know, How you collect those selected objects by checked check boxes into controller?

beginner
06-09-2008, 11:52 PM
I have the same situation. If you've got the solution, please share....