Hello to everybody,
I have a page with two dataTables. They have the same structure but only the data source (value) is different.
My question: I would like to implement the possibility to filter both tables at the same time. F.ex.: I have the column 'name' in both tables, so when I do the filtering on the first dataTable it should filter the second one too.
Is there any way to realize that??
Thank you in advance
Roman
Hello Roman,
You can consider the following two approaches to implement simultaneous filtering of two tables.
The first approach can be used if the layout of your page allows the second table to be placed in the "below" (or "above") facet of the first table. In this case you can set up filtering for both tables and bind the filterValue attribute of analogous columns from two tables to the same shared values. As a result, filtering a column in the first table will make the appropriate filterValue to be used by both tables, and the second table will be reloaded by any filtering action because it is located in the first table's "below" facet. The only additional thing that you will need to do in this approach is hide the filtering row in the second table to avoid specifying conflicting filter values for the same column. Here's an example that briefly outlines this approach:
<q:dataTable id="firstTable" value="#{DataBean.firstDataSet}" var="row">
<q:column filterKind="searchField" filterExpression="#{row.col1}" filterValue="#{DataBean.col1FilterValue}">...<q:column>
<q:column filterKind="searchField" filterExpression="#{row.col2}" filterValue="#{DataBean.col2FilterValue}">...<q:column>
...
<f:facet name="below">
<q:dataTable id="secondTable" value="#{DataBean.secondDataSet}" var="row">
<q:column filterKind="searchField" filterExpression="#{row.col1}" filterValue="#{DataBean.col1FilterValue}">...<q:column>
<q:column filterKind="searchField" filterExpression="#{row.col2}" filterValue="#{DataBean.col2FilterValue}">...<q:column>
...
</q:dataTable>
</f:facet>
</q:dataTable>
The second approach is to use manual filtering and Ajax4jsf for reloading both tables at once. This approach can be used if it's not possible to place one table inside of the "below" or "above" facet of another one. In this case you will need to place the filtering parameter components outside of both tables, with the "search" button having to submit these parameters and reload the two tables according to these parameters. Note that you can still utilize the filtering capabilities of the tables by providing the filtering parameters throught the filterValue attributes and hiding the filtering rows to disable inplace filtering (similarly to the way it is done for the second table in the first approach).
Feel free to ask if you have any questions.
Regards,
Dmitry
Hello Dmitry,
thanks for the fast reply! I tried to realize the first approach, but which data-type is required for the object of the filterValue in my backingBean??
I tried String, but then I've got a JSF-Rendering-Error. So i took the FilterValueBinding object and the rendering was ok, but now on filtering I get a " javax.el.ELException: java.lang.IllegalArgumentException: argument type mismatch" Exception.
Do you have any suggestion??
Thanks
Roman
Roman,
The set of actual classes whose instances are allowed in the filterValue attribute depends on the kind of filter that you use for the appropriate column -- see the Filtering section in DataTable documentation and the Tag Reference. Though it's always safe to declare the binding to have a common base class for all of them, that is the teamdev.jsf.component.datatable.ColumnFilterCriterion class.
Regards,
Dmitry
Hello Dmitry,
now I've chosen the second possibility you gave me, because I need the facet below... The columns I would like to filter in both dataTables are strings. So I have two dataTables in one page and outside I have three input fields with a submit button.
On submit the values of my input fields were written down in my backing bean where the objects of the variables are of the type 'TextFilterCriterion'. On the columns, which should be filtered, I put the filterValue attribute with reference to the related 'TextFilterCriterion' object of my backing bean.
Maybe I do something wrong, because on submit i get a IllegalArgumentException and the input fields become red...
Here some pieces of my code:
.jsp File
<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:q="http://teamdev.com/quipukit"
xmlns:authz="http://acegisecurity.org/authz">
<h:form id="form1" rendered="#{interfaceTicketController.systemOk}">
<h:panelGrid border="0" columns="2" style="width:800px;margin-left:auto;margin-right:auto;vertical-align:top" >
<h:outputText value="Stamm-Nr."/>
<q:suggestionField value="#{interfaceTicketController.filterCustomerNo}"> *<----INPUT FIELDS*
<q:dropDownItems value="#{interfaceTicketController.suggestCustomerNo}"/>
</q:suggestionField>
<h:outputText value="Vorname"/>
<q:suggestionField value="#{interfaceTicketController.filterFirstName}">
<q:dropDownItems value="#{interfaceTicketController.suggestFirstName}"/>
</q:suggestionField>
<h:outputText value="Nachname"/>
<q:suggestionField value="#{interfaceTicketController.filterLastName}">
<q:dropDownItems value="#{interfaceTicketController.suggestLastName}"/>
</q:suggestionField>
<h:outputText value=""/>
<h:commandButton value="Suche" type="submit" />
</h:panelGrid>
<q:dataTable value="#{interfaceTicketController.itrexsClients}" rolloverRowStyle="background-color:#E0E0E0;" <----DATA TABLE 1
var="row" pageSize="#{pager.pageSize5}" border="1" cellpadding="5" cellspacing="0" binding="#{interfaceTicketController.tbl}"
style='border-collapse:collapse;'>
<f:facet name="noDataMessage">
<f:verbatim>Keine Daten gefunden!</f:verbatim>
</f:facet>
<f:facet name="noFilterDataMessage">
<f:verbatim>Keine Daten mit Ihren Filterangaben gefunden!</f:verbatim>
</f:facet>
<f:facet name="footer">
<h:outputText value="Anzahl Zeilen gesamt: #{interfaceTicketController.rowCount}"/>
</f:facet>
<f:facet name="below">
<q:dataTablePaginator style="margin-left:auto;margin-right:auto;margin-top:5px;" showIfOnePage="true" pageCountPreposition="von" pageNumberPrefix="Seite" />
</f:facet>
<q:column filterExpression="#{row.stammnummer}" filterValue="#{interfaceTicketController.filterCustomerNo}" sortingComparator="caseInsensitiveText" sortingExpression="#{row.stammnummer}" > <----COLUMN I WOULD LIKE TO FILTER
<f:facet name="header">
<h:outputText value="Stamm-Nr." />
</f:facet>
<h:outputText value="#{row.stammnummer}"></h:outputText>
</q:column>
<q:dataTable value="#{interfaceTicketController.localClients}" rolloverRowStyle="background-color:#E0E0E0;" *<----DATA TABLE 2*
var="row" pageSize="#{pager.pageSize5}" border="1" cellpadding="5" cellspacing="0" binding="#{interfaceTicketController.tbl2}"
style='border-collapse:collapse;'>
<f:facet name="noDataMessage">
<f:verbatim>Keine Daten gefunden!</f:verbatim>
</f:facet>
<f:facet name="noFilterDataMessage">
<f:verbatim>Keine Daten mit Ihren Filterangaben gefunden!</f:verbatim>
</f:facet>
<f:facet name="footer">
<h:outputText value="Anzahl Zeilen gesamt: #{interfaceTicketController.rowCount2}"/>
</f:facet>
<f:facet name="below">
<q:dataTablePaginator style="margin-left:auto;margin-right:auto;margin-top:5px;" showIfOnePage="true" pageCountPreposition="von" pageNumberPrefix="Seite" />
</f:facet>
<q:column filterExpression="#{row.customerNo}" filterValue="#{interfaceTicketController.filterCustomerNo}" sortingExpression="#{row.customerNo}" > *<----COLUMN I WOULD LIKE TO FILTER*
<f:facet name="header">
<h:outputText value="Stamm-Nr." />
</f:facet>
<h:outputText value="#{row.customerNo}"></h:outputText>
</q:column>
backing bean:
public void setFilterCustomerNo(TextFilterCriterion filterCustomerNo) {
this.filterCustomerNo = filterCustomerNo;
}
public TextFilterCriterion getFilterFirstName() {
return filterFirstName;
}
public void setFilterFirstName(TextFilterCriterion filterFirstName) {
this.filterFirstName = filterFirstName;
}
public TextFilterCriterion getFilterLastName() {
return filterLastName;
}
public void setFilterLastName(TextFilterCriterion filterLastName) {
this.filterLastName = filterLastName;
}
Thank you
Roman
Hello,
now I've found a solution... In my backing bean I've bound my search fields to strings and in the setter methods of the string variables I call the referencing setter of the 'TextFilterCriterion' objects which are bound to the filter-value attribute of the filtered columns. As parameter for the setter I create a new TextFilterCriterion object with the string value as parameter for the constructor.
That works fine.
Thank you Dmitry for your support
Roman