简体   繁体   中英

JSF view calculations

I know that with JSF 2, facelets is the preferred view declaration language.

Is JSP to jsf deprecated?

Anyway, I need to create a special layout so I cannot use Datatable. Instead, I have 6 divs that I use as columns in which I drop a collection of Articles. My problem is that I have a JSF composite component, that is injected with a Collection A:

List<Article>

object.

The component then needs to divide the size of the collection into equal pieces for each column. Then set the appropiate offset and size for each

<ui:repeat></ui:repeat> 

so i end up with this

<!-- INTERFACE -->
<cc:interface>
    <cc:attribute name="featuredArticles" required="true" type="java.util.List;" />
</cc:interface>

<!-- IMPLEMENTATION -->
  <cc:implementation>
    <div class="col">
       <ui:repeat value="#{cc.attrs.featuredArticles}" var="art" offset="??" size="??">
            <mycomps:article art="#{art}" />
       </ui:repeat>
    </div>
    <div class="col">
       <ui:repeat value="#{cc.attrs.featuredArticles}" var="art" offset="??" size="??">
            <mycomps:article art="#{art}" />
       </ui:repeat>
    </div>
    <div class="col">
       <ui:repeat value="#{cc.attrs.featuredArticles}" var="art" offset="??" size="??">
            <mycomps:article art="#{art}" />
       </ui:repeat>
    </div>
    <div class="col">
       ...same here...
    </div>
    <div class="col">
       ...same here...
    </div>
</cc:implementation>

So how do I calculate those offsets and sizes so that each columns iterates over a portion of the collection? Or maybe there's a better way?

You can get collection's size with fn:length and there are basic arithmetic operators in EL.

<ui:composition xmlns:fn="http://java.sun.com/jsp/jstl/core">
    ...
    <ui:param name="size" value="#{fn:length(featuredArticles) / 6}" />
    ...
    <ui:repeat size="#{size}">
    ...
</ui:composition>

Update : as to the rounding, that get tricky. In old JSP you could use JSTL <fmt:formatNumber> for this which can export to a var attribute instead of displaying it straight in the view.

<fmt:formatNumber var="size" value="${fn:length(featuredArticles) / 6}" pattern="0" />

But the JSTL fmt is not available in Facelets.

A hacky way would be to split the fractions using fn:substringBefore .

<ui:param name="size" value="#{fn:substringBefore(fn:length(featuredArticles) / 6, '.')}" />

But this always rounds down.

The best way would be to create a custom EL function. You can find an example in this answer . For JSF 2.0 you only need to replace the deprecated <param-name>facelets.LIBRARIES</param-name> by <param-name>javax.faces.FACELETS_LIBRARIES</param-name> . Finally you'll end up like as:

<ui:param name="size" value="#{x:roundUp(fn:length(featuredArticles) / 6)}" />

As a completely different alternative, you could also do this job in the constructor, init or getter of a managed bean.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM