diff options
author | Denis <denis@vaadin.com> | 2016-12-15 12:40:54 +0200 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2016-12-15 12:40:54 +0200 |
commit | 809a486c60a680d31308ffd078e6f8036252a990 (patch) | |
tree | 75a3d7481a12d042606316fad190130ada181b62 /compatibility-server | |
parent | 616e1f8ce5e544693268f54a2ac4cec2158d4a19 (diff) | |
download | vaadin-framework-809a486c60a680d31308ffd078e6f8036252a990.tar.gz vaadin-framework-809a486c60a680d31308ffd078e6f8036252a990.zip |
Migrate 7.7.5 branch patches to v8. (#7969)
* Prevent adding several scrollbar handlers (#19189).
Change-Id: Ib0cc6c6835aab6d263f153362a328bcf2be7bc5c
* Prevent adding several scrollbar handlers (#19189).
* Keep expand ratio for last row/column when reducing grid layout size (#20297)
Change-Id: Iff53a803596f4fc1eae8e4bfa307b9c1f4df961a
* Fixed drag and drop failure when message dragged from email client (#20451)
When dragging message form email client on Windows, item.webkitGetAsEntry()
might return null creating NPE on the client side. Added additional checks
for this situation.
Change-Id: I569f7e6d0d7b137f24be53d1fbce384695ae8c73
* Change expected pre-release version number pattern in publish report
Change-Id: Icdacecc490d2490ea9e262f5c5736c1dece2a89d
* Mark TextField/TextArea as busy when a text change event is pending
(#20469)
Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
# Conflicts:
# client/src/main/java/com/vaadin/client/ui/VTextField.java
# uitest/src/main/java/com/vaadin/tests/components/textfield/TextChangeEvents.java
* Fixed touch scrolling issue in Surface and WP devices (#18737)
Fixed by using pointerevents instead of touchevents when the browser is
IE11,
or Edge. Also added touch-action: none; css rules into escalator.css to
prevent
default touch behaviour on IE11 and Edge. Does not affect IE8 to IE10
browsers,
behaviour on those will stay the same as before the fix.
No new unit tests since we do not have automatic touch testing
possibilities yet.
Please test manually with Surface: IE11 and Edge, use for example
uitest:
com.vaadin.tests.components.grid.basics.GridBasicsomponents.grid.basics.GridBasics
Change-Id: Iddbf1852e6ffafc855f749d6f4ebb235ed0f5703
* Add lazy/simple resize mode to Grid (#20108)
Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4
# Conflicts:
# client/src/main/java/com/vaadin/client/connectors/GridConnector.java
# client/src/main/java/com/vaadin/client/widgets/Grid.java
# server/src/main/java/com/vaadin/ui/Grid.java
# shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java
# themes/src/main/themes/VAADIN/themes/base/grid/grid.scss
# uitest/src/main/java/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java
Change-Id: Ieca56121875198ed559a41c143b28926e2695433
* Fix NPE in case some items don't contain all properties of Grid.
This could occur in when parent is a different entity than its children
in hierarchical data.
Change-Id: Icd53b5b5e5544a3680d0cd99702ab78224b2dc08
# Conflicts:
# server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
# server/src/main/java/com/vaadin/ui/Grid.java
* Mark TextField/TextArea as busy when a text change event is pending
(#20469)
Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
# Conflicts:
# client/src/main/java/com/vaadin/client/ui/VTextField.java
# uitest/src/test/java/com/vaadin/tests/components/textfield/TextChangeEventsTest.java
* Add lazy/simple resize mode to Grid (#20108)
Change-Id: I47427efc28c350382dba8c1f50fd332a3f4585e4
* Removed V8 VTextField unused import, forgotten @RunLocally.
* Don't rely on selenium "sendKeys" behavior.
* Revert "Change expected pre-release version number pattern in publish report"
This reverts commit 8df27b952dddb691aead6a633c5b3724c98bf343.
* Migrate TextField/TextArea patch from 7.7 to master (modern components)
Mark TextField/TextArea as busy when a text change event is pending
(#20469)
Change-Id: I404985ae0be1e7dc65171b610032f8649e700f50
Diffstat (limited to 'compatibility-server')
3 files changed, 441 insertions, 18 deletions
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/data/fieldgroup/FieldGroup.java b/compatibility-server/src/main/java/com/vaadin/v7/data/fieldgroup/FieldGroup.java index 1055d1921d..553bbc753c 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/data/fieldgroup/FieldGroup.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/data/fieldgroup/FieldGroup.java @@ -99,6 +99,13 @@ public class FieldGroup implements Serializable { public void setItemDataSource(Item itemDataSource) { this.itemDataSource = itemDataSource; + bindFields(); + } + + /** + * Binds all fields to the properties in the item in use. + */ + protected void bindFields() { for (Field<?> f : fieldToPropertyId.keySet()) { bind(f, fieldToPropertyId.get(f)); } @@ -254,20 +261,7 @@ public class FieldGroup implements Serializable { fieldToPropertyId.put(field, propertyId); propertyIdToField.put(propertyId, field); if (itemDataSource == null) { - // Clear any possible existing binding to clear the field - field.setPropertyDataSource(null); - boolean fieldReadOnly = field.isReadOnly(); - if (!fieldReadOnly) { - field.clear(); - } else { - // Temporarily make the field read-write so we can clear the - // value. Needed because setPropertyDataSource(null) does not - // currently clear the field - // (https://dev.vaadin.com/ticket/14733) - field.setReadOnly(false); - field.clear(); - field.setReadOnly(true); - } + clearField(field); // Will be bound when data source is set return; @@ -279,6 +273,29 @@ public class FieldGroup implements Serializable { } /** + * Clears field and any possible existing binding. + * + * @param field + * The field to be cleared + */ + protected void clearField(Field<?> field) { + // Clear any possible existing binding to clear the field + field.setPropertyDataSource(null); + boolean fieldReadOnly = field.isReadOnly(); + if (!fieldReadOnly) { + field.clear(); + } else { + // Temporarily make the field read-write so we can clear the + // value. Needed because setPropertyDataSource(null) does not + // currently clear the field + // (https://dev.vaadin.com/ticket/14733) + field.setReadOnly(false); + field.clear(); + field.setReadOnly(true); + } + } + + /** * Wrap property to transactional property. */ protected <T> Property.Transactional<T> wrapInTransactionalProperty( diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java index f5399f60ce..e48e58824f 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java @@ -104,6 +104,7 @@ import com.vaadin.v7.event.SelectionEvent.SelectionListener; import com.vaadin.v7.event.SelectionEvent.SelectionNotifier; import com.vaadin.v7.server.communication.data.DataGenerator; import com.vaadin.v7.server.communication.data.RpcDataProviderExtension; +import com.vaadin.v7.shared.ui.grid.ColumnResizeMode; import com.vaadin.v7.shared.ui.grid.EditorClientRpc; import com.vaadin.v7.shared.ui.grid.EditorServerRpc; import com.vaadin.v7.shared.ui.grid.GridClientRpc; @@ -566,6 +567,35 @@ public class Grid extends AbstractComponent } return field; } + + @Override + protected void bindFields() { + List<Field<?>> fields = new ArrayList<>(getFields()); + Item itemDataSource = getItemDataSource(); + + if (itemDataSource == null) { + unbindFields(fields); + } else { + bindFields(fields, itemDataSource); + } + } + + private void unbindFields(List<Field<?>> fields) { + for (Field<?> field : fields) { + clearField(field); + unbind(field); + field.setParent(null); + } + } + + private void bindFields(List<Field<?>> fields, Item itemDataSource) { + for (Field<?> field : fields) { + if (itemDataSource + .getItemProperty(getPropertyId(field)) != null) { + bind(field, getPropertyId(field)); + } + } + } } /** @@ -2242,8 +2272,9 @@ public class Grid extends AbstractComponent Renderer<?> renderer = column.getRenderer(); Item item = cell.getItem(); - Object modelValue = item.getItemProperty(cell.getPropertyId()) - .getValue(); + Property itemProperty = item.getItemProperty(cell.getPropertyId()); + Object modelValue = itemProperty == null ? null + : itemProperty.getValue(); data.put(columnKeys.key(cell.getPropertyId()), AbstractRenderer .encodeValue(modelValue, renderer, converter, getLocale())); @@ -4583,6 +4614,12 @@ public class Grid extends AbstractComponent private boolean editorSaving = false; private FieldGroup editorFieldGroup = new CustomFieldGroup(); + /** + * Poperty ID to Field mapping that stores editor fields set by + * {@link #setEditorField(Object, Field)}. + */ + private Map<Object, Field<?>> editorFields = new HashMap<>(); + private CellStyleGenerator cellStyleGenerator; private RowStyleGenerator rowStyleGenerator; @@ -5286,6 +5323,27 @@ public class Grid extends AbstractComponent } /** + * Sets the column resize mode to use. The default mode is + * {@link ColumnResizeMode#ANIMATED}. + * + * @param mode + * a ColumnResizeMode value + */ + public void setColumnResizeMode(ColumnResizeMode mode) { + getState().columnResizeMode = mode; + } + + /** + * Returns the current column resize mode. The default mode is + * {@link ColumnResizeMode#ANIMATED}. + * + * @return a ColumnResizeMode value + */ + public ColumnResizeMode getColumnResizeMode() { + return getState(false).columnResizeMode; + } + + /** * Creates a new column based on a property id and appends it as the last * column. * @@ -6868,6 +6926,16 @@ public class Grid extends AbstractComponent Field<?> editor = editorFieldGroup.getField(propertyId); + // If field group has no field for this property, see if we have it + // stored + if (editor == null) { + editor = editorFields.get(propertyId); + if (editor != null) { + editorFieldGroup.bind(editor, propertyId); + } + } + + // Otherwise try to build one try { if (editor == null) { editor = editorFieldGroup.buildAndBind(propertyId); @@ -6923,8 +6991,9 @@ public class Grid extends AbstractComponent editorFieldGroup.setItemDataSource(item); for (Column column : getColumns()) { - column.getState().editorConnector = getEditorField( - column.getPropertyId()); + column.getState().editorConnector = item + .getItemProperty(column.getPropertyId()) == null ? null + : getEditorField(column.getPropertyId()); } editorActive = true; @@ -6953,6 +7022,9 @@ public class Grid extends AbstractComponent field.setParent(this); editorFieldGroup.bind(field, propertyId); } + + // Store field for this property for future reference + editorFields.put(propertyId, field); } /** diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/GridEditorMissingPropertyTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/GridEditorMissingPropertyTest.java new file mode 100644 index 0000000000..be6334f8cc --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/GridEditorMissingPropertyTest.java @@ -0,0 +1,334 @@ +/* + * 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.v7.tests.server.component.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.fieldgroup.FieldGroup; +import com.vaadin.v7.data.util.AbstractInMemoryContainer; +import com.vaadin.v7.data.util.BeanItem; +import com.vaadin.v7.ui.Field; +import com.vaadin.v7.ui.PasswordField; +import com.vaadin.v7.ui.TextField; + +public class GridEditorMissingPropertyTest { + + private static final String PROPERTY_NAME = "name"; + private static final String PROPERTY_SIZE = "size"; + + private static final String FOLDER_NAME_BEFORE = "Folder name"; + private static final String FOLDER_NAME_AFTER = "Modified folder name"; + private static final String FILE_NAME_BEFORE = "File name"; + private static final String FILE_NAME_AFTER = "Modified file name"; + private static final String FILE_SIZE_BEFORE = "10kB"; + private static final String FILE_SIZE_AFTER = "20MB"; + + private final Grid grid = new Grid(); + + // Test items + private final Folder folder = new Folder(FOLDER_NAME_BEFORE); + private final File file = new File(FILE_NAME_BEFORE, FILE_SIZE_BEFORE); + + @Before + public void setup() throws SecurityException, NoSuchMethodException { + final BeanItem<Entry> folderItem = new BeanItem<>(folder); + final BeanItem<Entry> childItem = new BeanItem<>(file); + + @SuppressWarnings("unchecked") + TestContainer container = new TestContainer( + Arrays.asList(folderItem, childItem), + Arrays.asList(PROPERTY_NAME, PROPERTY_SIZE)); + + grid.setContainerDataSource(container); + grid.setSelectionMode(Grid.SelectionMode.SINGLE); + grid.setEditorEnabled(true); + } + + @Test + public void testBindFields() { + FieldGroup fieldGroup = grid.getEditorFieldGroup(); + + // Item with incomplete property set + fieldGroup.setItemDataSource( + grid.getContainerDataSource().getItem(folder)); + grid.getColumn(PROPERTY_NAME).getEditorField(); // called in + // grid.doEditItem + assertTrue("Properties in item should be bound", + fieldGroup.getBoundPropertyIds().contains(PROPERTY_NAME)); + assertFalse("Properties not present in item should not be bound", + fieldGroup.getBoundPropertyIds().contains(PROPERTY_SIZE)); + assertTrue("All of item's properties should be bound", + fieldGroup.getUnboundPropertyIds().isEmpty()); + + // Unbind all fields + fieldGroup.setItemDataSource(null); + assertTrue("No properties should be bound", + fieldGroup.getBoundPropertyIds().isEmpty()); + assertTrue("No unbound properties should exist", + fieldGroup.getUnboundPropertyIds().isEmpty()); + + // Item with complete property set + fieldGroup + .setItemDataSource(grid.getContainerDataSource().getItem(file)); + grid.getColumn(PROPERTY_NAME).getEditorField(); + grid.getColumn(PROPERTY_SIZE).getEditorField(); + assertTrue("Properties in item should be bound", + fieldGroup.getBoundPropertyIds().contains(PROPERTY_NAME)); + assertTrue("Properties in item should be bound", + fieldGroup.getBoundPropertyIds().contains(PROPERTY_SIZE)); + assertTrue("All of item's properties should be bound", + fieldGroup.getUnboundPropertyIds().isEmpty()); + + // Unbind all fields + fieldGroup.setItemDataSource(null); + assertTrue("No properties should be bound", + fieldGroup.getBoundPropertyIds().isEmpty()); + assertTrue("No unbound properties should exist", + fieldGroup.getUnboundPropertyIds().isEmpty()); + } + + @Test + public void testSetEditorField() { + FieldGroup fieldGroup = grid.getEditorFieldGroup(); + Field editorField = new PasswordField(); + + // Explicitly set editor field + fieldGroup.setItemDataSource( + grid.getContainerDataSource().getItem(folder)); + grid.getColumn(PROPERTY_NAME).setEditorField(editorField); + assertTrue("Editor field should be the one that was previously set", + grid.getColumn(PROPERTY_NAME).getEditorField() == editorField); + + // Reset item + fieldGroup.setItemDataSource(null); + fieldGroup + .setItemDataSource(grid.getContainerDataSource().getItem(file)); + assertTrue("Editor field should be the one that was previously set", + grid.getColumn(PROPERTY_NAME).getEditorField() == editorField); + } + + @Test + public void testEditCell() { + // Row with missing property + startEdit(folder); + assertEquals(folder, grid.getEditedItemId()); + assertEquals(getEditedItem(), + grid.getEditorFieldGroup().getItemDataSource()); + + assertEquals(FOLDER_NAME_BEFORE, + grid.getColumn(PROPERTY_NAME).getEditorField().getValue()); + try { + grid.getColumn(PROPERTY_SIZE).getEditorField(); + fail("Grid.editorFieldGroup should throw BindException by default"); + } catch (FieldGroup.BindException e) { + // BindException is thrown using the default FieldGroup + } + grid.cancelEditor(); + + // Row with all properties + startEdit(file); + assertEquals(file, grid.getEditedItemId()); + assertEquals(getEditedItem(), + grid.getEditorFieldGroup().getItemDataSource()); + + assertEquals(FILE_NAME_BEFORE, + grid.getColumn(PROPERTY_NAME).getEditorField().getValue()); + assertEquals(FILE_SIZE_BEFORE, + grid.getColumn(PROPERTY_SIZE).getEditorField().getValue()); + grid.cancelEditor(); + } + + @Test + public void testCancelEditor() { + // Row with all properties + testCancel(file, PROPERTY_NAME, FILE_NAME_BEFORE, FILE_NAME_AFTER); + testCancel(file, PROPERTY_SIZE, FILE_SIZE_BEFORE, FILE_SIZE_AFTER); + + // Row with missing property + testCancel(folder, PROPERTY_NAME, FOLDER_NAME_BEFORE, + FOLDER_NAME_AFTER); + } + + private void testCancel(Object itemId, String propertyId, + String valueBefore, String valueAfter) { + startEdit(itemId); + + TextField field = (TextField) grid.getColumn(propertyId) + .getEditorField(); + field.setValue(valueAfter); + + Property<?> datasource = field.getPropertyDataSource(); + + grid.cancelEditor(); + assertFalse(grid.isEditorActive()); + assertNull(grid.getEditedItemId()); + assertFalse(field.isModified()); + assertEquals("", field.getValue()); + assertEquals(valueBefore, datasource.getValue()); + assertNull(field.getPropertyDataSource()); + assertNull(grid.getEditorFieldGroup().getItemDataSource()); + } + + @Test + public void testSaveEditor() throws Exception { + // Row with all properties + testSave(file, PROPERTY_SIZE, FILE_SIZE_BEFORE, FILE_SIZE_AFTER); + + // Row with missing property + testSave(folder, PROPERTY_NAME, FOLDER_NAME_BEFORE, FOLDER_NAME_AFTER); + } + + private void testSave(Object itemId, String propertyId, String valueBefore, + String valueAfter) throws Exception { + startEdit(itemId); + TextField field = (TextField) grid.getColumn(propertyId) + .getEditorField(); + + field.setValue(valueAfter); + assertEquals(valueBefore, field.getPropertyDataSource().getValue()); + + grid.saveEditor(); + assertTrue(grid.isEditorActive()); + assertFalse(field.isModified()); + assertEquals(valueAfter, field.getValue()); + assertEquals(valueAfter, getEditedProperty(propertyId).getValue()); + grid.cancelEditor(); + } + + private Item getEditedItem() { + assertNotNull(grid.getEditedItemId()); + return grid.getContainerDataSource().getItem(grid.getEditedItemId()); + } + + private Property<?> getEditedProperty(Object propertyId) { + return getEditedItem().getItemProperty(propertyId); + } + + private void startEdit(Object itemId) { + grid.setEditorEnabled(true); + grid.editItem(itemId); + // Simulate succesful client response to actually start the editing. + grid.doEditItem(); + } + + private class TestContainer + extends AbstractInMemoryContainer<Object, String, BeanItem> { + + private final List<BeanItem<Entry>> items; + private final List<String> pids; + + public TestContainer(List<BeanItem<Entry>> items, List<String> pids) { + this.items = items; + this.pids = pids; + } + + @Override + protected List<Object> getAllItemIds() { + List<Object> ids = new ArrayList<>(); + for (BeanItem<Entry> item : items) { + ids.add(item.getBean()); + } + return ids; + } + + @Override + protected BeanItem<Entry> getUnfilteredItem(Object itemId) { + for (BeanItem<Entry> item : items) { + if (item.getBean().equals(itemId)) { + return item; + } + } + return null; + } + + @Override + public Collection<?> getContainerPropertyIds() { + return pids; + } + + @Override + public Property getContainerProperty(Object itemId, Object propertyId) { + return getItem(itemId).getItemProperty(propertyId); + } + + @Override + public Class<?> getType(Object propertyId) { + return String.class; + } + } + + public class Entry { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Entry(String name) { + this.name = name; + } + } + + public class Folder extends Entry { + + public Folder(String name) { + super(name); + } + } + + public class File extends Entry { + private String size; + + public File(String name, String size) { + super(name); + this.size = size; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + } + + private class Grid extends com.vaadin.v7.ui.Grid { + @Override + protected void doEditItem() { + super.doEditItem(); + } + } +} |