Reputation: 4181
I'm trying to make a conditional render in my Seam application (2.2.0), to display two different controls depending on a condition.
I'm using the s:fragment
tag with the render attribute, but my problem is that I want whatever the control is displayed, to have the same id:
<s:fragment render="${editable}">
<rich:calendar id="entityDate"..../>
</s:fragment>
<s:fragment render="${!editable}">
<h:outputText id="entityDate".../>
</s:fragment>
My problem is that even when the render attribute set to false, the "not to be rendered" element is parsed, and I get an exception because of the duplicated id.
I also tried with the tag <ui:remove>
, which effectively removes the element before the parsing phase, so I can have something like:
<span id="myId"/>
<ui:remove>
<span id="myId"/>
</ui:remove>
Unfortunately the <ui:remove>
tag doesn't allow conditional logic. Has anyone found a way to solve this?
Upvotes: 2
Views: 1408
Reputation: 857
Would you be able to get the same results you need by putting the id tag on the fragment? So:
<s:fragment id="entityDate">
<rich:calendar render="${editable}" />
<h:outputText render="${!editable}" />
</s:fragment>
Upvotes: 0
Reputation: 10075
I use selenuim myself in a seam environement and i recommend using defined ids whenever possible. First you have the ability to create smaller ids which is usefull for pagesize. Second the selenium test run alot faster if you use ids for referencing instead of other selectors. I have not yet found a selenium test where you cannot handle diffrent ids. Additionally if a code fails in jsf tree creation you see which id is failing.
I see you are using sfragment with editable or not. I use the sdecorate and give the decorate an id and then "just" ed for the input and vi for the outputtext for example. This makes it easy in selenium to check the availability of edit or view components.
Upvotes: 0
Reputation: 1108842
That's only possible when you use a view build time tag such as JSTL <c:if>
.
<c:if test="#{editable}">
<rich:calendar id="entityDate" />
</c:if>
<c:if test="#{!editable}">
<h:outputText id="entityDate" />
</c:if>
(note that this is not going to work within an iterablte JSF component, such as <ui:repeat>
, <h:dataTable>
and so on)
After all, I strongly recommend to take benefit of the disabled
attribute instead, if necessary with a good shot of CSS to hide the input field borders and so on. It'll minimize the JSF view boilerplate code.
<rich:calendar id="entityDate" disabled="#{!editable}" />
Disabled inputs are separately styleable by the CSS attribute selector element[attribute]
, e.g.
input[disabled] {
border: 0;
}
The above removes the border of input
elements with the disabled
attribute present so that it look like a normal output text.
Upvotes: 3
Reputation: 12495
"Solve"? There is nothing to solve here: two elements in a GUI can not have the same ID. Hardly unnatural or unsound?
It's like asking: "I have a database table with two rows, I would like them both to have the same primary key value, but somehow I get these errors... has anyone managed to solve the problem and circumvent the constraints?".
Or even closer analogy: "I have two spans, one of them is invisible (has style="display: none") I would like them both to have the same id - and browsers seem not to like it, despite one of the spans being invisible".
Bottom line: rendered on not rendered, each component is still a part of the view tree, and therefore has a UNIQUE id.
I have a suspicion that you want to have some "polymorphic" code that should work with the currently visible element. Using ID for such code IS WRONG. If you show us your use case, we might find a right way to achieve the effect.
Upvotes: 0