]> source.dussan.org Git - vaadin-framework.git/commitdiff
Table / TreeTable multiselect disabling of touch detection (#11641)
authorOlli Tietäväinen <ollit@vaadin.com>
Mon, 1 Jul 2019 12:17:59 +0000 (15:17 +0300)
committerGitHub <noreply@github.com>
Mon, 1 Jul 2019 12:17:59 +0000 (15:17 +0300)
* Fixes #11601. Add toggle for disabling touch detection on table multiselect.

* fix tests

client/src/main/java/com/vaadin/client/ui/VScrollTable.java
server/src/main/java/com/vaadin/ui/Table.java
uitest/src/main/java/com/vaadin/tests/components/table/CtrlShiftMultiselect.java
uitest/src/main/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabled.java [new file with mode: 0644]
uitest/src/main/java/com/vaadin/tests/components/treetable/TreeTableMultiselect.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxClosePopupRetainTextTest.java
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java
uitest/src/test/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabledTest.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/treetable/TreeTableMultiselectTest.java [new file with mode: 0644]

index 3659bf6bb70d44015a7a82dbfa6598625ab39dd6..26155c5bd6afe4a6b2ed90bb4f8b4688ea8e9857 100644 (file)
@@ -338,6 +338,8 @@ public class VScrollTable extends FlowPanel
 
     private SelectMode selectMode = SelectMode.NONE;
 
+    private boolean multiSelectTouchDetectionEnabled = true;
+
     public final HashSet<String> selectedRowKeys = new HashSet<String>();
 
     /*
@@ -1483,6 +1485,9 @@ public class VScrollTable extends FlowPanel
             } else {
                 selectMode = SelectMode.NONE;
             }
+            if (uidl.hasAttribute("touchdetection")) {
+                multiSelectTouchDetectionEnabled = uidl.getBooleanAttribute("touchdetection");
+            }
         }
     }
 
@@ -1936,9 +1941,9 @@ public class VScrollTable extends FlowPanel
     }
 
     private void setMultiSelectMode(int multiselectmode) {
-        if (BrowserInfo.get().isTouchDevice()) {
+        if (BrowserInfo.get().isTouchDevice() && multiSelectTouchDetectionEnabled) {
             // Always use the simple mode for touch devices that do not have
-            // shift/ctrl keys
+            // shift/ctrl keys (unless this feature is explicitly disabled)
             this.multiselectmode = MULTISELECT_MODE_SIMPLE;
         } else {
             this.multiselectmode = multiselectmode;
index a2496a5c4f21071de1bc0cc5b5fcc84d81fcc34c..930a152c61939fa819141327640e8f16a2f89ce3 100644 (file)
@@ -577,6 +577,8 @@ public class Table extends AbstractSelect implements Action.Container,
 
     private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT;
 
+    private boolean multiSelectTouchDetectionEnabled = true;
+
     private boolean rowCacheInvalidated;
 
     private RowGenerator rowGenerator = null;
@@ -3774,6 +3776,9 @@ public class Table extends AbstractSelect implements Action.Container,
         if (isSelectable()) {
             target.addAttribute("selectmode",
                     (isMultiSelect() ? "multi" : "single"));
+            if (isMultiSelect()) {
+                target.addAttribute("touchdetection", isMultiSelectTouchDetectionEnabled());
+            }
         } else {
             target.addAttribute("selectmode", "none");
         }
@@ -5185,7 +5190,10 @@ public class Table extends AbstractSelect implements Action.Container,
      * <p>
      * Note, that on some clients the mode may not be respected. E.g. on touch
      * based devices CTRL/SHIFT base selection method is invalid, so touch based
-     * browsers always use the {@link MultiSelectMode#SIMPLE}.
+     * browsers always use the {@link MultiSelectMode#SIMPLE} unless touch multi
+     * select is explicitly disabled .
+     *
+     * @see #setMultiSelectTouchDetectionEnabled(boolean)
      *
      * @param mode
      *            The select mode of the table
@@ -5204,6 +5212,31 @@ public class Table extends AbstractSelect implements Action.Container,
         return multiSelectMode;
     }
 
+    /**
+     * Default behavior on touch-reporting devices is to switch from CTRL/SHIFT
+     * based multi-selection to simple mode, but you can use this method to
+     * explicitly disable the touch device detection. Thus you can keep using
+     * keyboard-based multi selection on hybrid devices that have both a touch
+     * screen and a keyboard.
+     *
+     * @param multiSelectTouchDetectionEnabled
+     *               Whether to enable or disable touch screen detection
+     */
+    public void setMultiSelectTouchDetectionEnabled(boolean multiSelectTouchDetectionEnabled) {
+        this.multiSelectTouchDetectionEnabled = multiSelectTouchDetectionEnabled;
+        markAsDirty();
+    }
+
+    /**
+     * Returns if touch screen detection is used to toggle multi select mode.
+     *
+     * @return
+     *              If touch screen detection for multi select is enabled
+     */
+    public boolean isMultiSelectTouchDetectionEnabled() {
+        return multiSelectTouchDetectionEnabled;
+    }
+
     /**
      * Lazy loading accept criterion for Table. Accepted target rows are loaded
      * from server once per drag and drop operation. Developer must override one
index b9e23930e422bb90d06523926b8663835c9327d0..04838b9a88bcbb30af2b0da17510ae2a8137ed14 100644 (file)
@@ -10,10 +10,10 @@ import com.vaadin.ui.Table.TableDragMode;
 @SuppressWarnings("serial")
 public class CtrlShiftMultiselect extends TestBase {
 
+    protected final Table table = new Table("Multiselectable table");
+
     @Override
     protected void setup() {
-        final Table table = new Table("Multiselectable table");
-
         table.setContainerDataSource(createContainer());
         table.setImmediate(true);
 
diff --git a/uitest/src/main/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabled.java b/uitest/src/main/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabled.java
new file mode 100644 (file)
index 0000000..9b410af
--- /dev/null
@@ -0,0 +1,47 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.TableDragMode;
+
+import java.util.Set;
+
+@SuppressWarnings("serial")
+public class CtrlShiftMultiselectTouchDetectionDisabled extends CtrlShiftMultiselect {
+
+    protected Label label;
+
+    @Override
+    protected void setup() {
+        super.setup();
+        label = new Label("0");
+        label.setId("count");
+        label.setCaption("Amount of selected items");
+        table.setMultiSelectTouchDetectionEnabled(false);
+        table.addValueChangeListener(new Property.ValueChangeListener() {
+            @Override
+            public void valueChange(Property.ValueChangeEvent event) {
+                Property property = event.getProperty();
+                Set set = (Set) property.getValue();
+                label.setValue("" + set.size());
+            }
+        });
+        addComponent(label);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Allow disabling multi selection's touch screen detection for hybrid devices";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 11601;
+    }
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/treetable/TreeTableMultiselect.java b/uitest/src/main/java/com/vaadin/tests/components/treetable/TreeTableMultiselect.java
new file mode 100644 (file)
index 0000000..7b19d29
--- /dev/null
@@ -0,0 +1,64 @@
+package com.vaadin.tests.components.treetable;
+
+import com.vaadin.data.Property;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TreeTable;
+
+import java.util.Set;
+
+import static com.vaadin.server.Sizeable.Unit.PIXELS;
+
+public class TreeTableMultiselect extends AbstractTestUI {
+
+    protected final TreeTable tt = new TreeTable("Multiselectable treetable");
+    protected Label label;
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        label = new Label("0");
+        label.setCaption("Amount of selected items");
+        label.setId("count");
+
+        tt.setImmediate(true);
+        tt.addContainerProperty("Foo", String.class, "");
+        tt.setColumnWidth("Foo", 100);
+        tt.addContainerProperty("Bar", String.class, "");
+        tt.setColumnWidth("Bar", 100);
+        tt.setHeight(400, PIXELS);
+        Object item1 = tt.addItem(new Object[]{"Foo", "Bar"}, null);
+        Object item2 = tt.addItem(new Object[]{"Foo2", "Bar2"}, null);
+        Object item3 = tt.addItem(new Object[]{"Foo3", "Bar3"}, null);
+        tt.setParent(item2, item1);
+        tt.setParent(item3, item1);
+        tt.setCollapsed(item1, false);
+        tt.setSelectable(true);
+        tt.setMultiSelect(true);
+        tt.setMultiSelectTouchDetectionEnabled(false);
+        tt.setWidth("400px");
+        tt.setHeight("400px");
+        tt.addValueChangeListener(new Property.ValueChangeListener() {
+            @Override
+            public void valueChange(Property.ValueChangeEvent event) {
+                Property property = event.getProperty();
+                Set set = (Set) property.getValue();
+                label.setValue("" + set.size());
+            }
+        });
+
+        addComponent(tt);
+        addComponent(label);
+    }
+
+    @Override
+    public String getDescription() {
+        return "Allow disabling multi selection's touch screen detection for hybrid devices";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 11601;
+    }
+
+}
index 532b6929aecc82f7e41a4f81bf2b46a5fb708414..d71d954868f21c612e72af2e8a84475f6bb52291 100644 (file)
@@ -34,7 +34,7 @@ public class ComboBoxClosePopupRetainTextTest extends MultiBrowserTest {
         ComboBoxElement cb = $(ComboBoxElement.class).first();
         cb.selectByText("Item 3");
         WebElement textbox = cb.findElement(By.vaadin("#textbox"));
-        textbox.clear();
+        cb.clear();
         textbox.sendKeys("I");
         cb.openPopup();
         // Entered value should remain in the text field even though the popup
index 98651437e0499620c2a9c5c1061a659a033b2ea2..bdb47da998dffabca19bf70eaf702955157d0496 100644 (file)
@@ -20,6 +20,7 @@ public class ComboboxMenuBarAutoopenTest extends MultiBrowserTest {
 
     @Test
     public void closeComboboxPopupOnClickToMenuBar() {
+        setDebug(true);
         openTestURL();
 
         openPopup();
diff --git a/uitest/src/test/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabledTest.java b/uitest/src/test/java/com/vaadin/tests/components/table/CtrlShiftMultiselectTouchDetectionDisabledTest.java
new file mode 100644 (file)
index 0000000..485c257
--- /dev/null
@@ -0,0 +1,46 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class CtrlShiftMultiselectTouchDetectionDisabledTest extends MultiBrowserTest {
+
+    @Override
+    public List<DesiredCapabilities> getBrowsersToTest() {
+        return getBrowserCapabilities(Browser.IE11);
+    }
+
+    @Override
+    protected boolean requireWindowFocusForIE() {
+        return true;
+    }
+
+    @Test
+    public void testSelectedCount() {
+        openTestURL();
+        clickRow(3);
+        new Actions(driver).keyDown(Keys.SHIFT).perform();
+        clickRow(8);
+        new Actions(driver).keyUp(Keys.SHIFT).perform();
+        new Actions(driver).release().perform();
+        LabelElement labelElement = $(LabelElement.class).id("count");
+        assertEquals("6", labelElement.getText());
+
+    }
+
+    private void clickRow(int index) {
+        TableElement tableElement = $(TableElement.class).first();
+        tableElement.getRow(index).click();
+    }
+
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/treetable/TreeTableMultiselectTest.java b/uitest/src/test/java/com/vaadin/tests/components/treetable/TreeTableMultiselectTest.java
new file mode 100644 (file)
index 0000000..7ba8149
--- /dev/null
@@ -0,0 +1,46 @@
+package com.vaadin.tests.components.treetable;
+
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TreeTableElement;
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class TreeTableMultiselectTest extends MultiBrowserTest {
+
+
+    @Override
+    public List<DesiredCapabilities> getBrowsersToTest() {
+        return getBrowserCapabilities(Browser.IE11);
+    }
+
+    @Override
+    protected boolean requireWindowFocusForIE() {
+        return true;
+    }
+
+    @Test
+    public void testSelectedCount() {
+        openTestURL();
+        clickRow(0);
+        new Actions(driver).keyDown(Keys.SHIFT).perform();
+        clickRow(1);
+        new Actions(driver).keyUp(Keys.SHIFT).perform();
+        new Actions(driver).release().perform();
+        LabelElement labelElement = $(LabelElement.class).id("count");
+        assertEquals("2", labelElement.getText());
+    }
+
+    private void clickRow(int index) {
+        TreeTableElement treeTable = $(TreeTableElement.class).first();
+        treeTable.getRow(index).click();
+    }
+
+}