summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Anisimov <denis@vaadin.com>2014-08-24 14:48:03 +0300
committerVaadin Code Review <review@vaadin.com>2014-11-11 09:50:52 +0000
commit3b0ed7a67553ca48e40f9c78da5655256a1fe5ea (patch)
treea6719a7fec8b9fcbbad56400660f6510e500ddda
parentdeebc28ae7069b54e96b03e4067de63df99b78e0 (diff)
downloadvaadin-framework-3b0ed7a67553ca48e40f9c78da5655256a1fe5ea.tar.gz
vaadin-framework-3b0ed7a67553ca48e40f9c78da5655256a1fe5ea.zip
Update selection after changes in underlying data source (#13580).
Change-Id: I6354d85bd6bc37b1cbb69f388559278d5a163256
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java19
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectValueUpdate.java81
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java10
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRow.java117
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRowTest.java65
5 files changed, 289 insertions, 3 deletions
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java
index b083db3183..2c4dd5be5d 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -1675,6 +1675,8 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
// Clears the item id mapping table
itemIdMapper.removeAll();
+ adjustSelection();
+
// Notify all listeners
fireItemSetChange();
}
@@ -1713,6 +1715,23 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
}
/**
+ * Removes orphaned ids from selection.
+ */
+ protected void adjustSelection() {
+ Object value = getValue();
+ if (isMultiSelect() && (value instanceof Collection)) {
+ Collection<?> collection = (Collection<?>) value;
+ for (Object id : collection) {
+ if (!containsId(id)) {
+ unselect(id);
+ }
+ }
+ } else if (!containsId(value)) {
+ unselect(value);
+ }
+ }
+
+ /**
* Implementation of item set change event.
*/
private static class ItemSetChangeEvent extends EventObject implements
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectValueUpdate.java b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectValueUpdate.java
new file mode 100644
index 0000000000..e81f6e09b6
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestAbstractSelectValueUpdate.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2014 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.server.component.abstractselect;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.ui.AbstractSelect;
+
+public class TestAbstractSelectValueUpdate {
+
+ @Test
+ public void removeItem_deleteItemFromUnderlyingContainer_selectValueIsUpdated() {
+ BeanItemContainer<Object> container = new BeanItemContainer<Object>(
+ Object.class);
+ Object item1 = new Object();
+ Object item2 = new Object();
+ container.addBean(item1);
+ container.addBean(item2);
+ TestSelect select = new TestSelect();
+ select.setContainerDataSource(container);
+
+ select.setValue(item1);
+
+ Assert.assertNotNull("Value is null after selection", select.getValue());
+
+ container.removeItem(item1);
+
+ Assert.assertNull("Value is not null after removal", select.getValue());
+ }
+
+ @Test
+ public void removeItem_multiselectSectionDeleteItemFromUnderlyingContainer_selectValueIsUpdated() {
+ BeanItemContainer<Object> container = new BeanItemContainer<Object>(
+ Object.class);
+ Object item1 = new Object();
+ Object item2 = new Object();
+ container.addBean(item1);
+ container.addBean(item2);
+ TestSelect select = new TestSelect();
+ select.setMultiSelect(true);
+ select.setContainerDataSource(container);
+
+ select.setValue(Collections.singletonList(item1));
+
+ checkSelectedItemsCount(select, 1);
+
+ container.removeItem(item1);
+
+ checkSelectedItemsCount(select, 0);
+ }
+
+ private void checkSelectedItemsCount(TestSelect select, int count) {
+ Assert.assertNotNull("Selected value is null", select.getValue());
+ Assert.assertTrue("Selected value is not a collection",
+ select.getValue() instanceof Collection);
+ Assert.assertEquals("Wrong number of selected items",
+ ((Collection<?>) select.getValue()).size(), count);
+ }
+
+ private class TestSelect extends AbstractSelect {
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java
index 64f1a64558..4bdec81ccf 100644
--- a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java
+++ b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java
@@ -38,7 +38,7 @@ public class TableClickAndDragOnIconAndComponents extends AbstractTestUI {
table.setId("testable-table");
addComponent(table);
for (int i = 0; i < 5; i++) {
- addItemAfter(i + "foo", null);
+ addItemAfter(i + "foo", null, false);
}
table.addGeneratedColumn("Label", new ColumnGenerator() {
@@ -118,14 +118,15 @@ public class TableClickAndDragOnIconAndComponents extends AbstractTestUI {
IndexedContainer container = (IndexedContainer) table
.getContainerDataSource();
+ boolean selected = table.getValue().equals(dragged);
container.removeItem(dragged);
- addItemAfter(dragged, target);
+ addItemAfter(dragged, target, selected);
}
});
}
@SuppressWarnings("unchecked")
- private void addItemAfter(Object itemId, Object afterItemId) {
+ private void addItemAfter(Object itemId, Object afterItemId, boolean select) {
Item item;
if (afterItemId != null) {
item = table.addItemAfter(afterItemId, itemId);
@@ -136,6 +137,9 @@ public class TableClickAndDragOnIconAndComponents extends AbstractTestUI {
item.getItemProperty("red").setValue("red " + itemId);
item.getItemProperty("icon").setValue(
new ThemeResource("../runo/icons/16/ok.png"));
+ if (select) {
+ table.select(itemId);
+ }
}
@Override
diff --git a/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRow.java b/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRow.java
new file mode 100644
index 0000000000..349fbc73fe
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRow.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2000-2014 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.table;
+
+import java.util.Collection;
+
+import com.vaadin.data.util.BeanItemContainer;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.MultiSelectMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+
+/**
+ * Test UI for delete rows operation in multiselect table.
+ *
+ * @author Vaadin Ltd
+ */
+public class TableDeleteSelectedRow extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Table table = new Table();
+ table.setSelectable(true);
+ table.setImmediate(true);
+
+ BeanItemContainer<TableBean> container = createContainer();
+
+ table.setContainerDataSource(container);
+
+ final Label selectedSize = new Label();
+ selectedSize.addStyleName("selected-rows");
+
+ Button changeMode = new Button("Set multiselect", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ table.setMultiSelect(true);
+ table.setMultiSelectMode(MultiSelectMode.SIMPLE);
+
+ BeanItemContainer<TableBean> container = createContainer();
+
+ table.setContainerDataSource(container);
+ }
+ });
+ changeMode.addStyleName("multiselect");
+
+ Button delete = new Button("Delete selected", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (table.getValue() instanceof Collection) {
+ Collection<?> rows = (Collection<?>) table.getValue();
+ for (Object row : rows) {
+ table.getContainerDataSource().removeItem(row);
+ }
+ rows = (Collection<?>) table.getValue();
+ selectedSize.setValue(String.valueOf(rows.size()));
+ } else {
+ table.getContainerDataSource().removeItem(table.getValue());
+ selectedSize.setValue(table.getValue() == null ? "0" : "1");
+ }
+ }
+ });
+ delete.addStyleName("delete");
+
+ addComponents(delete, changeMode, selectedSize, table);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Items deleted via container data source should not be available as selected in the table.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13580;
+ }
+
+ private BeanItemContainer<TableBean> createContainer() {
+ BeanItemContainer<TableBean> container = new BeanItemContainer<TableBean>(
+ TableBean.class);
+ container.addBean(new TableBean("first"));
+ container.addBean(new TableBean("second"));
+ container.addBean(new TableBean("third"));
+ return container;
+ }
+
+ public static class TableBean {
+
+ TableBean(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private String name;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRowTest.java b/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRowTest.java
new file mode 100644
index 0000000000..0e807edf14
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableDeleteSelectedRowTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2014 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.table;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test to check selected rows in multiselect table after deletion.
+ *
+ * @author Vaadin Ltd
+ */
+public class TableDeleteSelectedRowTest extends MultiBrowserTest {
+
+ @Test
+ public void deleteSelectedRows() {
+ openTestURL();
+
+ // Select row in the table
+ findElement(By.className("v-table-row-odd")).click();
+
+ // Delete selected row
+ findElement(By.className("delete")).click();
+
+ WebElement selectedSize = findElement(By.className("selected-rows"));
+ int size = Integer.parseInt(selectedSize.getText());
+
+ Assert.assertEquals(
+ "Non empty collection of selected rows after remove via container",
+ 0, size);
+
+ // Reset table and set multiselect mode
+ findElement(By.className("multiselect")).click();
+
+ // Select row in the table
+ findElement(By.className("v-table-row-odd")).click();
+
+ // Delete selected row
+ findElement(By.className("delete")).click();
+
+ selectedSize = findElement(By.className("selected-rows"));
+ size = Integer.parseInt(selectedSize.getText());
+
+ Assert.assertEquals(
+ "Non empty collection of selected rows after remove via container",
+ 0, size);
+ }
+}