I am currently trying to get the current order of columns in a PrimeFaces datatable whenever a user reorders them. Since the server-side event does not provide any parameters, I decided to use a JavaScript handler to do so.
function onColumnReorder(glossary) {
var sortedColumnNames = ...
}
"glossary" is my datatable widget variable. Question is: how do I now retrieve the column names in their current order? Please note that I'm not talking about table data sorting, but just about the current order in which the columns appear in the table (left to right) - which may change of course, since "draggableColumns" is set to true.
Thanks for any advice and best regards
Pascal
First define colReorder AJAX event on datatable:
<p:ajax event="colReorder" listener="#{myBean.onColReorder}"/>
In onColReorder method find your datatable by id with UIViewRoot#findComponent() method. After you found your DataTable object it is easy. Use getColumns() method to get list of columns in onColReorder():
FacesContext fc = FacesContext.getCurrentInstance();
DataTable myDatatable = (DataTable) fc.getViewRoot().findComponent("your_datatable");
List<UIColumn> columns = myDatatable.getColumns();
var th =$(myTableWidgetVar.jqId).find('.ui-state-active');
returns you th with id myTableId:myColumnId, so you know which column has sorting enabled.
You can read now the triangle component:
th.find('.ui-sortable-column-icon');
And check which class it has defined:
'ui-icon-triangle-1-n' for sorting ascending
'ui-icon-triangle-1-s' for sorting descending
You'll have server callback on sort order change if you use LazyDataModel.
Related
We have a custom filter component for DataTable that works in PrimeFaces 8, but stopped to work in PF 11.
That custom filter updates the filter MatchMode with this call:
Column column = (Column) this.getParent();
column.setFilterMatchMode(this.filterMatchMode);
In PF 10 and 11 we have some changes in DataTable, but I don't know which one is responsible for filters map handling that caused above snippet stopped working.
First I think that some methods naming changes are related, so I tried to use new column.setFilterBy method, but DataTable do not reflect this in filters map.Then I put some break points on ColumnBase getters related to filtering, but none is called during filter.
So far, I think that I need to change filter directly in DataTable, but I have no clue how to.
This is what we do on our projects we have our own LazyDataTable implementation not sure if that makes a difference.
final Collection<FilterMeta> filters = table.getFilterMetaData();
filters.clear();
filters.add(FilterMeta.builder().field("registrationId").filterValue(registrationId).matchMode(MatchMode.EQUALS).build());
// construct the filter
table.setFilterMetaData(filters);
Using #Melloware answer as starting point, I managed to update filters map with this code:
Column column = (Column) this.getParent();
DataTable parentDataTable = (DataTable) column.getNamingContainer();
String key = column.getClientId();
// Get current filters map
Map<String, FilterMeta> filterByAsMap = parentDataTable.getFilterByAsMap();
// Get current column filter
FilterMeta filterMeta = filterByAsMap.get(key);
// Create new MatchMode and FilterConstraint
MatchMode matchMode = MatchMode.of(filterMatchMode);
FilterConstraint constraint = FilterFeature.FILTER_CONSTRAINTS.get(matchMode);
// Update column filter with MatchMode and FilterConstraint
filterMeta.setMatchMode(matchMode);
filterMeta.setConstraint(constraint);
// Update DataTable filters map
filterByAsMap.put(key, filterMeta);
parentDataTable.setFilterByAsMap(filterByAsMap);
Looks odd update filters map directly on DataTable, but current DataTable implementation do not cycle through columns to get filters like PF 8 did (AFAIK).
So... Don't know if this is correct or there are better approach, but for now this works.
A little note! My custom filter component handle value too, but filters map is correctly updated with new filter value without the need to this code above. It's probably handled by DataTable <-> Column <-> UIInput integration, if I can find how this works, maybe I can make a proper code to update filters map.
I have made a utility custom control to have a quick, generic view. the custom control has as properties a property names collection which is of type object and received an arraylist of java objects (e.g. a Customer object).
Then on the cc a repeat control is using this:
<xp:repeat id="rptObjects" var="obj" indexVar="idx" value="#{javascript:compositeData.collection}" >
I would like to make the columns more dynamic. So I defined a new property called linkName, also of type object.
The in my repeat control I have setup a div with a xp:link control:
<xp:link escape="true" text="#{javascript:compositeData.linkName}">
However I am struggling on the page that contains this cc to compute the value for the linkName property.
If for example I would like to use the name field on a Customer java object how should I compute the valeu for the linkName property?
on my cc I set the text for the link:
<xp:link escape="true">
<xp:this.value><![CDATA[#{javascript:return compositeData.pageLink + "?unid=" + obj.unid}]]></xp:this.value>
<xp:this.text><![CDATA[#{javascript:var lbl = compositeData.linkName;
obj[lbl]}]]></xp:this.text>
</xp:link>
on my xpage i could set:
<xc:ccUtilsGenericView pageLink="customer.xsp"
header="Customers" icon="fa fa-user" linkName="custName">
I want to write a totally dynamic query method, which gets dinamically column names as parameters. Column names i.e : id, age, name, etc. I'm going to use criteria query, however I don't know how it's done exactly.
Some example says:
"Path<Long> idPath = personRoot.get( Person_.id );
Path<Integer> agePath = personRoot.get( Person_.age );
criteria.select( builder.array( idPath, agePath ) );"
My problem is the usage of "builder.array" part. How can I put together my (i.e:) path elements into a "Selection... selections" parameter in order to the "select" accept it and be valid my dynamic query?
Is there any possibility to write multiple group by according to my "Selection... selections" parameter in the "select" part?
Any hints appreciated, thank You in advance.
Selection... selections is just syntactic sugra for Selection[] selections. So you just need to create an array of selections, and pas this array as argument to the builder.array() method.
I need to get to the second table's element. However since the web page contains two tables, I always end up getting an element from the first table.
Here is the code:
driver.get("http:.............");
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
String el = driver.findElement(By.xpath("//tr[1]/td[2]")).getText();
System.out.println(el);
//I need to get the following value: $0.00564000. How can I overcome this issue?
Try this:
String el = driver.findElements(By.xpath("//tr[2]/td[2]")).get(1).getText();
I am using DataTables with the tables being generated in a java controller class that talks to the database. Given a category id, the controller class returns an unknown number of preformatted HTML tables, one for each section in the given category queried. Ideally I would like to display each table as a DataTable on the same page, but unsure if that's possible given that I don't know how many tables I will be getting back so I can't set up their behavior before the query.
Is there a way to format the tables when/as I get them from the controller? I attempted to prepend each table with its own .ready block but that didn't seem to do the trick though I'm fairly new to jQuery and could just be missing something. I used the barest of configuration to try to get it working first
$(document).ready(function(){
$("#results").dataTable({
"bJQueryUI" : true
});
});
$(document).ready(function() {
$('.dataTable').dataTable();
} );
Turns out to work after all, but ONLY if you specify the tables as class="dataTable" which isn't well documented or explained, hopefully this un-confuses someone else!