/** * This file is part of pwt. * * pwt is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * pwt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with pwt. If not, * see <http://www.gnu.org/licenses/>. */ package fr.putnami.pwt.core.widget.incubating; import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.user.client.ui.Widget; import com.google.web.bindery.event.shared.HandlerRegistration; import java.util.List; import fr.putnami.pwt.core.editor.client.Editor; import fr.putnami.pwt.core.editor.client.Path; import fr.putnami.pwt.core.editor.client.Visitor; import fr.putnami.pwt.core.editor.client.util.PathUtils; import fr.putnami.pwt.core.model.client.model.Model; import fr.putnami.pwt.core.model.client.util.ModelUtils; import fr.putnami.pwt.core.theme.client.IconFont; import fr.putnami.pwt.core.widget.client.Button; import fr.putnami.pwt.core.widget.client.Button.Type; import fr.putnami.pwt.core.widget.client.Container; import fr.putnami.pwt.core.widget.client.InputText; import fr.putnami.pwt.core.widget.client.TableTH; import fr.putnami.pwt.core.widget.client.base.AbstractTableColumnAspect; import fr.putnami.pwt.core.widget.client.base.HasHeaderCell; import fr.putnami.pwt.core.widget.client.event.ButtonEvent; public class TableFilter<T> extends AbstractTableColumnAspect<T> implements HasHeaderCell { private final Button<T> button = new Button<T>(); private Boolean activate = false; private String filterValue; private final InputText inputText = new InputText(); private TableTH<?> headerCell; private HandlerRegistration valueChangeRegistration; public TableFilter() { this.endConstruct(); } protected TableFilter(TableFilter<T> source) { super(source); this.endConstruct(); } private void endConstruct() { this.button.setIconType(IconFont.ICON_FILTER); this.button.setType(Type.ICON); this.button.setSize(Button.Size.SMALL); this.button.addButtonHandler(new ButtonEvent.Handler() { @Override public void onButtonAction(ButtonEvent event) { TableFilter.this.toggle(); } }); } @Override public AbstractTableColumnAspect<T> cloneAspect() { return new TableFilter<T>(this); } @Override public Widget asWidget() { return this.button; } @Override public void setHeaderCell(TableTH<?> headerCell) { this.headerCell = headerCell; } private void toggle() { this.activate = !this.activate; this.redraw(); this.getDriver().resetDisplay(); } public void redraw() { this.button.setIconType(IconFont.ICON_FILTER); this.button.setActive(this.activate); Container row = (Container) ((Widget) this.headerCell).getParent(); this.headerCell.clear(); if (this.valueChangeRegistration != null) { this.valueChangeRegistration.removeHandler(); this.valueChangeRegistration = null; } boolean showFilterRow = false; if (this.activate) { this.headerCell.append(this.inputText); this.valueChangeRegistration = this.inputText.addBlurHandler(new BlurHandler() { @Override public void onBlur(BlurEvent event) { String newValue = TableFilter.this.inputText.flush(); if (!Objects.equal(TableFilter.this.filterValue, newValue)) { TableFilter.this.filterValue = newValue; TableFilter.this.getDriver().resetDisplay(); } } }); Widget hCell = this.button.getParent().getParent(); hCell.getElement().getStyle().setWidth(hCell.getOffsetWidth(), Unit.PX); showFilterRow = true; } if (!showFilterRow) { for (Widget cell : row) { if (cell instanceof TableTH) { showFilterRow |= Iterators.size(((TableTH<?>) cell).iterator()) > 0; if (showFilterRow) { break; } } } } row.setVisible(showFilterRow); } @Override public int getPrecedence() { return Visitor.PRECEDENCE_NORMAL + 3; } @Override public <A, B extends Editor> boolean beforeVisit() { if (this.activate && this.filterValue != null) { final Model<T> leafModel = this.getDriver().getModel().getLeafModel(); final Path path = PathUtils.evalPath(this.getColumnPath()); List<T> list = this.getDriver().getDisplayedValue(); list = Lists.newArrayList(Iterables.filter(list, new Predicate<T>() { @Override public boolean apply(T input) { Object p1 = ModelUtils.resolveValue(input, leafModel, path); if (p1 instanceof String) { return ((String) p1).toLowerCase().contains(TableFilter.this.filterValue.toLowerCase()); } return true; } })); this.getDriver().setDisplayedValue(list); } return true; } }