Is there a JSF2 component that can handle Ajax based pagination by adding/removing components?

StackOverflow https://stackoverflow.com/questions/15323294

  •  21-03-2022
  •  | 
  •  

Question

The use case is the following: I would like to render 10 new rows per click, but without rendering the previous rows. So in theory, what I would like it to have a component that always renders an extra panelgroup that references my next 10 rows (which are empty). When the user clicks, I would like only this panelgroup to be re-rendered without its ID and a new empty one added to the bottom with that ID.

Is there an out of the box JSF tag that can handle this or I should dive directly into custom tags/renderers?

Based on my tests, UI:repeat will always loop through the whole list and I couldn't manage to do a partial update (render) within the tag.From what I can tell it doesn't support partial rendering within the tag.

I wouldn't like to add further frameworks like Rich/Primefaces/tomahawk.

I am using the latest Mojarra.

Was it helpful?

Solution

I don't know of any out-of-the-box component in JSF capable of doing your task, but I can think of a possible workaround.

Essentially, you can have an empty placeholder with a predefined id, have it be populated via an AJAX call of <h:commandButton> and when the HTML DOM is updated afterwards, move the contents via javascript. One note: when you assign ids to your JSF components, beware of using this approach with naming containers, like <h:dataTable>, or <ui:repeat>, as they control identifiers of their children. Finally, it leaves you only with the style class defined in your elements. Basic example goes below.

The view:

<h:form id="form">
    <h:panelGroup id="basic">
        <ul class="basic-list">
            <ui:repeat var="data" value="#{bean.basicList}">
                <li class="data-class">#{data.value}</li>
            <ui:repeat>
        </ul>
    <h:panelGroup>
    <h:panelGroup id="additional">
        <ul class="additional-list">
            <ui:repeat var="data" value="#{bean.additionalList}">
                <li class="data-class">#{data.value}</li>
            <ui:repeat>
        </ul>
    <h:panelGroup>
    <h:commandButton value="Load 10 more rows">
        <f:ajax render="additional" onevent="replaceData" listener="#{bean.loadAdditionalData}"/>
    </h:commandButton>
</h:form>

The bean:

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    private List<Data> basicList;//getter+setter
    private List<Data> additionalList;//getter+setter

    @PostConstruct
    public void init() {
        basicList = new ArrayList<Data>();//populate first rows of data from somewhere
    }

    public void loadAdditionalData(AjaxBehaviorEvent event) {
        additionalList = new ArrayList<Data>();//populate additional rows of data from somewhere
        basicList.addAll(additionalList);//just for a possible postback
    }

}

The JavaScript:

function replaceData(data) {
    if(data.status == 'success') {
        var toAppend = $('#additional-list').html();
        $('#basic-list').append(toAppend);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top