Feature Request: Control over p:dataTable's state

UI Components for JSF
bchen
Posts: 4
Joined: 18 May 2012, 15:49

04 Dec 2012, 21:43

While it is very useful for p:dataTable to operate over ajax, sometimes I would like to programmatically control the state of p:dataTable. For example, I want p:dataTable to remember the filter or sorting parameters I specified before I refreshed the page. It would be great if there are attributes on the p:dataTable tag that can be used to control various parameters of its behaviour.

For now, I have created a workaround to achieve this. It is not an optimal solution, as it hacks into the internals of PrimeFaces and requires a filter to be installed. Therefore, I would like to see if PrimeFaces can enable an easy way to make it happen.

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

04 Dec 2012, 22:13

Is the filter needed if you use something like cdi to get the params in directly?

I have plans using you persistent state in combination with my jpa datamodel, but currently have no time to experiment with the possibility of using cdi.

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

04 Dec 2012, 22:21


cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

04 Dec 2012, 23:28

I have done it for a client during consulting a PrimeFaces PRO user so it is possible already much easier than the posted workaround.

bchen
Posts: 4
Joined: 18 May 2012, 15:49

05 Dec 2012, 08:06

@cagatay Good to know. Thanks for your response. I will keep investigating the way to do it without the workaround.

@kukeltje Sorry but I'm not familiar with CDI. Since a way to do it without using the workaround exists, there may after all be no need to use the filter.

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

05 Dec 2012, 09:59

Tip: There is a filterValue option in column.

purix
Posts: 17
Joined: 22 Nov 2012, 22:37

11 Dec 2012, 11:10

I can't find the filterValue option inside p:column. I'm using PF 3.4.2.
Am i missing something ?

smithh032772
Posts: 6144
Joined: 10 Sep 2011, 21:10

12 Jan 2013, 16:30

purix wrote:I can't find the filterValue option inside p:column. I'm using PF 3.4.2.
Am i missing something ?
Right now, I am using 3.5-SNAPSHOT, and I see filterValue in the following:

PrimeFaces 3.5-SNAPSHOT JAR
org.primefaces.component.column
Column.class

Maybe you should review how filterValue is used throughout the entire PrimeFaces (sources) JAR.
kukeltje wrote:Is the filter needed if you use something like cdi to get the params in directly?

but currently have no time to experiment with the possibility of using cdi.
Ronald, I hope you will have time to experiment with CDI. :)
Howard

PrimeFaces 6.0, Extensions 6.0.0, Push (Atmosphere 2.4.0)
TomEE+ 1.7.4 (Tomcat 7.0.68), MyFaces Core 2.2.9, JDK8
JUEL 2.2.7 | OmniFaces | EclipseLink-JPA/Derby | Chrome

Java EE 6 Tutorial|NetBeans|Google|Stackoverflow|PrimeFaces|Apache

sedekpav
Posts: 4
Joined: 23 Jan 2012, 18:24

27 Feb 2015, 23:44

Achieved this using filterValue and filteredValue as Cagatay mentioned. This solution keeps current page, row count, sorting and filtering state in the session.

index.xhtml

Code: Select all

<p:dataTable 
	value="#{usersBean.employees}" 
	var="e"
	rows="#{userListState.rows}" 
	rowsPerPageTemplate="10,20,50,100"  
	first="#{userListState.page}"
	binding="#{userListState.datatable}" 
	id="dt" 
	filteredValue="#{userListState.filteredValue}"
	>
	
	<p:ajax event="page" listener="#{userListState.onPageChange}"/>
	<p:ajax event="sort" listener="#{userListState.onSortChange}"/>
	<p:ajax event="filter" listener="#{userListState.onFilterChange}"/>
	
	<p:column 
		headerText="user" 
		sortBy="#{e.user.id}" 
		sortFunction="#{list.sortByString}" 
		filterBy="#{e.user.id}" 
		filterValue="#{userListState.filterState('user.id')}">
		
		<h:link outcome="employee.xhtml" value="#{e.user.id}" >
			<f:param name="id" value="#{e.id}" />
		</h:link>
		
	</p:column>
	
	<p:column
		sortBy="#{e.user.name}" 
		sortFunction="#{list.sortByString}" 
		filterBy="#{e.user.name}" 
		filterValue="#{userListState.filterState('user.name')}" 
		filterMatchMode="contains">
		#{e.user.name}
	</p:column>
</p:dataTable>
UserListState.java

Code: Select all

@Named(value = "userListState")
@SessionScoped
public class UserListState implements Serializable{

	private int page = 0;
	private int rows = 500;
	private String sortBy;
	private String sortFunction;
	private String sortOrder;
	private DataTable datatable;
	private Map<String, String> filterState = new HashMap<String, String>();
	private List<Employee> filteredValue;

	/**
	 * Creates a new instance of NewsListState
	 */
	public UserListState() {
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public String getSortBy() {
		return sortBy;
	}

	public void setSortBy(String sortBy) {
	}

	public DataTable getDatatable() {
		return null;
	}

	public void setDatatable(DataTable datatable) {
		ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
		ELContext elContext = FacesContext.getCurrentInstance().getELContext();
		if (datatable.getSortBy() == null && sortBy != null) {
			datatable.setValueExpression("sortBy", expressionFactory.createValueExpression(elContext, sortBy, Object.class));
			if (sortFunction != null) {
				datatable.setSortFunction(expressionFactory.createMethodExpression(elContext, sortFunction, Integer.TYPE, new Class[]{Object.class, Object.class}));
			}
			if (sortOrder != null) {
				datatable.setSortOrder(sortOrder);
			}
		}

		this.datatable = datatable;
	}

	public void onPageChange(PageEvent event) {
		this.setPage(((DataTable) event.getSource()).getFirst());
	}

	public void onSortChange(SortEvent event) {
		sortBy = (event.getSortColumn().getValueExpression("sortBy").getExpressionString());
		sortFunction = (event.getSortColumn().getSortFunction().getExpressionString());
		sortOrder = (event.isAscending() ? "ASCENDING" : "DESCENDING");
	}

	public void onFilterChange(FilterEvent filterEvent) {
		filterState = filterEvent.getFilters();
		filteredValue =(List<Employee>) filterEvent.getData();
	}

	public String filterState(String column) {
		return filterState.get(column);
	}

	public List<Employee> getFilteredValue() {
		return filteredValue;
	}

	public void setFilteredValue(List<Employee> filteredValue) {
		this.filteredValue = filteredValue;
	}
}

Pollum
Posts: 6
Joined: 16 Nov 2015, 16:22

25 Feb 2016, 17:04

Hi,

the solution posted by sedekpav works for me. Big thanks!

For clarification I have got a following question. In this solution the datatable is bound to a property in the @SessionScoped Bean. While having another problem I stubmled over an stackoverflow answer which states that
the backing bean [which helds a bound property] should absolutely not be in a broader scope than the request scope
.
How does the 'binding' attribute work in JSF? When and how should it be used?

Does this quoted statement apply to the solution posted above, so that in a future moment my application possibly stops working because of this and I am searching like a year or so for the mistake? Or is it safe to use the above solution and the possible thread-safety problems mentioned can not occur because of ... (fill in the correct answer; I have no clue)?

Does anyone have an insight on this?
Primefaces 6.0 | JSF 2.2 Mojarra | Glassfish 4.0

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: Google [Bot] and 14 guests