From 8588b4a7759dff9a3862079d516f5201be55982c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Dahlstr=C3=B6m?= Date: Thu, 8 Sep 2016 22:49:54 +0300 Subject: [PATCH] Add selection support to NativeSelect Change-Id: Iabe563852150a7d690f6e2edaa40253d03127881 --- .../com/vaadin/client/ui/VNativeSelect.java | 23 +++++++++++++ .../nativeselect/NativeSelectConnector.java | 34 ++++++++++++++++++- .../main/java/com/vaadin/ui/NativeSelect.java | 21 ++---------- .../components/AbstractComponentTest.java | 22 ++++++++++++ .../nativeselect/NativeSelects.java | 12 +++++++ .../nativeselect/NativeSelectTest.java | 33 ++++++++++++++++++ 6 files changed, 125 insertions(+), 20 deletions(-) diff --git a/client/src/main/java/com/vaadin/client/ui/VNativeSelect.java b/client/src/main/java/com/vaadin/client/ui/VNativeSelect.java index 4a3d95c0a5..716450c82a 100644 --- a/client/src/main/java/com/vaadin/client/ui/VNativeSelect.java +++ b/client/src/main/java/com/vaadin/client/ui/VNativeSelect.java @@ -15,6 +15,8 @@ */ package com.vaadin.client.ui; +import java.util.Objects; + import com.google.gwt.user.client.ui.ListBox; import com.vaadin.shared.ui.nativeselect.NativeSelectState; @@ -31,4 +33,25 @@ public class VNativeSelect extends ListBox { public VNativeSelect() { setStyleName(NativeSelectState.STYLE_NAME); } + + /** + * Sets the selected item by its value. If given {@code null}, removes + * selection. + * + * @param value + * the value of the item to select or {@code null} to select + * nothing + */ + public void setSelectedItem(String value) { + if (value == null) { + setSelectedIndex(-1); + } else { + for (int i = 0; i < getItemCount(); i++) { + if (Objects.equals(value, getValue(i))) { + setSelectedIndex(i); + break; + } + } + } + } } diff --git a/client/src/main/java/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java b/client/src/main/java/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java index afa202e174..c61b7efc3c 100644 --- a/client/src/main/java/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java @@ -16,6 +16,7 @@ package com.vaadin.client.ui.nativeselect; +import com.google.gwt.event.shared.HandlerRegistration; import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.connectors.AbstractListingConnector; import com.vaadin.client.data.DataSource; @@ -23,7 +24,9 @@ import com.vaadin.client.ui.VNativeSelect; import com.vaadin.shared.Range; import com.vaadin.shared.Registration; import com.vaadin.shared.data.selection.SelectionModel; +import com.vaadin.shared.data.selection.SelectionServerRpc; import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.nativeselect.NativeSelectState; import elemental.json.JsonObject; @@ -39,10 +42,29 @@ import elemental.json.JsonObject; */ @Connect(com.vaadin.ui.NativeSelect.class) public class NativeSelectConnector extends - AbstractListingConnector> { + AbstractListingConnector> { + private HandlerRegistration selectionChangeRegistration; private Registration dataChangeRegistration; + private final SelectionServerRpc selectionRpc = getRpcProxy( + SelectionServerRpc.class); + + @Override + protected void init() { + super.init(); + + selectionChangeRegistration = getWidget().addChangeHandler( + e -> selectionRpc.select(getWidget().getSelectedValue())); + } + + @Override + public void onUnregister() { + super.onUnregister(); + selectionChangeRegistration.removeHandler(); + selectionChangeRegistration = null; + } + @Override public VNativeSelect getWidget() { return (VNativeSelect) super.getWidget(); @@ -64,6 +86,16 @@ public class NativeSelectConnector extends getWidget().setEnabled(isEnabled() && !isReadOnly()); } + @OnStateChange("selectedItemKey") + void updateSelectedItem() { + getWidget().setSelectedItem(getState().selectedItemKey); + } + + @Override + public NativeSelectState getState() { + return (NativeSelectState) super.getState(); + } + /** * A data change handler registered to the data source. Updates the data * items and selection status when the data source notifies of new changes diff --git a/server/src/main/java/com/vaadin/ui/NativeSelect.java b/server/src/main/java/com/vaadin/ui/NativeSelect.java index 9a400a1a01..be4cbc5e12 100644 --- a/server/src/main/java/com/vaadin/ui/NativeSelect.java +++ b/server/src/main/java/com/vaadin/ui/NativeSelect.java @@ -17,12 +17,9 @@ package com.vaadin.ui; import java.util.Collection; -import java.util.Collections; -import java.util.Set; import com.vaadin.server.data.DataSource; import com.vaadin.shared.data.DataCommunicatorConstants; -import com.vaadin.shared.data.selection.SelectionModel; import com.vaadin.shared.ui.nativeselect.NativeSelectState; /** @@ -37,7 +34,7 @@ import com.vaadin.shared.ui.nativeselect.NativeSelectState; * * @see com.vaadin.ui.ComboBox */ -public class NativeSelect extends AbstractListing> { +public class NativeSelect extends AbstractSingleSelect { /** * Creates a new {@code NativeSelect} with an empty caption and no items. @@ -46,21 +43,7 @@ public class NativeSelect extends AbstractListing> { addDataGenerator((item, json) -> json.put( DataCommunicatorConstants.DATA, String.valueOf(item))); - setSelectionModel(new SelectionModel() { - - @Override - public Set getSelectedItems() { - return Collections.emptySet(); - } - - @Override - public void select(T item) { - } - - @Override - public void deselect(T item) { - } - }); + setSelectionModel(new SimpleSingleSelection()); } /** diff --git a/uitest/src/main/java/com/vaadin/tests/components/AbstractComponentTest.java b/uitest/src/main/java/com/vaadin/tests/components/AbstractComponentTest.java index 1e0f54bebc..de0f70ef88 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/AbstractComponentTest.java +++ b/uitest/src/main/java/com/vaadin/tests/components/AbstractComponentTest.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.function.Function; import com.vaadin.annotations.Theme; import com.vaadin.event.FieldEvents.BlurEvent; @@ -19,6 +20,7 @@ import com.vaadin.event.FieldEvents.FocusNotifier; import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.Registration; import com.vaadin.tests.util.Log; import com.vaadin.tests.util.LoremIpsum; import com.vaadin.ui.AbstractComponent; @@ -676,6 +678,26 @@ public abstract class AbstractComponentTest extends } } + protected void createListenerAction(String caption, String category, + Function addListener) { + + createBooleanAction(caption, category, false, + new Command() { + Registration registration; + + @Override + public void execute(T c, Boolean enabled, + Object data) { + if (enabled) { + registration = addListener.apply(c); + } else if (registration != null) { + registration.remove(); + registration = null; + } + } + }); + } + protected LinkedHashMap createIntegerOptions(int max) { LinkedHashMap options = new LinkedHashMap<>(); for (int i = 0; i <= 9 && i <= max; i++) { diff --git a/uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelects.java b/uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelects.java index 3338f8156f..cc1c15b2ce 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelects.java +++ b/uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelects.java @@ -11,4 +11,16 @@ public class NativeSelects extends protected Class> getTestClass() { return (Class) NativeSelect.class; } + + @Override + protected void createActions() { + super.createActions(); + createListenerMenu(); + } + + protected void createListenerMenu() { + createListenerAction("Selection listener", "Listeners", + c -> c.addSelectionListener( + e -> log("Selected: " + e.getValue()))); + } } diff --git a/uitest/src/test/java/com/vaadin/tests/components/nativeselect/NativeSelectTest.java b/uitest/src/test/java/com/vaadin/tests/components/nativeselect/NativeSelectTest.java index ae971630ad..364e53aa75 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/nativeselect/NativeSelectTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/nativeselect/NativeSelectTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.customelements.NativeSelectElement; +import com.vaadin.testbench.elements.AbstractComponentElement.ReadOnlyException; import com.vaadin.tests.tb3.MultiBrowserTest; public class NativeSelectTest extends MultiBrowserTest { @@ -48,6 +49,38 @@ public class NativeSelectTest extends MultiBrowserTest { assertItems(100); } + @Test + public void selectItemProgrammatically_correctItemSelected() { + selectMenuPath("Component", "Selection", "Select", "Item 2"); + + assertEquals("Selected item", "Item 2", getSelect().getValue()); + } + + @Test + public void selectionListenerAdded_selectItem_listenerInvoked() { + selectMenuPath("Component", "Listeners", "Selection listener"); + + getSelect().selectByText("Item 5"); + + assertEquals("1. Selected: Item 5", getLogRow(0)); + } + + @Test + public void selectionListenerRemoved_selectItem_listenerNotInvoked() { + selectMenuPath("Component", "Listeners", "Selection listener"); + selectMenuPath("Component", "Listeners", "Selection listener"); + + getSelect().selectByText("Item 5"); + + assertEquals("1. Command: /Selection listener(false)", getLogRow(0)); + } + + @Test(expected = ReadOnlyException.class) + public void setReadOnly_trySelectItem_throws() { + selectMenuPath("Component", "State", "Readonly"); + getSelect().selectByText("Item 5"); + } + @Override protected Class getUIClass() { return NativeSelects.class; -- 2.39.5