I have a ListGrid and have defined the Datasource via XML. One of the columns has persons name called Officer. Is it possible to have a dropdown in the grid filter with all the unique values on it? I dont want to hard-code it as list of uniques person names may grow or shrunk. I want the dropdown list to be based on the current data loaded on grid.
Announcement
Collapse
No announcement yet.
X
-
If you mean all of the values for Officer in the whole DataSource, just set an optionDataSource on the SelectItem used as filterEditorProperties for the field, and point it to an operationBinding that uses Server Summaries to perform the equivalent of a SELECT DISTINCT (see the last section on Grouping without Summarizing).
If you want to instead show just the distinct values present in the current filtered grid, you still use an optionDataSource, but now create a clientOnly DataSource to use as the optionDataSource, and implement dataProtocol:clientCustom so that you can respond to the "fetch" DSRequest from the SelectItem with custom code. That code should go to the grid and grab all the distinct values from the grid's ResultSet. When the filter criteria on the grid change (DataChanged event), use DataSource.invalidateCache() to cause the list in the FilterEditor to be refreshed (a new DSRequest will then come in to your DataSource).
Last case: maybe the grid isn't full loaded, so you still need to go back to the DataSource to get the full list of Officer values. You can figure out whether you're in this case because the grid's resultSet's allMatchingRowsCached() will be false. In this case, you can just implement your fetch request by issuing a fetch request to the original DataSource, again with SELECT DISTINCT. Pass along the criteria from the grid via calling listGrid.getFilterEditorCriteria().
-
Hi Isomorphic,
thanks, I was thinking about how to solve this as well, even though it is not an issue here, yet.
While option 1 and 3 were clear to me, #2 is new.
Thank you & Best regards
Blama
Comment
-
Originally posted by Isomorphic View PostIf you want to instead show just the distinct values present in the current filtered grid, you still use an optionDataSource, but now create a clientOnly DataSource to use as the optionDataSource, and implement dataProtocol:clientCustom so that you can respond to the "fetch" DSRequest from the SelectItem with custom code. That code should go to the grid and grab all the distinct values from the grid's ResultSet. When the filter criteria on the grid change (DataChanged event), use DataSource.invalidateCache() to cause the list in the FilterEditor to be refreshed (a new DSRequest will then come in to your DataSource).
Code:ListGrid myGrid = new ListGrid("myGridDataSource"); DataSource dsi = new DataSource() { @Override protected Object transformRequest(DSRequest dsRequest) { if (dsRequest.getOperationType() == DSOperationType.FETCH) { ListGridRecord[] recs = grid.getRecords(); Set<String> uniqueValues = new HashSet<>(); for (ListGridRecord rec : recs) { String value = rec.getAttribute("industry"); uniqueValues.add(value); } Record[] newData = uniqueValues.stream().map(value -> { Record i = new Record(); i.setAttribute("industry", value); return i; }).toArray(Record[]::new); DSResponse dsResponse = new DSResponse(); dsResponse.setStatus(0); dsResponse.setData(newData); processResponse(dsRequest.getRequestId(), dsResponse); } return dsRequest.getData(); } }; dsi.setDataProtocol(DSProtocol.CLIENTCUSTOM); dsi.setClientOnly(true); ListGridField industryField = grid.getField("industry"); industryField.setOptionDataSource(dsi); industryField.setValueField("industry"); grid.addDataChangedHandler(dataChangedEvent -> { dsi.fetchData(new Criteria()); grid.getDataSource().invalidateCache(); });
Last edited by steolan; 13 Oct 2020, 07:21.
Comment
-
No existing sample, but your question did inspire creation of one in the future.
It's expected that you would be called as soon as the grid draws - see SelectItem.autoFetchData - data is fetched at draw for a SelectItem because it allows keyboard navigation of data while the SelectItem is closed.
So you can turn that off to avoid the request if you want, but your code will likely still need the other branch discussed above (where allMatchingRowsCached() is false and you need to hit the server to get all the distinct values), which would also handle that early fetch.
Comment
Comment