Conditionally wrap HTML elements
In my Seam application, I have a Seam component that returns a list ( @Datamodel
) of elements that I want to convert to a set of <li>
HTML elements . It works for me without problems.
But now I want to split the list according to EL expression. Thus, the EL expression determines whether to start a new element <ul>
. I tried the following:
<s:fragment rendered="#{action.isNewList(index)}">
<ul>
</s:fragment>
<!-- stuff that does the <li> goes here -->
<s:fragment rendered="#{action.isNewList(index)}">
</ul>
</s:fragment>
But this is not true because the nesting for <ul>
is wrong.
How should I do it?
You can do it with a JSF tag <f:verbatim>
, which is not very good but works:
<f:verbatim rendered="#{action.isNewList(index)}">
<ul>
</f:verbatim>
<!-- stuff that does the <li> goes here -->
<f:verbatim rendered="#{action.isNewList(index)}">
</ul>
</f:verbatim>
I am not familiar with the Seam Framework, but if I understood the problem correctly, it might work.
<!-- before your loop, open your first <ul> if the (@Datamodel) is not empty -->
<s:fragment rendered="#{action.isNewList(index)}">
</ul>
<ul>
</s:fragment>
<!-- stuff that does the <li> goes here -->
<!-- after your loop, close your last </ul> if the (@Datamodel) is not empty -->
I'm not familiar with Seam specifically, but I've seen this same issue occur when working with XSLT and other XML-based frameworks.
Typically, there are two solutions:
- Reimagine your page and data architecture so that the entire list is written based on one condition. This may require a loop inside the s: fragment.
- Wrap the offending invalid html snippet in <! [CDATA [...]]>
You should have something like this (I will use pseudocode):
<ul>
<s:for items="itemList" ...>
<s:fragment rendered="#{action.isNewList(index) && index > 0}">
</ul>
<ul>
</s:fragment>
<li>
<!-- stuff that does the <li> goes here -->
</li>
</s:for>
</ul>