Header of Sortable CellTable Column not Responsive - gwt

I am using GWT 2.5 to create a CellTable with a sortable date column.
My code is as follows:
CellTable<Activity> table = new CellTable<Activity>();
table.setRowStyles(new RowStyles<Activity>() {
#Override
public String getStyleNames(Activity row, int rowIndex) {
return TABLE_ROW_STYLE_NAME;
}
});
// create date column
TextColumn<Activity> dateColumn = new TextColumn<Activity>() {
#Override
public String getValue(Activity a) {
return dateFormat.format(a.getDate());
}
};
dateColumn.setSortable(true);
dateColumn.setDefaultSortAscending(false);
// add column to table
table.addColumn(dateColumn, myConstants.dateColumnHeader());
// attach provider to table
activityProvider.addDataDisplay(table);
// create sort handler
ListHandler<Activity> sortHandler = new ListHandler<Activity>(activityProvider.getList());
sortHandler.setComparator(dateColumn, new Comparator<Activity>() {
#Override
public int compare(Activity a1, Activity a2) {
if (a1 == a2) {
return 0;
}
// compare the date columns
if (a1 != null) {
if (a2 != null) {
long a1Val = a1.getDate().getTime();
long a2Val = a2.getDate().getTime();
if (a1Val == a2Val) {
return 0;
}
else if (a1Val > a2Val) {
return 1;
}
else {
return -1;
}
}
else {
return 1;
}
}
return -1;
}
});
// add sort handler to table
table.addColumnSortHandler(sortHandler);
// add date column to table's sort list
table.getColumnSortList().push(dateColumn);
table.setWidth("100%");
getView().getActivityPanel().add(table);
With this code, the data is displayed in the table and the sorting arrow on the column appears. However, nothing happens when I click on the sortable column's header. The sorting order doesn't change, rows are not rearranged.
Can anyone spot the problem here? This code is almost the same as what they have in Google's own example.

This is what I use:
dateColumn.setSortable(true);
sortHandler.setComparator(dateColumn, new Comparator<ObjectPobject>() {
public int compare(ObjectPobject o1, ObjectPobject o2) {
return o1.getDate().compareTo(o2.getDate());
}
});

It should be
a1.getDate().getTime().compareTo(a2.getDate().getTime())
or
a1.getDate().after(a2.getDate())
This happens because GWT uses JavaScript comparisons, and compareTo does not work for dates.

Related

Vaadin Grid always selects last row

I need help debugging the follow issue:
When I click on a Vaadin Grid with 3 rows, it ignores the click on any but the last row and always selects the 3rd row.
Code is as follows:
// declare Grid objects
public final Grid<SoapKPIContainer> soapKPIOverviewGridDisplay;
..
public SoapKPIOverviewView(SoapKPIRepository soapKPIRepository, Navigator navigator,
BpspSoapCheckCommunications bpspSoapCheckCommunications,
UIMessageByLocaleService messageByLocaleService) {
..
this.soapKPIOverviewGridDisplay = new Grid<>(SoapKPIContainer.class);
this.soapKPIOverviewGridDisplay.setColumns();
Grid.Column<SoapKPIContainer, ?> lastAlarmStatusIconColumn = this.soapKPIOverviewGridDisplay.addColumn("lastAlarmStatusIcon", new ImageRenderer<>());
lastAlarmStatusIconColumn.setSortable(false);
lastAlarmStatusIconColumn.setResizable(false);
lastAlarmStatusIconColumn.setWidth(80.0f);
lastAlarmStatusIconColumn.setCaption(messageByLocaleService.getMessage("label.lastalarmstatus"));
Grid.Column<SoapKPIContainer, ?> activationIconColumn = this.soapKPIOverviewGridDisplay.addColumn("activationIcon", new ImageRenderer<>());
activationIconColumn.setSortable(false);
activationIconColumn.setResizable(false);
this.soapKPIOverviewGridDisplay.getDefaultHeaderRow().getCell("lastAlarmStatusIcon").setHtml(messageByLocaleService.getMessage("label.lastalarmstatus"));
this.soapKPIOverviewGridDisplay.getDefaultHeaderRow().getCell("activationIcon").setHtml(messageByLocaleService.getMessage("label.activationicon"));
this.soapKPIOverviewGridDisplay.addColumn(SoapKPIContainer::getKpiName).
setCaption(messageByLocaleService.getMessage("header.kpiName"));
..
this.setSizeFull();
this.soapKPIOverviewGridDisplay.setSizeFull();
this.soapKPIOverviewGridDisplay.setHeight(400, Unit.PIXELS);
this.soapKPIService = new SoapKPIService(soapKPIRepository);
this.soapKPIOverviewGridDisplay.setItems( soapKPIService.toContainer( soapKPIService.findAllSoapKPI() ) );
..
// adding Listener for the Grid to enable for the user to select single KPIs
soapKPIOverviewGridDisplay.setSelectionMode(SelectionMode.SINGLE);
soapKPIOverviewGridDisplay.asSingleSelect().addValueChangeListener(e -> {
log.debug("asSingleSelect().addValueChangeListener " + e.getValue());
if ( e.getValue() != null) {
log.debug("asSingleSelect().addValueChangeListener findSoapKPIById #" + e.getValue().getKpiId());
testKPIDefView.setEnabled(true);
soapKPI = soapKPIService.findSoapKPIById( e.getValue().getKpiId() );
changeEnabled.setVisible(true);
if( soapKPI.getEnabled() == 1)
changeEnabled.setCaption(messageByLocaleService.getMessage("button.disable"));
else
changeEnabled.setCaption(messageByLocaleService.getMessage("button.enable"));
}
else {
testKPIDefView.setEnabled(false);
changeEnabled.setVisible(false);
soapKPI = null;
}
});
..
soapKPIOverviewLayout.addComponent(soapKPIOverviewGridDisplay);
I'm still not sure what line in the code cause it to break, but I found that overriding the equals method of the row object makes the problem go away:
#Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof SoapKPIContainer)) {
return false;
}
SoapKPIContainer container = (SoapKPIContainer) o;
return this.getKpiId() == container.getKpiId();
}

