Monday, March 23, 2015

Adding a date range filter to Primefaces 4 DataTable

This post is an addendum to this other post 

This is some sort of a hack, but it seems to work.

First, the xhtml

                    <f:facet name="header">

                        <p:outputLabel
                            for="from"
                            value="Filter from:" />
                        <p:calendar
                            id="from"
                            value="#{sitePasswordHistoryMB.filterFrom}"
                            pattern="MM/dd/yyyy HH:mm:ss">
                            <p:ajax
                                event="dateSelect"
                                listener="#{sitePasswordHistoryMB.handleUserFilterSelection}"
                                update=":am:pas" />
                        </p:calendar>


                        <p:outputLabel
                            for="to"
                            value="&#160;Filter until:" />
                        <p:calendar
                            id="to"
                            value="#{sitePasswordHistoryMB.filterTo}"
                            pattern="MM/dd/yyyy HH:mm:ss">
                            <p:ajax
                                event="dateSelect"
                                listener="#{sitePasswordHistoryMB.handleUserFilterSelection}"
                                update=":am:pas" />
                        </p:calendar>

                    </f:facet>


The Managed Bean

    private Date filterFrom;
    private Date filterTo;

    @PostConstruct
    public void init() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
       
        filterFrom = cal.getTime(); //yesterday
        filterTo = new Date(); //today
       
        refresh();
    }

    private void refresh() {
        try {
            this.model = new LazyDataModel<SitePasswordHistory>(){
                private static final long    serialVersionUID    = 1L;
                @Override
                public List<SitePasswordHistory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                   
                    filters.put("from", String.valueOf(filterFrom.getTime()));
                    filters.put("to", String.valueOf(filterTo.getTime()));
                   
                    List<SitePasswordHistory> result = sitePasswordHistoryEJB.getResultList(first, pageSize, sortField, sortOrder, filters);
                   
                    filters.put("from", String.valueOf(filterFrom.getTime()));
                    filters.put("to", String.valueOf(filterTo.getTime()));

                    model.setRowCount((int)sitePasswordHistoryEJB.count(filters));
                   
                    return result;
                }
            };
        } catch (Exception e) {
            jsfUtilEJB.addErrorMessage(e,"Could not list");
        }
    }


and down to the DAO

    public Collection<SitePasswordHistory> getAll(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
       
        Date from = null;
        if (filters != null && filters.get("from") != null) {
            from = new Date(Long.parseLong(filters.get("from")));
            filters.remove("from");
        }
       
        Date to = null;
        if (filters != null && filters.get("to") != null) {
            to = new Date(Long.parseLong(filters.get("to")));
            filters.remove("to");
        }
(...)


        Predicate filterCondition = cb.conjunction();
       
        if (from != null) {
            filterCondition = cb.and(filterCondition, cb.greaterThan(sitePasswordHistory.get(SitePasswordHistory_.ts), from));
        }
       
        if (to != null) {
            filterCondition = cb.and(filterCondition, cb.lessThan(sitePasswordHistory.get(SitePasswordHistory_.ts), to));
        }
       
        for (Map.Entry<String, String> filter : filters.entrySet()) {
(...)


I haven't tried yet, but I believe PrimeFaces 5 has a better support for these kind of filters, since the LazyDataModel API has been changed (thus making this post incompatible with the new API...) 

No comments:

Post a Comment