]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add selection support to NativeSelect
authorJohannes Dahlström <johannesd@vaadin.com>
Thu, 8 Sep 2016 19:49:54 +0000 (22:49 +0300)
committerArtur Signell <artur@vaadin.com>
Mon, 12 Sep 2016 09:36:08 +0000 (09:36 +0000)
Change-Id: Iabe563852150a7d690f6e2edaa40253d03127881

client/src/main/java/com/vaadin/client/ui/VNativeSelect.java
client/src/main/java/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java
server/src/main/java/com/vaadin/ui/NativeSelect.java
uitest/src/main/java/com/vaadin/tests/components/AbstractComponentTest.java
uitest/src/main/java/com/vaadin/tests/components/nativeselect/NativeSelects.java
uitest/src/test/java/com/vaadin/tests/components/nativeselect/NativeSelectTest.java

index 4a3d95c0a5e09f8cce857bb68bbf94c4d6db2581..716450c82afd9a35d37d5bca6b57054cd87fa50b 100644 (file)
@@ -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;
+                }
+            }
+        }
+    }
 }
index afa202e1747c8bba805f25f402ae483a1bd699e1..c61b7efc3c479e5f234a1e26cf843433eb70a0f1 100644 (file)
@@ -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<SelectionModel<?>> {
+        AbstractListingConnector<SelectionModel.Single<?>> {
 
+    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
index 9a400a1a01c23507719e24d81abadb8c248a24b8..be4cbc5e121e5acdb60990390c3172f24e834149 100644 (file)
 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<T> extends AbstractListing<T, SelectionModel<T>> {
+public class NativeSelect<T> extends AbstractSingleSelect<T> {
 
     /**
      * Creates a new {@code NativeSelect} with an empty caption and no items.
@@ -46,21 +43,7 @@ public class NativeSelect<T> extends AbstractListing<T, SelectionModel<T>> {
         addDataGenerator((item, json) -> json.put(
                 DataCommunicatorConstants.DATA, String.valueOf(item)));
 
-        setSelectionModel(new SelectionModel<T>() {
-
-            @Override
-            public Set<T> getSelectedItems() {
-                return Collections.emptySet();
-            }
-
-            @Override
-            public void select(T item) {
-            }
-
-            @Override
-            public void deselect(T item) {
-            }
-        });
+        setSelectionModel(new SimpleSingleSelection());
     }
 
     /**
index 1e0f54bebc37552fc3e85ea2d976b5cd64ca9cb5..de0f70ef887862b255ebb3594cb11cb22d409f19 100644 (file)
@@ -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<T extends AbstractComponent> extends
         }
     }
 
+    protected void createListenerAction(String caption, String category,
+            Function<T, Registration> addListener) {
+
+        createBooleanAction(caption, category, false,
+                new Command<T, Boolean>() {
+                    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<String, Integer> createIntegerOptions(int max) {
         LinkedHashMap<String, Integer> options = new LinkedHashMap<>();
         for (int i = 0; i <= 9 && i <= max; i++) {
index 3338f8156fa344056962749e828c9b691906b9d4..cc1c15b2ce1aed17edca653a8c4646e1170ba8c0 100644 (file)
@@ -11,4 +11,16 @@ public class NativeSelects extends
     protected Class<NativeSelect<Object>> 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())));
+    }
 }
index ae971630ad51da54b804a83c4e773dd3900ec8a2..364e53aa75a98f7610d1762b047777fd9a2fe818 100644 (file)
@@ -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;