I'm trying to use a code which looks like :
<ice:dataTable id="revisionDocuments" value="#{agendaBean.agenda.revisionsDocuments}" var="revision">
<ice:column>
<ice:inputText value="#{revision.sequenceAdresse}" id="revisionSequenceAdresse#{revision.index}" />
</ice:column>
I'd like to have a different id for my form fields. The revision object do contains an "index" field, representing the index of the object in the List. I want to see it appears in the id. However, nothing happens. The #{revision.index} expression is never interpreted (getIndex() on the revision object is never called).
You'll tell me JSF already make something that looks like :
revisionDocuments:0:revisionSequenceAdresse
revisionDocuments:1:revisionSequenceAdresse
revisionDocuments:2:revisionSequenceAdresse
True, but this affect only the clientId generated in the HTML. The UIComponent representing the form fields (in the ViewRoot from FacesContext) have all the same "id" AND "clientId" (yes, event if the HTML contains "revisionDocuments:0:revisionSequenceAdresse", the "clientId" you will find in ViewRoot is revisionDocuments:revisionSequenceAdresse).
Someone can help with my try ?
Thank you very much, any help will be greatly appreciated.
The component IDs are to be determined during view build time, not during view render time. The #{revision} is not available during view build time, so it always evaluates empty. Basically, you need to bind it to #{agendaBean} or something else which is already in the scope during the view build time. The component ID is specific to the component itself, not to its generated HTML output. You can't assign multiple different IDs to physically the one and same component.
But you actually don't need to fiddle around this approach. Your concrete problem for which you thought that this is the solution is already answered in your previous question: JSF2 + IceFaces 2 - Retrieve UIComponent from ViewRoot.
Related
okay lets start step by step:
Imagin, you have a selectOneMenu component which is working with objects which are comming from the database.
To work with objects in a selectOneMenu component, you have to define a simple converter which compare the object id with the givin string value which is passed as a function parameter and return the correct object. So far so good, nothing special here.
Now, a user can add additional Objects, which will be added to the selectOneMenu component.
The problem is now, if the user select the selfdefined object in the selectOneMenu component, it will throw an error, because of id is null. A workaround is to give the manual added object (created by a user) a unique id, and all is fine. But does exist a solution where no ids are required and still working with objects ?
thanks
I have 6 columns in my dataTable and I am particularly interested in two InputText: I must prevent the possibility of writing in both inputText on the same row. Either is written into one or the other, but not both.
The solution I found is to implement a Validator and browse the dataTable or specifically visiting the tree of components with UIComponent#visitTree() on UIData as advocated by BalusC here. My question is: how do I know on which row I am? How can I retrieve the value of a InputText specifying the row ?
My goal is to validate two InputText relative to another. When one has a value, the other must be null. And reciprocally.
If you have another solution, I'm interested.
Thanks for your help.
in our company we're hitting a serious problem which we think is a serious design flaw of the JSF spec, if it is the normal behavior.
This is our usecase:
SelectOneMenu (standard JSF or primefaces, doesn't matter, same behavior)
SelectItems with a database entity as it's value and a string as the label
A converter (via attribute on the selectOneMenu) which translates the entity to its ID (getAsString) and from the ID to the entity (getAsObject)
Everything works as expected as long as the entity inside the value attribute of the selectOneMenu is loaded using the same entityManager as the entities inside the selectItems. We have the same POJOs and therefore the same hashcode (Object#equals() returns true). But as soon as one of the entities is loaded via a different entityManager and therefore has a different hashcode, we are never able to get a match to generate the expected selected attribute of an select item (HTML <option /> ).
The cause of this behavior is, that the JSF-impl and primefaces both use the POJOs in the call
boolean selected = isSelected(context, menu, itemValue, valuesArray, converter);
for itemValue and valuesArray. The implementation of isSelected relies on Object#equals() for POJOs. In my opinion it should always use the value of Converter#getAsString if we have a Converter and pass it to isSelected. This is also the behavior for a POST request. Here we got a submittedValue for the selectOneMenu which is compared to the converted value of the POJO (Converter#getAsString).
Now the question:
Is this the expected behavior as it's described in the spec? Isn't the output of the converter the better way to handle this comparision? Now we have to modify our entity classes and overwrite the equals method to be able to use this construct.
Your mistake is that you forgot to implement/autogenerate equals() (and hashCode()) method conform the contract. This is beyond control of JSF. Pointing the accusing finger to JSF isn't making any sense.
It's handy to have a base entity where all your entities extend from so that you don't need to repeat the task over all entities (even though the average IDE/tool can easily autogenerate them). You can find an elaborate example in 2nd "See also" link.
See also:
Validation Error: Value is not valid
Implement converters for entities with Java Generics
I believe that this is the correct behavior. On Java side the values of the component and selection are POJOs. You have full control of the logic of their equality etc. It should not matter how it is converted to UI display and back. As a component user you should not bother to know how the POJO is displayed. As text, icon, color, whatever. The Java side of the component undestands and communicats with POJOs
YOUR CODE ----------> JAVA COMPONENT --------> CONVERTER ----------> HTML
Also I guess that relying on reference equality for entities is a road to problems. Setting equals/hashCode to use actual ID is the best approach.
We are facing a problem with dynamic columns. We have a table where columns depend on some filters previouosly selected. When you enter the page you can select year and some other criteria, and with these values we render the table. Our problem is that columns may vary when you select different criteria, and this is a problem because c:forEach is not so much dynamic.
If you look at the example provided in IceSoft Wiki you can see something similar to what we have in our code (but our code is much more complicated):
http://www.icesoft.org/wiki/display/ICE/DataTable+Dynamic+Columns
The problem comes with this sentence:
<c:forEach items="#{backing.columns}" var="colModel">
backing.columns is static. But if you change its number of elements (in this example it makes no sense because values in "columns" List match to properties in Task class, but if you are printing a List instead of List) you have a problem, as described here:
http://drewdev.blogspot.com.es/2008/08/cforeach-with-jsf-could-ruin-your-day.html
We've tried to recreate component list when we change columns with:
component.getChildren().clear(); //component is of UIComponent type
But didn't work. Also we've tried restoring view from context in a PhaseListener, and no positive results. And we've run out of ideas.
Any idea (or solution :D) would be appreciated. And if someone need more specific code, just ask.
TIA.
PS: This question is also posted in ICEFaces Forum (http://www.icesoft.org/JForum/posts/list/0/21842.page#76787), and I will update with solution (if any) both places.
We've solved the problem, as we've been suggested at IceSoft Forum, redirecting navigation to the same page in order to get a completely new component tree. For this you need your state to be in a bean that will survive that, but since our backing beans are usually viewscoped this is not a problem. To achieve this, we've changd valueChangeListener method that was changing the list behind the c:foreach and used an action method, and in this action method we're returning null as navigation rule to get the page reload.
See more at: http://www.icesoft.org/JForum/posts/list/21842.page#sthash.sXtPazmS.dpuf
Is it best to NOT label a form component (or any other component for that matter) unless you have a need to do so e.g. if you want to be able to reliably distinguish one component from another?
When I see examples of reference components I am always seeing them with a preceding colon e.g. ":dialog" rather than "dialog" or "form:dialog". Is not naming the form and then specifying the component using a preceding colon the best practice?
If you don't specify the id of the form because you don't need to reference it by a client ID right now, then it will technically not harm to omit it, because JSF will autogenerate one in any way.
From inside an ID-less form, for example, you can always reference the parent form as #form in execute and render attributes of <f:ajax> to signal that you want to submit and/or render the entire parent form.
<f:ajax execute="#form" render="#form" />
But if you need to reference for example another form or one of its child components on ajax render, then you should give that form a fixed ID, so that you will be able to reference it by client ID.
Another reason which we're experiencing in real world projects is that automated web unit testing software such as Selenium really requires a form with a fixed ID, because it needs to find the input fields and submit buttons by their name attribute which is also composed based on the JSF form ID. If the JSF form ID is not specified, then the input field name is unpredictable on every deploy/request and thus untestable.
All with all, the "best practice" is basically: "only if you need it". I myself am just getting used to always specify the ID of NamingContainer, UIInput and UICommand components. "You never know".
Your component ID would look something like,
:namingContainer:myComponent. Where the first “:” tells JSF that you
want to start looking for the component at the UIViewRoot instance, or
the very top level of the component tree
Read http://ocpsoft.org/java/jsf2-java/how-to-jsf-2-0-render-components-outside-of-the-form/