limit number of iterations in ui:repeat
Asked Answered
C

2

5

We have a JSF page that displays a table with query results. We want to show just the top 3 results.

How can this be done using <ui:repeat>?

We can't do this in the business layer, because it is not under our control. We need to cap the results to 3 in view side.

Currin answered 2/12, 2013 at 9:52 Comment(1)
I'm confused. Are you using ui:repeat or h:dataTable for the output?Thermoluminescence
D
8

You can follow the way kocko proposes in his answer, but certainly it's quite excessive to iterate through the whole list to output only three components.

The necessity of such verbose approach is dictated by the fact that size attribute of <ui:repeat> component doesn't for some reason allow to specify EL as its value but rather plain integer like 3. See also Jsf ui:repeat size doesn't gets java bean value.

If you know that only 3 values are needed you can use the size attribute:

<ui:repeat var="var" value="#{bean.list}" size="3">
    <h:outputText value="#{var}" />
</ui:repeat>

Alternatively, if you are on EL2.2+ you can get a sublist by calling List#subList(from, to) method:

<ui:repeat var="var" value="#{bean.list.subList(0, (bean.list.size() gt 3) ? 3 : bean.list.size())}">
    <h:outputText value="#{var}" />
</ui:repeat>
Delogu answered 2/12, 2013 at 10:31 Comment(2)
It'd be voting for the size option, but that produces an error if the list ever contains less than 3 elements.Thermoluminescence
@Thermoluminescence That's true, but both empty list and other size assertions should be done beforehand, i.e. inside some conditionally rendered component.Delogu
P
2

You can do the following:

  1. Register a <ui:param> which will hold the limit of the displayed result. In your case it will be 3.
  2. Use the <ui:repeat>'s varStatus property and it's internal index property which holds the index of the current collection item.

For example:

<ui:param name="limit" value="3"/>
<ui:repeat var="item" value="#{managedBean.list}" varStatus="status">
    <ui:fragment rendered="#{status.index lt limit}">
        <! -- place your value-holding-component here -->
    </ui:fragment>
</ui:repeat>

This way you will have only 3 components rendered by the <ui:repeat>.

Note that the rendered attribute was introduced to the <ui:fragment> in JSF 2.1. If your JSF version is older than 2.1, consider changind the <ui:fragment> with

<h:panelGroup rendered="#{status.index lt limit}">
    <! -- place your value-holding-component here -->
</h:panelGroup>
Pathless answered 2/12, 2013 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.