diff options
author | Denis Anisimov <denis@vaadin.com> | 2014-08-24 14:48:03 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2014-11-11 09:50:52 +0000 |
commit | 3b0ed7a67553ca48e40f9c78da5655256a1fe5ea (patch) | |
tree | a6719a7fec8b9fcbbad56400660f6510e500ddda | |
parent | deebc28ae7069b54e96b03e4067de63df99b78e0 (diff) | |
download | vaadin-framework-3b0ed7a67553ca48e40f9c78da5655256a1fe5ea.tar.gz vaadin-framework-3b0ed7a67553ca48e40f9c78da5655256a1fe5ea.zip |
Update selection after changes in underlying data source (#13580).
Change-Id: I6354d85bd6bc37b1cbb69f388559278d5a163256
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); + } +} |