Empty rows in Vaadin grid after applying filter

I try to use Vaadin grid with lazy loading. When I add filter to the grid, at some filter values I see empty rows and get java.lang.IndexOutOfBoundsException: toIndex = 45. Below is my code:
public class ProcessService {
private List<GeneralProcess> processList;
private int i;
public ProcessService() {
processList=new Repository().list(); //fetch all data from DB
}
public List<GeneralProcess> findAll(int offset, int limit, String
filter){
Collections.sort(processList,Comparator
.comparing(GeneralProcess::getName));
if(filter!=null) {
return processList.stream().filter((s) ->
s.getName().startsWith(filter))
.collect(Collectors.toList()).subList(offset,offset+limit);
}
else {
return processList.subList(offset,offset+limit);
}
}
public int count() {
return processList.size();
}
And here is code from UI:
private TextField FilterProcessName= new TextField();
DataProvider<GeneralProcess,String> provider=
DataProvider.fromFilteringCallbacks(query->{
int offset = query.getOffset();
int limit = query.getLimit();
String filter = query.getFilter().orElse(null);
List<GeneralProcess> processes =
service.findAll(offset, limit,filter);
return processes.stream();
},
query -> service.count());
ConfigurableFilterDataProvider<GeneralProcess,Void,String> wrapper=
provider.withConfigurableFilter();
grid.setDataProvider(wrapper);
FilterProcessName.addValueChangeListener(event -> {
String filter = event.getValue();
if (filter.trim().isEmpty()) {
filter = null;
}
wrapper.setFilter(filter);
grid.getDataProvider().refreshAll();
});
The problem appears when filter value is very narrow and there should be just few rows in the grid. Please any help

How to remove row selection on Space click in GWT celltable?

In celltable when I use like this,
dgrid.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
Edited fields space click selecting the row, so I used like this
dgrid.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.BOUND_TO_SELECTION);
But in this row gets selected on single click itself..
I want only checkbox for selection, column click should not select the row, Can anyone help me in achieving this?
protected DefaultSelectionEventManager.EventTranslator<ProductProxy> eventTranslator = new DefaultSelectionEventManager.EventTranslator<ProductProxy>() {
#Override
public boolean clearCurrentSelection(CellPreviewEvent<ProductProxy> event) {
NativeEvent nativeEvent = event.getNativeEvent();
String type = nativeEvent.getType();
if (BrowserEvents.CLICK.equals(type)) {
int index = event.getContext().getColumn();
if (index == getDeleteColumnIndex())
return true;
}
return false;
}
#Override
public SelectAction translateSelectionEvent(CellPreviewEvent<ProductProxy> event) {
NativeEvent nativeEvent = event.getNativeEvent();
String type = nativeEvent.getType();
if (BrowserEvents.CLICK.equals(type)) {
if (event.getColumn() == getDeleteColumnIndex()) {
ProductTable.this.productTableManager.deleteProduct(event.getValue());
return SelectAction.IGNORE;
}
}
return SelectAction.DEFAULT;
}
};
Then use that selector in your CellTable:
I have
class MyTable extends CellTable {
void myInit() {
setSelectionModel(selectionModel, DefaultSelectionEventManager.createCustomManager(eventTranslator));
}}
So for your case, just replace getDeleteColumnIndex() by getCheckoxColumnIndex() and return your column index (if it changes), and handle the space key instead of the click

How to apply like search on GWT cell table?

