-
1. Re: form controls with the same property name
wise_guybg Sep 19, 2007 7:19 AM (in response to schmod54)Normally you wouldn't have components with the same name. Why don't you add an index next to the name. Ex.: username1, username2...
Either way if you want them referenced from/to a backing bean you should have different fields!? -
2. Re: form controls with the same property name
schmod54 Sep 21, 2007 4:39 PM (in response to schmod54)My initial attempt was to do as you said... but it didn't work. I've played around with it and discovered that displaying faces messages attached to a control inside of a loop is problematic. Has anyone done this? The following is my code to allow users to modify a set of "Category" objects:
<a4j:repeat value="#{batchCategories}" var="cat"> <ui:param name="i" value="#{batchCategories.rowIndex}"/> <s:decorate id="name#{i}Decorate" template="/inc/Field.xhtml"> <ui:define name="label">Name:</ui:define> <h:inputText id="name#{i}" value="#{cat.name}"/> </s:decorate> </a4j:repeat>
Instead of getting my form error messages displayed attached to the proper controls, I get:WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
in my logs. My decorator is fine, and works if I hardwire it to a particular item, like so:<ui:param name="cat" value="#{batchCategories.rowData}"/> <ui:param name="i" value="#{batchCategories.rowIndex}"/> <s:decorate id="name#{i}Decorate" template="/inc/Field.xhtml"> <ui:define name="label">Name:</ui:define> <h:inputText id="name#{i}" value="#{cat.name}"/> </s:decorate>
<ui:repeat> has the same behavior, except no warning in the logs. <c:forEach> doesn't display properly either... it puts all the messages in the global area. So... does anyone know how to display faces messages next to particular form controls inside a loop? -
3. Re: form controls with the same property name
wise_guybg Sep 23, 2007 3:03 AM (in response to schmod54)I'm wondering about that
batchCategories.rowIndex
How have you realized it?
I also did not see how you have calledfacesMessages.addToControlFromResourceBundle("username", "usernameExists");
You should be using indexes there too, right? -
4. Re: form controls with the same property name
schmod54 Sep 23, 2007 8:13 AM (in response to schmod54)I was a bit ambiguous in my previous posts, because I was mixing examples... also I was wrong about the exact problems I've had with different approaches. So I've made a simplified example that shows what I want to do, and how the different approaches fail. I'm running this in a seam-genned project on seam 2 beta, jboss 4.2.1.GA, but I expect it to behave the same way in other versions. Here is the source:
I have the following in my pages.xml... It's not strictly necessary to run the example though:<page view-id="/control_loop_test.xhtml"> <begin-conversation join="true"/> </page>
Here is an action bean that assigns facesMessages to form controls inside a loop:import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.datamodel.DataModel; import org.jboss.seam.faces.FacesMessages; import java.util.Arrays; import java.util.Collection; @Name("controlLoop") @Scope(ScopeType.CONVERSATION) public class ControlLoopAction { @In private FacesMessages facesMessages; public static class MyEntity { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @DataModel private Collection<MyEntity> batchEntities = Arrays.asList(new MyEntity(), new MyEntity()); public Collection<MyEntity> getBatchEntities() { return batchEntities; } public String submit(String controlPrefix) { for (int i = 0; i < batchEntities.size(); i++) facesMessages.addToControlFromResourceBundle(controlPrefix + "Name" + i, "badName" + i); return "/control_loop_test.xhtml"; } }
Here is a page that tries a few different ways of inputting data into the action bean.<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:a4j="https://ajax4jsf.dev.java.net/ajax" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets"> <head> <title>Control Loop Test</title> </head> <body> controlLoop: #{controlLoop}<br/> global messages: <h:messages globalOnly="true"/><br/> hardwired form... this works (at least for h:message anyway) but I really don't want to have to do this for large variable-size forms: <h:form id="hardwiredForm"> Name0: <h:inputText id="hardwiredName0" value="#{controlLoop.batchEntities[0].name}"/> s:message: <s:message/> h:message: <h:message for="hardwiredName0"/><br/> Name1: <h:inputText id="hardwiredName1" value="#{controlLoop.batchEntities[1].name}"/> s:message: <s:message/> h:message: <h:message for="hardwiredName1"/><br/> <h:commandButton value="Submit" action="#{controlLoop.submit('hardwired')}"/> </h:form> <br/> a4j:repeat form... I'm thinking this doesn't work because the id of h:inputText gets resolved when the view is built... see <a href="http://www.ninthavenue.com.au/blog/c:foreach-vs-ui:repeat-in-facelets"> http://www.ninthavenue.com.au/blog/c:foreach-vs-ui:repeat-in-facelets</a>:<br/> <h:form id="a4jRepeatForm"> <a4j:repeat id="mainLoop" value="#{controlLoop.batchEntities}" var="myEntity" rowKeyVar="i"> Name#{i}: <h:inputText id="a4jName#{i}" value="#{myEntity.name}"/> s:message: <s:message/> h:message: <h:message for="a4jName#{i}"/><br/> </a4j:repeat> <h:commandButton value="Submit" action="#{controlLoop.submit('a4j')}"/> </h:form> <br/> ui:repeat form... same problem as a4j:repeat, but I don't want to use ui:repeat anyway because of its known bugs: <h:form id="uiRepeatForm"> <ui:repeat value="#{batchEntities}" var="myEntity"> Name#{batchEntities.rowIndex}: <h:inputText id="uiName#{batchEntities.rowIndex}" value="#{myEntity.name}"/> s:message: <s:message/> h:message: <h:message for="uiName#{batchEntities.rowIndex}"/><br/> </ui:repeat> <h:commandButton value="Submit" action="#{controlLoop.submit('ui')}"/> </h:form> <br/> c:forEach form... maybe this would work if I could get c: tags working... I tried some things I found on the web to get c: tags working, but none of them worked for me:<br/> <h:form id="cForEachForm"> <c:forEach id="mainLoop" value="#{controlLoop.batchEntities}" var="myEntity" varStatus="i"> Name#{i.index}: <h:inputText id="forEachName#{i.index}" value="#{myEntity.name}"/> s:message: <s:message/> h:message: <h:message for="forEachName#{i.index}"/><br/> </c:forEach> <h:commandButton value="Submit" action="#{controlLoop.submit('forEach')}"/> </h:form> </body> </html>
If anyone could show me how to get the facesMessages to correctly appear next to the relevant controls within the context of a loop, I'd greatly appreciate it. Thanks. -
6. Re: form controls with the same property name
schmod54 Sep 25, 2007 11:09 AM (in response to schmod54)Thanks. I voted for it.