]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add role="grid" and aria-multiselectable to grid (#10009)
authorKnoobie <Knoobie@gmx.de>
Wed, 4 Oct 2017 05:51:31 +0000 (07:51 +0200)
committerHenri Sara <henri.sara@gmail.com>
Wed, 4 Oct 2017 05:51:31 +0000 (08:51 +0300)
Also adds aria-selected for grid rows.

all/src/main/templates/release-notes.html
client/src/main/java/com/vaadin/client/connectors/grid/MultiSelectionModelConnector.java
client/src/main/java/com/vaadin/client/connectors/grid/SingleSelectionModelConnector.java
client/src/main/java/com/vaadin/client/widget/grid/selection/SelectionModel.java
client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java
client/src/main/java/com/vaadin/client/widgets/Escalator.java
client/src/main/java/com/vaadin/client/widgets/Grid.java
uitest/src/main/java/com/vaadin/tests/components/grid/GridAriaMultiselectable.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/grid/GridAriaMultiselectableTest.java [new file with mode: 0644]

index 8db3ef86708b3ee9964b7b1a44b651af3d5470fc..be04a7247aaa4cb39a71ed293a1d62840e732ad7 100644 (file)
         <li>Error indicators are now <tt>&lt;span class="v-errorindicator"&gt;&lt;/span&gt;</tt> elements.</li>
         <li><tt>Embedded</tt> is not a <tt>LegacyComponent</tt> anymore.</li>
         <li><tt>Notification</tt> method <tt>show</tt> returns <tt>Notification</tt>, instead of <tt>void</tt>.</li>
+        <li>The client side <tt>SelectionModel</tt> interface has a new method <tt>isMultiSelectionAllowed</tt>.</li>
 
         <h2>For incompatible or behavior-altering changes in 8.1, please see <a href="https://vaadin.com/download/release/8.1/8.1.0/release-notes.html#incompatible">8.1 release notes</a></h2>
         
index 92b858cb977039aca7a42c6c28d268301d61a212..79a3cac92be4756ba24f891b106416f92d792179 100644 (file)
@@ -121,6 +121,10 @@ public class MultiSelectionModelConnector
             return isSelectionAllowed;
         }
 
+        @Override
+        public boolean isMultiSelectionAllowed() {
+            return true;
+        }
     }
 
     @Override
index 560ccb2d8589d0c4066c2faebf4b879103973020..2320edc8e07260df14d9d386671603a51383b8ed 100644 (file)
@@ -82,6 +82,11 @@ public class SingleSelectionModelConnector
             return isSelectionAllowed;
         }
 
+        @Override
+        public boolean isMultiSelectionAllowed() {
+            return false;
+        }
+
         /**
          * Sets whether it's allowed to deselect the selected row through the
          * UI. Deselection is allowed by default.
index 17763b0a947480e396019fb282c49204c148f663..513ee4949abb7fc6290a1c01e554cc43378433c1 100644 (file)
@@ -58,6 +58,11 @@ public interface SelectionModel<T> {
         public boolean isSelectionAllowed() {
             return false;
         }
+
+        @Override
+        public boolean isMultiSelectionAllowed() {
+            return false;
+        }
     }
 
     /**
@@ -115,6 +120,16 @@ public interface SelectionModel<T> {
      */
     boolean isSelectionAllowed();
 
+    /**
+     * Checks if the user is allowed to have more than on item selected.
+     * <p>
+     *
+     * @return <code>true</code> if the user is allowed to select multiple items,
+     *         <code>false</code> otherwise
+     * @since 8.2
+     */
+    boolean isMultiSelectionAllowed();
+
     /**
      * Gets the selected state from a given grid row json object. This is a
      * helper method for grid selection models.
index 016c701debb604754f9a637cab64e90d7cce3442..cf9d7ea833cee2062a2a477b7732949d1647ebac 100644 (file)
@@ -44,6 +44,13 @@ public class TreeGrid extends Grid<JsonObject> {
      */
     private String depthStyleNamePrefix;
 
