Hi all,
I have the following question: What is the best/intended way to store paging/sorting/filtering information for DataTable in the HTTP Session?
Basically I want to use DataTable + normal columns in View scope, then navigate away to another view. On return, I want to see the last used filters/paging/sorting.
What I have tried so far:
[1] Tried to find some useful DataTable attributes, which can be bound to a session-scoped bean with appropriate EL. I think this works for Paging. I could not get Sorting/Filtering to work. sortBy for table/columns is meant to designate EL that operates on the table row variable, I think. filterBy for columns seems to follow the same approach. filterValue - not sure what this does.
[2] Thought about extending Features - could not find a way to do it Feature registry is static with default access. Moreover, copying the entire DataTable class is no good, because e.g. the Features use DataTable in their signatures.
[3] Thought about some workarounds that require Facelets code. For example, have controller listeners for page/sort/filter events, save page/sort/filter data to Session, then on lazy load or in-memory sort get those values. Can be done, but seems not optimal to me (everyone should remember to use events in view, controller event handlers).
So, is there an easy way to preserve paging/sorting/filtering in Session?
Is it built-in, or do we have to somehow extend the PF classes?
Thanks in advance!
PF DataTable store paging/sorting/filtering in Session
I'm also looking for an answer to the same question. So far without much success. If you save the value of dataTable.getFirst() at the @PreDestroy method of the view's backing bean then you can restore it later using dataTable.setFirst(theSavedValue) at a preRenderView listener method. I tried to do something similar with getFilters/setFilters and getMultiSortMeta/setMultiSortMeta but that doesn't work. Let's keep looking.
I cannot detect any non-ASCII character in my post. This is the error I get:
General Error
SQL ERROR [ mysqli ]
Incorrect string value: '\xE2\x80\x99s l...' for column 'post_text' at row 1 [1366]
It always fails at row 1 [1366] regardless of the text!
I'll split the text and try posting it in several replies.
General Error
SQL ERROR [ mysqli ]
Incorrect string value: '\xE2\x80\x99s l...' for column 'post_text' at row 1 [1366]
It always fails at row 1 [1366] regardless of the text!
I'll split the text and try posting it in several replies.
I couldn't even post the first one! It is less than 20 lines long. I don't see any strange character. I send an e-mail to the board administrator last week (similar problem, also at row1 [1366] entirely different text) but I have not received any answer yet.
I've finally found the illegal character, so here is my answer:
This is a partial but relatively easy solution. I found it looking at the code of org.primefaces.component.datatable.feature.FilterFeature. It is a 3-step procedure.
Step-1. Save the table data you want to restore later. Ideally all data should be saved at PreDestroy, but some has to be saved earlier, at preRenderView because the getter fails at PreDestroy (e.g. multiSortMeta). So you might need to add two methods to the view backing bean. They would look somehow like this:
Step-2. Add the filters as request parameters to the URL/outcome of the link, button, etc. you want to use to go back the page containing the table. You would need something like this:
As you might have already guessed, DATA_TABLE_ID is the DataTable component id (something like myForm:myDataTable); the id of the columns would be the filtered field name (which is used as key of the filters map) plus a suffix (like "Column"); for instance, the column for customerName would look like this:
Step-3. Restore the data you saved earlier. It should be restored at preRenderView. Finally, filter and sort the data (this is the tricky part). You would need a method like this:
There is a lot of details that still need your attention but I hope this would get you started.
This is a partial but relatively easy solution. I found it looking at the code of org.primefaces.component.datatable.feature.FilterFeature. It is a 3-step procedure.
Step-1. Save the table data you want to restore later. Ideally all data should be saved at PreDestroy, but some has to be saved earlier, at preRenderView because the getter fails at PreDestroy (e.g. multiSortMeta). So you might need to add two methods to the view backing bean. They would look somehow like this:
Code: Select all
public void saveAtPreRenderView(DataTable dataTable) {
if (dataTable != null) {
// getMultiSortMeta at PreDestroy fails
// ERROR WELD-000019 will appear in server's log
save(dataTable.getMultiSortMeta());
}
}
public void saveAtPreDestroy(DataTable dataTable) {
if (dataTable != null) {
save(dataTable.getFirst());
save(dataTable.getRows());
save(dataTable.getFilters());
}
}
Code: Select all
String rpl = "";
Map<String, Object> filters = dataTableState.getFilters();
if (filters != null && !filters.isEmpty()) {
Set<String> keySet = filters.keySet();
for (String key : keySet) {
Object obj = filters.get(key);
if (obj != null) {
String cid = DATA_TABLE_ID
+ ":" + key + "Column"
+ ":" + "filter";
rpl += "&" + cid + "=" + obj;
}
}
}
Code: Select all
<p:column
id="customerNameColumn"
sortBy="#{currentRow.customerName}"
filterBy="#{currentRow.customerName}"
filterMatchMode="contains"
headerText="Customer Name">
#{currentRow.customerName}
</p:column>
Code: Select all
public void restore(DataTable dataTable) {
if (dataTable != null) {
dataTable.setFirst(firstSavedValue);
dataTable.setRows(rowsSavedValue);
dataTable.setFilters(filtersSavedValue);
dataTable.setMultiSortMeta(multiSortMetaSavedValue);
FacesContext facesContext = FacesContext.getCurrentInstance();
// Filter like FilterFeature.encode
FilterFeature filterFeature = (FilterFeature) dataTable.getFeature(DataTableFeatureKey.FILTER);
List<FilterMeta> filterMetaData = filterFeature.populateFilterMetaData(facesContext, dataTable);
String globalFilterParam = dataTable.getClientId(facesContext) + ":" + "globalFilter";
filterFeature.filter(facesContext, dataTable, filterMetaData, globalFilterParam);
// Sort like FilterFeature.encode and DataTableRenderer.preRender
SortFeature sortFeature = (SortFeature) dataTable.getFeature(DataTableFeatureKey.SORT);
if (dataTable.isMultiSort()) {
if (dataTable.getMultiSortMeta() != null) { // check multiSortMeta because multiSort fails when it is null
sortFeature.multiSort(facesContext, dataTable);
}
} else {
sortFeature.singleSort(facesContext, dataTable);
}
}
}
-
- Information
-
Who is online
Users browsing this forum: No registered users and 34 guests