diff options
author | Pekka Hyvönen <pekka@vaadin.com> | 2016-09-27 12:26:15 +0300 |
---|---|---|
committer | Denis Anisimov <denis@vaadin.com> | 2016-09-28 12:59:52 +0000 |
commit | c4b17ca879c0bb51c7da390fcbd25c96b73486fb (patch) | |
tree | 524833ebab1553534e3d4ff01cd0fa5cf58db3a7 /client | |
parent | 96119ab0224421d69393d9d41ed02900121a683e (diff) | |
download | vaadin-framework-c4b17ca879c0bb51c7da390fcbd25c96b73486fb.tar.gz vaadin-framework-c4b17ca879c0bb51c7da390fcbd25c96b73486fb.zip |
ListSelect with new data binding API8.0.0.alpha3
No single select mode for list select.
Based on AbstractMultiSelect.
Removes feature for adding new items.
Change-Id: I9a92aaf1f3d338a3b05c3aa4048f9db496dacd1d
Diffstat (limited to 'client')
-rw-r--r-- | client/src/main/java/com/vaadin/client/ui/VListSelect.java | 263 | ||||
-rw-r--r-- | client/src/main/java/com/vaadin/client/ui/listselect/ListSelectConnector.java | 54 |
2 files changed, 317 insertions, 0 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VListSelect.java b/client/src/main/java/com/vaadin/client/ui/VListSelect.java new file mode 100644 index 0000000000..185c593b83 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/VListSelect.java @@ -0,0 +1,263 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HasEnabled; +import com.google.gwt.user.client.ui.ListBox; +import com.vaadin.client.FastStringSet; +import com.vaadin.client.Focusable; +import com.vaadin.client.connectors.AbstractMultiSelectConnector.MultiSelectWidget; +import com.vaadin.shared.Registration; + +import elemental.json.JsonObject; + +/** + * A simple list select for selecting multiple items. + * + * @author Vaadin Ltd + */ +public class VListSelect extends Composite implements ClickHandler, Field, + Focusable, HasEnabled, MultiSelectWidget { + + private List<BiConsumer<Set<String>, Set<String>>> selectionChangeListeners = new ArrayList<>(); + + /** Container for select. Kept for DOM backwards compatibility. */ + protected final FlowPanel container; + /** The select component. */ + protected final ListBox select; + + private boolean enabled; + private boolean readOnly; + private FastStringSet selectedItemKeys = FastStringSet.create(); + + /** + * Constructs a simple ListSelect widget in multiselect mode. + */ + public VListSelect() { + container = new FlowPanel(); + initWidget(container); + + select = new ListBox(); + select.setMultipleSelect(true); + select.addClickHandler(this); + + container.add(select); + + updateEnabledState(); + } + + /** + * Sets the number of visible items for the list select. + * + * @param rows + * the number of items to show + * @see ListBox#setVisibleItemCount(int) + */ + public void setRows(int rows) { + if (select.getVisibleItemCount() != rows) { + select.setVisibleItemCount(rows); + } + } + + /** + * Returns the number of visible items for the list select. + * + * @return the number of items to show + * @see ListBox#setVisibleItemCount(int) + */ + public int getRows() { + return select.getVisibleItemCount(); + } + + @Override + public Registration addSelectionChangeListener( + BiConsumer<Set<String>, Set<String>> listener) { + Objects.nonNull(listener); + selectionChangeListeners.add(listener); + return (Registration) () -> selectionChangeListeners.remove(listener); + } + + @Override + public void setStyleName(String style) { + super.setStyleName(style); + updateStyleNames(); + } + + @Override + public void setStylePrimaryName(String style) { + super.setStylePrimaryName(style); + updateStyleNames(); + } + + /** Update the style names for container & select. */ + protected void updateStyleNames() { + container.setStyleName(getStylePrimaryName()); + select.setStyleName(getStylePrimaryName() + "-select"); + } + + @Override + public void setItems(List<JsonObject> items) { + selectedItemKeys = FastStringSet.create(); + for (int i = 0; i < items.size(); i++) { + final JsonObject item = items.get(i); + // reuse existing option if possible + final String key = MultiSelectWidget.getKey(item); + if (i < select.getItemCount()) { + select.setItemText(i, MultiSelectWidget.getCaption(item)); + select.setValue(i, key); + } else { + select.addItem(MultiSelectWidget.getCaption(item), key); + } + final boolean selected = MultiSelectWidget.isSelected(item); + select.setItemSelected(i, selected); + if (selected) { + selectedItemKeys.add(key); + } + } + + // remove extra + for (int i = select.getItemCount() - 1; i >= items.size(); i--) { + select.removeItem(i); + } + } + + /** + * Gets the currently selected item values. + * + * @return the currently selected item keys + */ + protected FastStringSet getSelectedItems() { + final FastStringSet selectedItemKeys = FastStringSet.create(); + for (int i = 0; i < select.getItemCount(); i++) { + if (select.isItemSelected(i)) { + selectedItemKeys.add(select.getValue(i)); + } + } + return selectedItemKeys; + } + + @Override + public void onClick(ClickEvent event) { + if (event.getSource() == select) { + // selection can change by adding and at the same time removing + // previous keys, or by just adding (e.g. when modifier keys are + // pressed) + final Set<String> newSelectedItemKeys = new HashSet<>(); + final Set<String> removedItemKeys = new HashSet<>(); + for (int i = 0; i < select.getItemCount(); i++) { + String key = select.getValue(i); + boolean selected = select.isItemSelected(i); + boolean wasSelected = selectedItemKeys.contains(key); + if (selected && !wasSelected) { + newSelectedItemKeys.add(key); + selectedItemKeys.add(key); + } else if (!selected && wasSelected) { + removedItemKeys.add(key); + selectedItemKeys.remove(key); + } + } + selectionChangeListeners.forEach( + l -> l.accept(newSelectedItemKeys, removedItemKeys)); + } + } + + @Override + public void setHeight(String height) { + select.setHeight(height); + super.setHeight(height); + } + + @Override + public void setWidth(String width) { + select.setWidth(width); + super.setWidth(width); + } + + /** + * Sets the tab index. + * + * @param tabIndex + * the tab index to set + */ + public void setTabIndex(int tabIndex) { + select.setTabIndex(tabIndex); + } + + /** + * Gets the tab index. + * + * @return the tab index + */ + public int getTabIndex() { + return select.getTabIndex(); + } + + /** + * Sets this select as read only, meaning selection cannot be changed. + * + * @param readOnly + * {@code true} for read only, {@code false} for not read only + */ + public void setReadOnly(boolean readOnly) { + if (this.readOnly != readOnly) { + this.readOnly = readOnly; + updateEnabledState(); + } + } + + /** + * Returns {@code true} if this select is in read only mode, {@code false} + * if not. + * + * @return {@code true} for read only, {@code false} for not read only + */ + public boolean isReadOnly() { + return readOnly; + } + + @Override + public void setEnabled(boolean enabled) { + if (this.enabled != enabled) { + this.enabled = enabled; + updateEnabledState(); + } + } + + @Override + public boolean isEnabled() { + return enabled; + } + + private void updateEnabledState() { + select.setEnabled(isEnabled() && !isReadOnly()); + } + + @Override + public void focus() { + select.setFocus(true); + } +} diff --git a/client/src/main/java/com/vaadin/client/ui/listselect/ListSelectConnector.java b/client/src/main/java/com/vaadin/client/ui/listselect/ListSelectConnector.java new file mode 100644 index 0000000000..3e20b115e0 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/ui/listselect/ListSelectConnector.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.listselect; + +import com.vaadin.client.annotations.OnStateChange; +import com.vaadin.client.connectors.AbstractMultiSelectConnector; +import com.vaadin.client.ui.VListSelect; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.listselect.ListSelectState; +import com.vaadin.ui.ListSelect; + +/** + * Client side connector for {@link ListSelect} component. + * + * @author Vaadin Ltd + * + */ +@Connect(ListSelect.class) +public class ListSelectConnector extends AbstractMultiSelectConnector { + + @Override + public VListSelect getWidget() { + return (VListSelect) super.getWidget(); + } + + @Override + public MultiSelectWidget getMultiSelectWidget() { + return getWidget(); + } + + @Override + public ListSelectState getState() { + return (ListSelectState) super.getState(); + } + + @OnStateChange("readOnly") + void updateReadOnly() { + getWidget().setReadOnly(isReadOnly()); + } + +} |