+    /**
+     * Creates a new instance.
+     */
+    public TreeGrid() {
+        setAriaRole("treegrid");
+    }
+
     /**
      * Body updater that adds additional style to each row containing depth
      * information inside the hierarchy.
index a46450fe07ddb84069c7e183b9ec9314d606b3f3..640304e82874f2b3f3f3c1b74d729ed748964504 100644 (file)
@@ -6792,6 +6792,16 @@ public class Escalator extends Widget
         return tableWrapper;
     }
 
+    /**
+     * Returns the {@code <table />} element of the grid.
+     *
+     * @return the table element
+     * @since 8.2
+     */
+    public Element getTable() {
+        return getTableWrapper().getFirstChildElement();
+    }
+
     private Element getSubPartElementTableStructure(SubPartArguments args) {
 
         String type = args.getType();
index e4ceac93f87ffc2446525ef230bc3fcca5865d99..81f6756930442c463627db6cc5e164392947e4de 100755 (executable)
@@ -5597,10 +5597,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
 
             rowReference.set(rowIndex, rowData, rowElement);
 
-            if (hasData) {
-                setStyleName(rowElement, rowSelectedStyleName,
-                        isSelected(rowData));
+            boolean isSelected = hasData && isSelected(rowData);
+            if (Grid.this.selectionModel.isSelectionAllowed()) {
+                rowElement.setAttribute("aria-selected", String.valueOf(isSelected));
+            } else {
+                rowElement.removeAttribute("aria-selected");
+            }
 
+            if (hasData) {
+                setStyleName(rowElement, rowSelectedStyleName, isSelected);
                 if (rowStyleGenerator != null) {
                     try {
                         String rowStylename = rowStyleGenerator
@@ -6148,6 +6153,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
         cellFocusHandler = new CellFocusHandler();
 
         setStylePrimaryName(STYLE_NAME);
+        setAriaRole("grid");
 
         escalator.getHeader().setEscalatorUpdater(createHeaderUpdater());
         escalator.getBody().setEscalatorUpdater(createBodyUpdater());
@@ -6308,6 +6314,17 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
         }
     }
 
+    /**
+     * Adds the given role as 'role="$param"' to the {@code <table />} element
+     * of the grid.
+     *
+     * @param role the role param
+     * @since 8.2
+     */
+    protected void setAriaRole(String role){
+        escalator.getTable().setAttribute("role", role);
+    }
+
     /**
      * Creates the escalator updater used to update the header rows in this
      * grid. The updater is invoked when header rows or columns are added or
@@ -7971,6 +7988,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
             setSelectColumnRenderer(null);
         }
 
+        if (this.selectionModel.isMultiSelectionAllowed()) {
+            escalator.getTable().setAttribute("aria-multiselectable", "true");
+        } else if (this.selectionModel.isSelectionAllowed()) {
+            escalator.getTable().setAttribute("aria-multiselectable", "false");
+        } else {
+            escalator.getTable().removeAttribute("aria-multiselectable");
+        }
         // Refresh rendered rows to update selection, if it has changed
         requestRefreshBody();
     }
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridAriaMultiselectable.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridAriaMultiselectable.java
new file mode 100644 (file)
index 0000000..144e518
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.tests.components.grid;
+
+import com.vaadin.data.ValueProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.SelectionMode;
+
+/**
+ * @author Vaadin Ltd
+ *
+ */
+public class GridAriaMultiselectable extends AbstractTestUI {
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Grid<String> grid = new Grid<>();
+        grid.addColumn(ValueProvider.identity());
+        grid.setItems("a", "b");
+        grid.setSelectionMode(SelectionMode.NONE);
+
+        addComponent(grid);
+
+        Button singleSelectBtn = new Button("SingleSelect", event -> {
+            grid.setSelectionMode(SelectionMode.SINGLE);
+        });
+        addComponent(singleSelectBtn);
+
+        Button multiSelectBtn = new Button("MultiSelect", event -> {
+            grid.setSelectionMode(SelectionMode.MULTI);
+        });
+        addComponent(multiSelectBtn);
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridAriaMultiselectableTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridAriaMultiselectableTest.java
new file mode 100644 (file)
index 0000000..eb6cd44
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.tests.components.grid;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Vaadin Ltd
+ */
+public class GridAriaMultiselectableTest extends SingleBrowserTest {
+
+    @Test
+    public void checkAriaMultiselectable() {
+        openTestURL();
+
+        GridElement grid = $(GridElement.class).first();
+
+        Assert.assertTrue("Grid should have the role 'grid'",
+                grid.getHTML().contains("role=\"grid\""));
+        Assert.assertFalse("Grid should not have aria-multiselectable",
+                grid.getHTML().contains("aria-multiselectable"));
+
+        $(ButtonElement.class).caption("SingleSelect").first().click();
+
+        Assert.assertTrue("Grid should have aria-multiselectable 'false'",
+                grid.getHTML().contains("aria-multiselectable=\"false\""));
+
+        $(ButtonElement.class).caption("MultiSelect").first().click();
+
+        Assert.assertTrue("Grid should have aria-multiselectable 'true'",
+                grid.getHTML().contains("aria-multiselectable=\"true\""));
+    }
+}