Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using lazy dataTable another component does not get updated / 2nd component data is one request behind

I have a PrimeFaces p:dataTable and enabled lazy loading by implementing a LazyDataModel.

The dataTable holds search results, so when doing a search request the search service only retrieves the required (paginating) data. That works fine.

When doing a ajax request with p:commandButton:

<p:commandButton id="searchCmdBtn" value="Search" action="#{searchBean.search}" 
   update=":resultForm:resultList :filterForm:filterMenu :resultForm:messages" 
   ajax="true" />

the dataTable gets updated properly, but not the filterMenu in the filterForm (differnt forms, bcz using p:layout).

The filterMenu is one request behind. Which means when I hit search button again, the filterMenu gets updated with t only gets updated after the 2nd ajax request

Bean

@ManagedBean
@ViewScoped
public class SearchBean implements Serializable {

    private LazyDataModel<Entity> lazyDataModel;
    private MenuModel filterMenuModel = new DefaultMenuModel();
    private SearchResult searchResult = null;

    public void search() {   
        // lazy call
        getLazyDataModel();
        if (searchResult != null) {
            buildFilterMenu(searchResult);
        }
    }

    private void initializeDataModel() {

        lazyDataModel = new LazyDataModel<Entity>() {

            private static final long serialVersionUID = 1L;

            @Override
            public List<Entity> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, String> filters) {

                // handling sorting and filtering

                // get search results
                try {
                    setSearchResult(searchService.getEntities(queryText, selectedQueryOperand, getFilterOptions(), first, (first + pageSize), multiSortMeta));
                } catch (Exception e) {
                    // handle exception
                }
                if (searchResult == null) {
                    return null;
                }
                List<Entity> resultEntities = searchResult.getResultEntities();
                // total count
                this.setRowCount((int) searchResult.getTotalSize());
                return resultEntities;
            }

        // other override-methods     
        };
    }

    public void buildFilterMenu() {
        // builds the filterMenu depending on searchResults
    }


    // getters and setters

    public LazyDataModel<Entity> getLazyDataModel() {
        if (lazyDataModel == null) {
            initializeDataModel();
        }
        return lazyDataModel;
    }

}

filters.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions">

    <p:panelMenu id="filterMenu" model="#{searchBean.filterMenuModel}" />

</ui:composition>
like image 971
jimmybondy Avatar asked May 17 '13 18:05

jimmybondy


1 Answers

After searching the PF forum I found the root cause:

The dataTable Lazy load() method is invoked during render response phase

To know about the phases, read this tutorial on JSF lifecycle from BalusC

Solutions for displaying messages (e.g: p:messages or p:growl):

  1. Update message component with PrimeFaces RequestContext

    RequestContext.getCurrentInstance().update(":growlOrMsgID");
    

    This will not work because at that time it's too late to add additional components to update.

  2. use dataTable attribute errorMessage

    No attribute found with this name for dataTable

  3. Put the p:messages or p:growl below the p:dataTable

    Worked for me

  4. Use PF execute method of RequestContext

    The RequestContext#execute() executes a javascript after current ajax request is completed.

    Worked for me


See also:

  • Request update of component with ajax from LazyDataModel.load?
  • How to handle error in Primefaces lazy load?
  • PF Issue: DataTable with LazyDataModel updates model during render
  • http://itaffinity.wordpress.com/2013/06/08/jsf-displaying-facesmessages-during-render-response-phase/
like image 60
jimmybondy Avatar answered Nov 15 '22 10:11

jimmybondy