0
votes

I am building a single page application with Primefaces 6.1, JSF 2.2 and running it on Wildfly, which has an option to search for users. Initial view renders only search panel with various filters and on click of search, user table will be queried and set of data is returned and then a block is rendered in the view which contains datatable. Below is the lazyloading code for search users.

public void getUsers(ActionEvent event) {
    //few lines to get filterData
    this.lazyUsers = new LazyDataModel<UserModel>() {
        private static final long serialVersionUID = 1L;
        @Override
        public List<UserModel> load(int first, int pageSize, String sortField, SortOrder sortOrder,
                        Map<String, Object> filters) {

            filterObject.setStartCount(new Long(first));
            filterObject.setCountPerPage(new Long(pageSize));
            List<UserModel> list = userService.getUsers(filterObject);
            if (list != null)
                this.setRowCount(list.get(0).getTotalNumberOfRecords().intValue());
            RequestContext context = RequestContext.getCurrentInstance(); 
            if(context!=null)
                context.addCallbackParam("totalRecords", this.getRowCount());
            return list;
        }
    };
}

and here's my table view.

<p:outputPanel id="users" autoUpdate="true">
    <p:outputPanel rendered="#{users.displayusers}">
        <h5 class="title">
            <h:outputText value="#{msg.header_title}"></h:outputText>
        </h5>
        <p:dataTable id="userTable" lazy="true" paginator="true"
            rows="2"
            emptyMessage="#{msg.emtpymsg}"
            paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
            rowsPerPageTemplate="2,4,5"
            rendered="#{null != users.lazyUsers &amp;&amp; not empty users.lazyUsers }"
            value="#{users.lazyUsers}" var="user"
            rowIndexVar="userRow">
            <p:column headerText="#{msg.Name}">
                <h:outputLabel class="tdRow" value="#{user.name}" />
            </p:column>
            <p:column headerText="#{msg.Phone}">
                <h:outputLabel class="tdRow" value="#{user.phone}" />
            </p:commandLink>
            </p:column>
            <p:column headerText="#{msg.Address}">
                <h:outputLabel class="tdRow" value="#{user.address}" />
            </p:column>
            <p:column headerText="#{msg.Email}">
                <h:outputLabel class="tdRow" value="#{user.email}" />
            </p:column>
        </p:dataTable>
    </p:outputPanel>
</p:outputPanel>

Everything renders when search happens but then when I paginate it searches for the next page data, and gets the next page data, but it renders it as plain html removing the datatable. On inspection of html, I can only see tr,td as response from server in network tab, and only contents within it are rendered directly into div. The datatable is not preserverd. Could anyone please let me know what's happening here.

I also tried to capture page event within datatable and added update value as

<p:ajax event="page" update="userContainer:userTable"></p:ajax>

but again it did not help. Hope to find some help.

Update

I noticed, this happens for any ajax operation through datatables, like, filtering, sorting, rowsperpage changed etc., Is there any way to identify on exactly what's wrong with this?

2
Possible duplicate of Primefaces Datatable display bugKukeltje
@Kukeltje Even though the problem was somewhat similar to him the solution was to use process in pagination ajax rather than update. I have updated my question and added an answer for the same. Thank you.. :)Guruprasad J Rao

2 Answers

0
votes

You change the value of rendered attribute. Try to encapsulate the dataTable ino another component, and re-render this outer component.

Also could be helpful if you place a dummy table in the template, that is always rendered, EG:

<p:dataTable disabled="true" />

This will make sure all the dataTable needed libraries are loaded at first load of your page...

0
votes

The solution for this problem was very simple infact.

I had to keep <p:ajax event="page" update="userContainer:userTable"></p:ajax> and rather than update, I had to use process and also with ignoreAutoUpdate="true"

<p:ajax event="page" ignoreAutoUpdate="true" process="userContainer:userTable"></p:ajax>

That fixed the issue. Hope this will be useful to someone in future.