问题
Given a collection that I want to arrange on a page like this:
<!-- Group 0 -->
<div style="float:left;">
<div><!-- Item 0 --></div>
<div><!-- Item 1 --></div>
<!-- ... -->
<div><! -- Item n - 1 --></div>
</div>
<!-- Group 1 -->
<div style="float:left;">
<div><!-- Item n --></div>
<div><!-- Item n + 1 --></div>
<!-- ... -->
<div><! -- Item 2n - 1 --></div>
</div>
<!-- ... -->
<!-- Group g -->
<div><!-- Item gn --></div>
<div><!-- Item gn + 1 --></div>
<!-- ... -->
<div><! -- Item (g + 1)n - 1 --></div>
</div>
Is there some sort of trick I can use to do this inside a ui:repeat or by some other technique, preferably other than creating a custom component?
回答1:
You can check the current loop round by the varStatus
attribute and print the intermediary </div><div style="float: left;">
whenever necessary.
E.g. every 3 items:
<div style="float: left;">
<ui:repeat value="#{bean.list}" var="item" varStatus="loop">
<h:outputText value="</div><div style='float: left;'>" escape="false" rendered="#{not loop.first and loop.index % 3 == 0}" />
<div>#{item}</div>
</ui:repeat>
</div>
Note that it's not possible to wrap this as plain HTML inside a <h:panelGroup>
, because it would result in non-wellformed XML, hence the <h:outputText escape="false">
with them as XML entities.
Update as per the comments, here's an alternate approach having the <div>
s definied only once which is probably less confusing:
<ui:repeat value="#{bean.list}" var="item" varStatus="loop">
<h:outputText value="<div style='float: left;'>" escape="false" rendered="#{loop.index % 3 == 0}" />
<div>#{item}</div>
<h:outputText value="</div>" escape="false" rendered="#{loop.last or (loop.index + 1) % 3 == 0}" />
</ui:repeat>
回答2:
If possible I would break collection on the server side:
<ui:repeat value="#{groups}" var="group">
<div style="float:left;">
<ui:repeat value="#{group.items}" var="item">
<div>#{item.content}</div>
</ui:repeat>
</div>
</ui:repeat>
another option could be (haven't tested, not sure about size behaviour in particular):
<ui:repeat value="#{items}" var="group" varStatus="status" step="n">
<div style="float:left;">
<ui:repeat value="#{items}" var="item" offset="#{status.index}" size="#{status.index + n}">
<div>#{item.content}</div>
</ui:repeat>
</div>
</ui:repeat>
EDIT: the second version has been replaced
来源:https://stackoverflow.com/questions/10481742/jsf-2-uirepeat-group-every-n-items-inside-a-div