0
votes

I am working with Primefaces DataTable component. The user makes some city-district-service type choices before hitting the button and the datatable gets filled with the needed urban services (hospital, schools etc.), located at the needed spots of the city. The below code contains only the fetching button and the table itself.

When you fetch the first results you want, there isn't any problem. All is good, paginator works well. The problem starts when you filter the results by name. They actually get filtered very well too, BUT after a filtering is done; if you make other choices about the city, district or service and try fetching them; the columns of datatable gets filled with '| 0 | (empty) | (empty) |' rows (I guess its because the ID column is of type int and the other two are strings). Additional info: the number of the newly created empty rows are exactly equal to the former filter results.

I made the necessary debugging and found that at the backend everything is perfect. I get all my fetched objects. Actually when I type anything in the filter bar the new results become exposed too. It seems to be a problem totally in the client side rendering, though I couldn't find a way to solve it.

Any help would be greatly appreciated.

Update: After working on it for several more hours, I concluded that the reason might not be the filter but the paginator. Because when I turn off the paginator and get a full scrollable table, everything works perfectly well. Still not sure about the exact reason, so I edited the question subject according to that.

p.s: I'm using Primefaces 5.3, JSF 2.2 Mojarra, JDK 1.7, TomEE Plume

    <p:commandButton action="#{filterByLocation.fetchServicesByLocation}" id="elbuton" value="Fetch" icon="ui-icon-check" onclick="PF('servisWidget').clearFilters();" update="servisList" />

    <p:dataTable id="servisList" paginator="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" rows="10" var="loc" value="#{filterByLocation.finalResults}"
     widgetVar="servisWidget">
      <p:column headerText="ID">
        <h:outputText value="#{loc.id}" />
      </p:column>
      <p:column headerText="NAME" filterBy="#{loc.name}" filterFunction="#{filterByLocation.filterResults}">
        <h:outputText value="#{loc.name}" />
      </p:column>
      <p:column headerText="SERVICE NAME">
        <h:outputText value="#{loc.serviceName}" />
      </p:column>
    </p:dataTable>

My backing bean (getters/setters excluded for clarity):

@ManagedBean
@ViewScoped
public class FilterByLocation {

    private List<LocationEntity> cities;
    private List<LocationEntity> districtSelection;
    private List<LocationEntity> finalResults = new ArrayList<LocationEntity>();
    private List<Integer> selectedNodes = new ArrayList<Integer>();

    private String filterText;
    private String filterName; 
    private int city;
    private int district;

    public FilterByLocation() {
        setCities(LocationTreeDAO.fetchCities());
    }

    public void listDistricts() {
        setDistrictSelection(LocationTreeDAO.fetchDistricts(city));
    }

    public void selectNode(NodeSelectEvent node) {
        TreeNode treeNode = node.getTreeNode();
        LayerEntity layer = (LayerEntity) treeNode.getData();
        selectedNodes.add(Integer.valueOf(layer.getId()));
    }

    public void unselectNode(NodeUnselectEvent node) {
        TreeNode treeNode = node.getTreeNode();
        LayerEntity layer = (LayerEntity) treeNode.getData();
        selectedNodes.remove(Integer.valueOf(layer.getId()));
    }

    public void fetchServicesByLocation() {
        setFinalResults(LocationTreeDAO.fetchFilteredServices(getCity(), getDistrict(), getSelectedNodes(), getFinalResults()));
        setFilterText("");
    }


    public boolean filterResults(Object value, Object filter, Locale locale) {

        setFilterText((filter == null) ? null : filter.toString().trim());
        if (filterText == null || filterText.equals("")) {
            return true;
        }
        if (value == null) {
            return false;
        }
        String searched = value.toString().toUpperCase();
        filterText = filterText.toUpperCase();

        if (searched.contains(filterText)) {
            return true;
        } else {
            return false;
        }


    }

Two screenshots depicting the situation before after

1
Do you see any error messages on browser side?Paul Wasilewski
@PaulWasilewski not at all. no errors on browser side, nor on the server side. just brings me three columns without data (except they seem to have default values | 0 | (nothing | (nothing) | as I said. "nothing" is actually a blank, probably a "null" passed to the expected strings)patateskafa
What is the content of your filterFunction #{filterByLocation.filterResults}?Paul Wasilewski
added the backing beanpatateskafa
can you make an minimal reproducible example? See alsp stackoverflow.com/tags/jsf/info And is the commandButton relevant? Does it play a role? Try removing update="servisList".Kukeltje

1 Answers

1
votes

The filterFunction parameter of <p:column ... filterFunction="#{filterByLocation.filterResults}" ...> is not necessary.

  1. Change the statement to

<p:column headerText="NAME" filterBy="#{loc.name}" filterMatchMode="contains">

  1. Add a List for the filtered values

<p:dataTable ... filteredValue="#{filterByLocation.filteredResults} ...>

@ManagedBean
@ViewScoped
public class FilterByLocation {
    ...
    private List<LocationEntity> filteredResults;
    ...
}