Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Grid - Filter in HeaderRow, attached widget
Hello Everyone! :)
I am using Grid Component in my Vaadin application. I have following function to initialize my columns:
private void prepareColumns() {
removeAllColumns();
final HeaderRow filterInputRow = appendHeaderRow();
final HeaderRow filterOptionRow = appendHeaderRow();
for (Map.Entry < String, String > columnEntry: columns.entrySet()) {
final Column column = addColumn(columnEntry.getKey());
column.setHidable(true);
column.setHeaderCaption(columnEntry.getValue());
column.setWidthUndefined();
final HeaderCell filterInputCell = filterInputRow.getCell(columnEntry.getKey());
final HeaderCell filterOptionCell = filterOptionRow.getCell(columnEntry.getKey());
switch (columnEntry.getKey()) {
case "statusImage":
column.setRenderer(new HtmlRenderer());
break;
case "correlationId":
column.setHidden(true);
break;
case "timestamp":
column.setRenderer(new DateRenderer(new SimpleDateFormat("dd MMM yyyy HH:mm:ss", GWUI.get().getGWLocale())));
break;
case "duration":
column.setRenderer(new NumberRenderer("%d"));
filterInputCell.setComponent(createFilter(columnEntry.getKey()));
filterOptionCell.setComponent(createNumberOptionGroup());
break;
default:
filterInputCell.setComponent(createFilter(columnEntry.getKey()));
filterOptionCell.setComponent(createTextOptionGroup());
break;
}
}
}
Everytime I reload component I got following errors in web console (taken from Chrome web console):
SEVERE: Widget is still attached to the DOM after the connector (CssLayoutConnector (89)) has been unregistered. Widget was removed.
I noticed that when I disable adding additional header rows the error does not appear. Does anyone encounter this problem?
Thanks in advance!
Kamil
Do you have a CssLayout defined somewhere? I can't see where that is?
I don't use Css Layout, but the error message is the same. Ok, almost the same, exactly (this is a JS error!):
Fri Aug 19 13:18:28 GMT+200 2016 com.vaadin.client.VConsole
SEVERE: Widget is still attached to the DOM after the connector (TextFieldConnector (182)) has been unregistered. Widget was removed.
http://localhost:8181/alumni/#!/html/body/script (27)
Line 1
In the TomCat console log:
aug. 19, 2016 13:18:27 DE com.vaadin.ui.ConnectorTracker unregisterConnector
WARNING: Unregistered TextField (182) that was already unregistered.
I've (tried :) ) created a general filters for a grid. Simple filters: text contains and date range.
The superclass has a method which adds a header row to grid (if not extists) and walks throught container properties and takes filter column by the property class (String -> text filter, Date -> date filter).
Here it is a part of the superclass (... extends Grid) :
protected LazyQueryContainer containter;
protected HeaderRow filterRow = null;
public void setContainer(LazyQueryContainer containter) {
this.containter = containter;
setContainerDataSource(containter);
addFilterRow();
}
protected void removeColFilter(String pid, LazyQueryContainer container) {
for (int i = 0; i < allColFilters.size(); i++) {
String key = (String) allColFilters.get(i).getKey();
if (key.equals(pid)) {
container.removeContainerFilter((Filter) allColFilters.get(i).getValue());
allColFilters.remove(i);
return;
}
}
}
protected void addFilterRow() {
if (containter == null || this.getHeaderRowCount() > 1) {
return;
}
filterRow = appendHeaderRow();
for (Object pid : containter.getContainerPropertyIds()) {
HeaderCell cell = filterRow.getCell(pid);
if (containter.getType(pid).toString().contains("java.util.Date")) {
DateField filterDFieldFrom = new DateField();
DateField filterDFieldTo = new DateField();
filterDFieldFrom.setDateFormat("yyyy.MM.dd HH:mm:ss");
filterDFieldTo.setDateFormat("yyyy.MM.dd HH:mm:ss");
filterDFieldFrom.setResolution(Resolution.SECOND);
filterDFieldTo.setResolution(Resolution.SECOND);
filterDFieldFrom.addValueChangeListener(change -> {
removeColFilter(pid.toString(), containter);
if (filterDFieldFrom.getValue() != null || filterDFieldTo.getValue() != null) {
if (filterDFieldFrom.getValue() != null && filterDFieldTo.getValue() == null) {
Filter colFilter = new Compare.GreaterOrEqual(pid,
filterDFieldFrom.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
if (filterDFieldFrom.getValue() == null && filterDFieldTo.getValue() != null) {
Filter colFilter = new Compare.LessOrEqual(pid,
filterDFieldTo.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
if (filterDFieldFrom.getValue() != null && filterDFieldTo.getValue() != null) {
Filter colFilter = new Between(pid,
filterDFieldFrom.getValue(),
filterDFieldTo.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
} else {
containter.refresh();
}
});
filterDFieldTo.addValueChangeListener(change -> {
removeColFilter(pid.toString(), containter);
if (filterDFieldTo.getValue() != null || filterDFieldFrom.getValue() != null) {
if (filterDFieldFrom.getValue() != null && filterDFieldTo.getValue() == null) {
Filter colFilter = new Compare.GreaterOrEqual(pid,
filterDFieldFrom.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
if (filterDFieldFrom.getValue() == null && filterDFieldTo.getValue() != null) {
Filter colFilter = new Compare.LessOrEqual(pid,
filterDFieldTo.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
if (filterDFieldFrom.getValue() != null && filterDFieldTo.getValue() != null) {
Filter colFilter = new Between(pid,
filterDFieldFrom.getValue(),
filterDFieldTo.getValue());
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
}
} else {
containter.refresh();
}
});
HorizontalLayout hl = new HorizontalLayout();
hl.addComponents(filterDFieldFrom, new Label(" - "), filterDFieldTo);
cell.setComponent(hl);
} else {
TextField filterField = new TextField();
filterField.addTextChangeListener(change -> {
removeColFilter(pid.toString(), containter);
if (!change.getText().isEmpty()) {
Filter colFilter = new Like(pid, "%" + change.getText() + "%", false);
containter.addContainerFilter(colFilter);
allColFilters.add(new AbstractMap.SimpleEntry(pid, colFilter));
} else {
containter.refresh();
}
});
cell.setComponent(filterField);
}
}
}
(This is the first attempt. So probably not the final solution. ;) )
Something I missed or misundertood... The problem:
when open a filtered grid - first time, after login - it works perfectly, no error.
Than I go to another view - to another filtered grid or there is not grid, doesn't matter - the error raises. So when I leave that view the error raises.
It seems it generates some JS code for filter which is stuck in the page/view...
It seems something I missed...
What did I do wrong?
One more detail:
I call the "addFilterRow" method in the "attach" method of subclass.
I have tried with one, single "text filter field".
And in the "detach" method of subclass I remove that one (filter) textfiled component.
But the error raises just like I wrote above. :(
Ok, next approach. No generic/general solution. Everything is specific.
Here's the AuditLog grid creator class, with one filter column:
public class AuditLogsGridCreator {
private Grid grid;
protected LazyQueryContainer containter;
private TextField ffEvent; // filter field for Event column
public AuditLogsGridCreator(LazyQueryContainer containter) {
this.containter = containter;
createGrid();
addFilters();
}
private void addFilters() {
Object pid = "event";
HeaderRow filterRow = this.grid.appendHeaderRow();
Grid.HeaderCell cell = filterRow.getCell(pid);
ffEvent = new TextField();
ffEvent.addTextChangeListener((change) -> {
if (!change.getText().isEmpty()) {
Container.Filter colFilter = new Like(pid, "%" + change.getText() + "%", false);
this.containter.addContainerFilter(colFilter);
} else {
this.containter.refresh();
}
});
cell.setComponent(ffEvent);
}
private void createGrid() throws IllegalArgumentException, IllegalStateException {
this.grid = new Grid(this.containter);
this.grid.setSizeFull();
this.grid.getColumn("id").setHeaderCaption("ID");
this.grid.getColumn("event").setHeaderCaption("Event");
this.grid.getColumn("source").setHeaderCaption("Source");
this.grid.getColumn("functionName").setHeaderCaption("Fnc.");
this.grid.getColumn("clientInfo").setHeaderCaption("Client");
this.grid.getColumn("created").setHeaderCaption("Created");
this.grid.getColumn("userName").setHeaderCaption("User");
this.grid.getColumn("event").setWidth(800);
}
public Grid getGrid() {
return this.grid;
}
public TextField getFfEvent() {
return ffEvent;
}
public void setFfEvent(TextField ffEvent) {
this.ffEvent = ffEvent;
}
}
Calling in the "view class":
[...]
private void createContent() {
LazyQueryContainer items = new LazyQueryContainer(this.auditlogsService.lazyLoadData(), "id", 50, false);
items.addContainerProperty("id", Long.class, 0L, true, true);
items.addContainerProperty("event", String.class, "", true, true);
items.addContainerProperty("source", String.class, "", true, true);
items.addContainerProperty("functionName", String.class, "", true, true);
items.addContainerProperty("clientInfo", String.class, "", true, true);
items.addContainerProperty("created", Date.class, "", true, true);
items.addContainerProperty("userName", String.class, "", true, true);
this.table = new AuditLogsGridCreator(items);
addComponents(table.getGrid());
}
[...]
The error raises when I go throught views/grids. Just right I wrote previous post....
:(
I did miss something..... but what?