Search code examples
ajaxjsfopenfaces

Filter for several open Faces datatables


I have 3 openFaces <o:datatable />s in the same view page (overview.xhtml).

  • The first displays a list of all music bands
  • The 2d displays a list of all songs written by music bands
  • The 3d displays a list of all shows given by music bands

I am using <o:inputTextFilter /> to filter the first datatable using the row ID (

<h:form>
        <o:datatable value="#{bandBean.items}" var="band" ........<o:inputTextFilter 
        expression="#{band.id}" .../> 
</h:form>

<h:form>    
    <o:datatable value="#{showBean.items}" var="show" ........<o:inputTextFilter 
        expression="#{band.id}" .../> 
</h:form>
    <h:form>
    <o:datatable value="#{songBean.items}" var="song" ........<o:inputTextFilter 
        expression="#{band.id}" .../> 
</h:form>

The songs and the shows are child objects of music bands. What I really need is the ability to filter the 3 datatables using the same inputTextFilter or something similar, since the 3 datatables have each a column with the band ID.

The user will never accept typing the band id three times, first tilme for the BAND table, second time for the shows table and the third time for the song table, using 3 filters. Instead he wants to type once the band ID , and instantly the 3 tables get filtered.

One workaround would be to use three <o:inputTextFilter /> and set their values using javascript or ajax : while the user types something in a filter, the value being typed is appended immediately to the other filters. I can't figure that workaround. yet it seems to be odd to display 3 filters while the user should use only one. Any ideas and help will be precious!


Solution

  • There's no direct support for attaching a filter to several tables, however you can simulate this behavior. To so this, you can attach a hidden ("display: none") to each of your tables using the "for" attribute, and specify the filtering value for all of them programmatically.

    Here's a simple code snippet which demonstrate this idea:

    <o:inputText value="#{MyBean.filterText}"/> 
    <o:commandButton value="Submit" action="#{MyBean.filterAllTables}"/> 
    <o:inputTextFilter for="table1" expression="#{book.bookTitle}" 
                       value="#{MyBean.filterCriterion}" style="display: none"/> 
    <o:inputTextFilter for="table2" expression="#{book.bookTitle}" 
                       value="#{MyBean.filterCriterion}" style="display: none"/> 
    <o:dataTable id="table1" ...> 
    <o:dataTable id="table2" ...> 
    

    MyBean.java:

    private String filterText; // a property w/ getter/setter 
    private ExpressionFilterCriterion filterCriterion; // a property w/ getter/setter 
    
    public void filterTables() { 
        String filterText = getFilterText(); 
        SimplePropertyLocatorFactory.SimplePropertyLocator propertyLocator =
                    new SimplePropertyLocatorFactory.SimplePropertyLocator("id"); // "id" is a property name by which you'd like to filter
        ExpressionFilterCriterion filterCriterion = new ExpressionFilterCriterion(
                    propertyLocator, FilterCondition.CONTAINS, filterText); 
        setFiterCriterion(filterCriterion); 
    }