summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorPekka Hyvönen <pekka@vaadin.com>2016-09-27 12:26:15 +0300
committerDenis Anisimov <denis@vaadin.com>2016-09-28 12:59:52 +0000
commitc4b17ca879c0bb51c7da390fcbd25c96b73486fb (patch)
tree524833ebab1553534e3d4ff01cd0fa5cf58db3a7 /client
parent96119ab0224421d69393d9d41ed02900121a683e (diff)
downloadvaadin-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.java263
-rw-r--r--client/src/main/java/com/vaadin/client/ui/listselect/ListSelectConnector.java54
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());
+ }
+
+}