I am using GWT 2.3.I which I am using GWT cell table.
Here below is the code for my cell table:
public class FormGrid extends SuperGrid {
List<Form> formList;
#Override
public void setColumns(CellTable table) {
TextColumn<Form> nameColumn = new TextColumn<Form>() {
#Override
public String getValue(Form object) {
return object.getName();
}
};
table.addColumn(nameColumn, "Name");
}
#Override
public void setData() {
if (formList != null && formList.size() > 0) {
AsyncDataProvider<Form> provider = new AsyncDataProvider<Form>() {
#Override
protected void onRangeChanged(HasData<Form> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
end = end >= formList.size() ? formList.size() : end;
List<Form> sub = formList.subList(start, end);
updateRowData(start, sub);
}
};
provider.addDataDisplay(getTable());
provider.updateRowCount(formList.size(), true);
}
}
public List<Form> getFormList() {
return formList;
}
public void setFormList(List<Form> formList) {
this.formList = formList;
}
}
In this my set column and set data will be called fro super class flow.This cell table is working fine.
Now I want to put a filter type facility (like search) in this cell table.It should be like, there is a texbox above the cell table and what ever written in that text box, it should fire a like query to all form name for that text box value.
for example I have 1000 form in the grid.Now if user writes 'app' in some filter textbox above the cell table the all the form which have 'app' in there name will be filtered and grid has only those forms only.
This is the first case:
Another case is I am only render one column in grid name.I have two more properties in form (description,tag).But I am not rendering them.now for filter if user writes 'app' in filter box then it should make a query to all three (name, description, and tag) and should return if 'app' matched to any of three.
I am not getting how to apply filter in cell table.
Please help me out.Thanks in advance.
You can find an implementation in the expenses sample.
Here is a short summary of the steps
1.) Create a Textbox and a SearchButton.
2.) add a clickHandler to the SearchButton (You can also add KeyUpHandler to the Textbox alternatively)
searchButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
search();
}
});
3.) In the search function retrieve the searchString and store it.
private void search() {
searchString = searchBox.getText();
setData();
}
4.) modify your setdata() function to take searchString into account
#Override
public void setData() {
if (formList != null && formList.size() > 0) {
AsyncDataProvider<Form> provider = new AsyncDataProvider<Form>() {
#Override
protected void onRangeChanged(HasData<Form> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
//new function if searchString is specified take into account
List<Form> sub = getSubList(start,end);
end = end >= sub.size() ? sub.size() : end;
updateRowData(sub.subList(start, end);, sub);
}
};
provider.addDataDisplay(getTable());
provider.updateRowCount(formList.size(), true);
}
}
private List<Form> getSubList(int start, int end) {
List<Form> filtered_list = null;
if (searchString != null) {
filtered_list= new ArrayList<Form>();
for (Form form : formList) {
if (form.getName().equals(searchString) || form.getTag().equals(searchString) || form.getDescription().equals(searchString))
filtered_list.add(form);
}
}
else
filtered_list = formList;
return filtered_list;
}
can propose another solution what can be used quite easy multiple times.
Idea is to create custom provider for your celltable.
GWT celltable filtering
Video in this post shows it in action.
Here is the part of code of custom list data provider which u have to implement.
#Override
protected void updateRowData(HasData display, int start, List values) {
if (!hasFilter() || filter == null) { // we don't need to filter, so call base class
super.updateRowData(display, start, values);
} else {
int end = start + values.size();
Range range = display.getVisibleRange();
int curStart = range.getStart();
int curLength = range.getLength();
int curEnd = curStart + curLength;
if (start == curStart || (curStart < end && curEnd > start)) {
int realStart = curStart < start ? start : curStart;
int realEnd = curEnd > end ? end : curEnd;
int realLength = realEnd - realStart;
List<t> resulted = new ArrayList<t>(realLength);
for (int i = realStart - start; i < realStart - start + realLength; i++) {
if (filter.isValid((T) values.get(i), getFilter())) {
resulted.add((T) values.get(i));
}
}
display.setRowData(realStart, resulted);
display.setRowCount(resulted.size());
}
}
}

How to hide column in Cell table GWT?

I am using Cell Table in GWT.In that cell table I am adding these columns.
TextColumn<Document> idColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return Long.toString(object.getId());
}
};
TextColumn<Document> refColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getReferenceNumber();
}
};
/*
* DateCell dateCell = new DateCell(); Column<Contact, Date> dateColumn
* = new Column<Contact, Date>(dateCell) {
*
* #Override public Date getValue(Contact object) { return
* object.birthday; } };
*/
TextColumn<Document> nameColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getDocumentName();
}
};
table = new CellTable<T>();
table.addColumn(idColumn, "Id");
table.addColumn(refColumn, "Reference Number");
table.addColumn(nameColumn, "Name");
}
Now I have some queries:
How to hide the id column?
On click of row how can i get the from selected row?
Please help me out.
Thanks in advance.
Well you could try to use fixed layout for the CellTable and set the width of the specific column you want to hide to 0px.
I did use another approach.
In my case I have a cellTable which should display a checkbox column as soon as I press a button (which puts the celltable in edit mode).
I do this by creating a CheckBoxColumn and inserting and removing it when I press on the button. It looks seomething like that:
#Override
public void insertCheckBoxColumn(Column<Object,Boolean> column) {
if (cellTable.getColumnIndex(column) == -1) {
cellTable.addColumn(column,"");
cellTable.setColumnWidth(column,50, Unit.PX);
}
}
#Override
public void removeCheckBoxColumn(Column<Object, Boolean> column) {
int index = cellTable.getColumnIndex(column);
if (index != -1)
cellTable.removeColumn(index);
}
However note that you might run into this issue on google chrome.