@@ -0,0 +1,59 @@ | |||
/* | |||
* 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.client.ui; | |||
import com.vaadin.client.Focusable; | |||
public class VCustomField extends VCustomComponent implements Focusable { | |||
private Focusable focusDelegate; | |||
@Override | |||
public void focus() { | |||
if (focusDelegate != null) { | |||
focusDelegate.focus(); | |||
} | |||
} | |||
/** | |||
* Sets the focusable widget to focus instead of this custom field. | |||
* | |||
* @param focusDelegate | |||
* the widget to delegate focus to | |||
*/ | |||
public void setFocusDelegate(Focusable focusDelegate) { | |||
this.focusDelegate = focusDelegate; | |||
} | |||
/** | |||
* Sets the focusable widget to focus instead of this custom field. | |||
* | |||
* @param focusDelegate | |||
* the widget to delegate focus to | |||
*/ | |||
public void setFocusDelegate( | |||
final com.google.gwt.user.client.ui.Focusable focusDelegate) { | |||
this.focusDelegate = new Focusable() { | |||
@Override | |||
public void focus() { | |||
focusDelegate.setFocus(true); | |||
} | |||
}; | |||
} | |||
} |
@@ -17,15 +17,18 @@ package com.vaadin.client.ui.customfield; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.logging.Logger; | |||
import com.google.gwt.event.shared.HandlerRegistration; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler; | |||
import com.vaadin.client.Focusable; | |||
import com.vaadin.client.HasComponentsConnector; | |||
import com.vaadin.client.communication.StateChangeEvent; | |||
import com.vaadin.client.ui.AbstractFieldConnector; | |||
import com.vaadin.client.ui.VCustomComponent; | |||
import com.vaadin.client.ui.VCustomField; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.shared.ui.customfield.CustomFieldState; | |||
import com.vaadin.ui.CustomField; | |||
@@ -44,8 +47,13 @@ public class CustomFieldConnector extends AbstractFieldConnector | |||
} | |||
@Override | |||
public VCustomComponent getWidget() { | |||
return (VCustomComponent) super.getWidget(); | |||
public CustomFieldState getState() { | |||
return (CustomFieldState) super.getState(); | |||
} | |||
@Override | |||
public VCustomField getWidget() { | |||
return (VCustomField) super.getWidget(); | |||
} | |||
@Override | |||
@@ -53,6 +61,32 @@ public class CustomFieldConnector extends AbstractFieldConnector | |||
// NOP, custom field does not render the caption of its content | |||
} | |||
@Override | |||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | |||
super.onStateChanged(stateChangeEvent); | |||
if (getState().focusDelegate != null) { | |||
Widget widget = ((ComponentConnector) getState().focusDelegate) | |||
.getWidget(); | |||
if (widget instanceof Focusable) { | |||
getWidget().setFocusDelegate((Focusable) widget); | |||
} else if (widget instanceof com.google.gwt.user.client.ui.Focusable) { | |||
getWidget().setFocusDelegate( | |||
(com.google.gwt.user.client.ui.Focusable) widget); | |||
} else { | |||
getLogger().warning( | |||
"The given focus delegate does not implement Focusable: " | |||
+ widget.getClass().getName()); | |||
} | |||
} else { | |||
getWidget().setFocusDelegate((Focusable) null); | |||
} | |||
} | |||
private static Logger getLogger() { | |||
return Logger.getLogger(CustomFieldConnector.class.getName()); | |||
} | |||
@Override | |||
public void onConnectorHierarchyChange( | |||
ConnectorHierarchyChangeEvent event) { | |||
@@ -122,9 +156,4 @@ public class CustomFieldConnector extends AbstractFieldConnector | |||
} | |||
} | |||
@Override | |||
public CustomFieldState getState() { | |||
return (CustomFieldState) super.getState(); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* 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.client.ui; | |||
import com.vaadin.client.Focusable; | |||
@Deprecated | |||
public class VCustomField extends VCustomComponent implements Focusable { | |||
private Focusable focusDelegate; | |||
@Override | |||
public void focus() { | |||
if (focusDelegate != null) { | |||
focusDelegate.focus(); | |||
} | |||
} | |||
/** | |||
* Sets the focusable widget to focus instead of this custom field. | |||
* | |||
* @param focusDelegate | |||
* the widget to delegate focus to | |||
*/ | |||
public void setFocusDelegate(Focusable focusDelegate) { | |||
this.focusDelegate = focusDelegate; | |||
} | |||
/** | |||
* Sets the focusable widget to focus instead of this custom field. | |||
* | |||
* @param focusDelegate | |||
* the widget to delegate focus to | |||
*/ | |||
public void setFocusDelegate( | |||
final com.google.gwt.user.client.ui.Focusable focusDelegate) { | |||
this.focusDelegate = new Focusable() { | |||
@Override | |||
public void focus() { | |||
focusDelegate.setFocus(true); | |||
} | |||
}; | |||
} | |||
} |
@@ -17,16 +17,19 @@ package com.vaadin.v7.client.ui.customfield; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.logging.Logger; | |||
import com.google.gwt.event.shared.HandlerRegistration; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler; | |||
import com.vaadin.client.Focusable; | |||
import com.vaadin.client.HasComponentsConnector; | |||
import com.vaadin.client.communication.StateChangeEvent; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.v7.client.ui.AbstractFieldConnector; | |||
import com.vaadin.v7.client.ui.VCustomComponent; | |||
import com.vaadin.v7.client.ui.VCustomField; | |||
import com.vaadin.v7.ui.CustomField; | |||
@Connect(value = CustomField.class) | |||
@@ -43,8 +46,8 @@ public class CustomFieldConnector extends AbstractFieldConnector | |||
} | |||
@Override | |||
public VCustomComponent getWidget() { | |||
return (VCustomComponent) super.getWidget(); | |||
public VCustomField getWidget() { | |||
return (VCustomField) super.getWidget(); | |||
} | |||
@Override | |||
@@ -52,6 +55,32 @@ public class CustomFieldConnector extends AbstractFieldConnector | |||
// NOP, custom field does not render the caption of its content | |||
} | |||
@Override | |||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | |||
super.onStateChanged(stateChangeEvent); | |||
if (getState().focusDelegate != null) { | |||
Widget widget = ((ComponentConnector) getState().focusDelegate) | |||
.getWidget(); | |||
if (widget instanceof Focusable) { | |||
getWidget().setFocusDelegate((Focusable) widget); | |||
} else if (widget instanceof com.google.gwt.user.client.ui.Focusable) { | |||
getWidget().setFocusDelegate( | |||
(com.google.gwt.user.client.ui.Focusable) widget); | |||
} else { | |||
getLogger().warning( | |||
"The given focus delegate does not implement Focusable: " | |||
+ widget.getClass().getName()); | |||
} | |||
} else { | |||
getWidget().setFocusDelegate((Focusable) null); | |||
} | |||
} | |||
private static Logger getLogger() { | |||
return Logger.getLogger(CustomFieldConnector.class.getName()); | |||
} | |||
@Override | |||
public void onConnectorHierarchyChange( | |||
ConnectorHierarchyChangeEvent event) { |
@@ -130,7 +130,7 @@ public abstract class CustomField<T> extends AbstractField<T> | |||
private class ComponentIterator | |||
implements Iterator<Component>, Serializable { | |||
boolean first = (root != null); | |||
boolean first = root != null; | |||
@Override | |||
public boolean hasNext() { | |||
@@ -153,4 +153,53 @@ public abstract class CustomField<T> extends AbstractField<T> | |||
public Iterator<Component> iterator() { | |||
return new ComponentIterator(); | |||
} | |||
/** | |||
* Sets the component to which all methods from the {@link Focusable} | |||
* interface should be delegated. | |||
* <p> | |||
* Set this to a wrapped field to include that field in the tabbing order, | |||
* to make it receive focus when {@link #focus()} is called and to make it | |||
* be correctly focused when used as a Grid editor component. | |||
* <p> | |||
* By default, {@link Focusable} events are handled by the super class and | |||
* ultimately ignored. | |||
* | |||
* @param focusDelegate | |||
* the focusable component to which focus events are redirected | |||
*/ | |||
public void setFocusDelegate(Focusable focusDelegate) { | |||
getState().focusDelegate = focusDelegate; | |||
} | |||
private Focusable getFocusable() { | |||
return (Focusable) getState(false).focusDelegate; | |||
} | |||
@Override | |||
public void focus() { | |||
if (getFocusable() != null) { | |||
getFocusable().focus(); | |||
} else { | |||
super.focus(); | |||
} | |||
} | |||
@Override | |||
public int getTabIndex() { | |||
if (getFocusable() != null) { | |||
return getFocusable().getTabIndex(); | |||
} else { | |||
return super.getTabIndex(); | |||
} | |||
} | |||
@Override | |||
public void setTabIndex(int tabIndex) { | |||
if (getFocusable() != null) { | |||
getFocusable().setTabIndex(tabIndex); | |||
} else { | |||
super.setTabIndex(tabIndex); | |||
} | |||
} | |||
} |
@@ -15,6 +15,7 @@ | |||
*/ | |||
package com.vaadin.v7.shared; | |||
import com.vaadin.shared.Connector; | |||
import com.vaadin.shared.annotations.NoLayout; | |||
/** | |||
@@ -34,4 +35,13 @@ public class AbstractFieldState extends AbstractLegacyComponentState { | |||
*/ | |||
@NoLayout | |||
public int tabIndex = 0; | |||
/** | |||
* The component which should receive focus events instead of the custom | |||
* field wrapper. | |||
* <p> | |||
* This is not used in all fields, but needs to be here for the time being | |||
* (#20468). | |||
*/ | |||
public Connector focusDelegate; | |||
} |
@@ -155,4 +155,54 @@ public abstract class CustomField<T> extends AbstractField<T> | |||
public Iterator<Component> iterator() { | |||
return new ComponentIterator(); | |||
} | |||
/** | |||
* Sets the component to which all methods from the {@link Focusable} | |||
* interface should be delegated. | |||
* <p> | |||
* Set this to a wrapped field to include that field in the tabbing order, | |||
* to make it receive focus when {@link #focus()} is called and to make it | |||
* be correctly focused when used as a Grid editor component. | |||
* <p> | |||
* By default, {@link Focusable} events are handled by the super class and | |||
* ultimately ignored. | |||
* | |||
* @param focusDelegate | |||
* the focusable component to which focus events are redirected | |||
*/ | |||
public void setFocusDelegate(Focusable focusDelegate) { | |||
getState().focusDelegate = focusDelegate; | |||
} | |||
private Focusable getFocusable() { | |||
return (Focusable) getState(false).focusDelegate; | |||
} | |||
@Override | |||
public void focus() { | |||
if (getFocusable() != null) { | |||
getFocusable().focus(); | |||
} else { | |||
super.focus(); | |||
} | |||
} | |||
@Override | |||
public int getTabIndex() { | |||
if (getFocusable() != null) { | |||
return getFocusable().getTabIndex(); | |||
} else { | |||
return super.getTabIndex(); | |||
} | |||
} | |||
@Override | |||
public void setTabIndex(int tabIndex) { | |||
if (getFocusable() != null) { | |||
getFocusable().setTabIndex(tabIndex); | |||
} else { | |||
super.setTabIndex(tabIndex); | |||
} | |||
} | |||
} |
@@ -16,14 +16,21 @@ | |||
package com.vaadin.shared.ui.customfield; | |||
import com.vaadin.shared.AbstractFieldState; | |||
import com.vaadin.shared.Connector; | |||
/** | |||
* State class for CustomField. | |||
* | |||
* | |||
* @author Vaadin Ltd | |||
* @since 8.0 | |||
* | |||
*/ | |||
public class CustomFieldState extends AbstractFieldState { | |||
/** | |||
* The component which should receive focus events instead of the custom | |||
* field wrapper. | |||
*/ | |||
public Connector focusDelegate; | |||
} |
@@ -0,0 +1,144 @@ | |||
/* | |||
* 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 java.util.HashSet; | |||
import java.util.Set; | |||
import com.vaadin.annotations.Theme; | |||
import com.vaadin.data.Binder; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.server.data.ListDataProvider; | |||
import com.vaadin.server.data.Query; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.tests.fieldgroup.ComplexPerson; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.ComboBox; | |||
import com.vaadin.ui.Component; | |||
import com.vaadin.ui.CustomField; | |||
import com.vaadin.ui.Grid; | |||
import com.vaadin.ui.HorizontalLayout; | |||
import com.vaadin.ui.TextField; | |||
@Theme("tests-valo-disabled-animations") | |||
public class GridEditorCustomField extends AbstractTestUIWithLog { | |||
private static final String LAST_NAME_IDENTIFIER = "lastName"; | |||
private static final String FIRST_NAME_IDENTIFIER = "firstName"; | |||
private static final String ADDRESS_CITY_IDENTIFIER = "address.city"; | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Grid<ComplexPerson> grid = createGrid(); | |||
ListDataProvider<ComplexPerson> dataProvider = ComplexPerson | |||
.createDataProvider(100); | |||
grid.setDataProvider(dataProvider); | |||
Set<String> cities = new HashSet<>(); | |||
dataProvider.fetch(new Query<>()).forEach(person -> { | |||
cities.add(person.getAddress().getCity()); | |||
}); | |||
CustomCitySelect cityEditor = new CustomCitySelect( | |||
cities.toArray(new String[cities.size()])); | |||
TextField firstNameField = new TextField(); | |||
TextField lastNameField = new TextField(); | |||
Binder<ComplexPerson> binder = new Binder<>(); | |||
binder.bind(firstNameField, ComplexPerson::getFirstName, | |||
ComplexPerson::setFirstName); | |||
binder.bind(lastNameField, ComplexPerson::getLastName, | |||
ComplexPerson::setLastName); | |||
binder.bind(cityEditor, person -> person.getAddress().getCity(), | |||
(person, city) -> person.getAddress().setCity(city)); | |||
grid.getEditor().setBinder(binder); | |||
grid.getColumn(ADDRESS_CITY_IDENTIFIER).setEditorComponent(cityEditor); | |||
grid.getColumn(FIRST_NAME_IDENTIFIER) | |||
.setEditorComponent(firstNameField); | |||
grid.getColumn(LAST_NAME_IDENTIFIER).setEditorComponent(lastNameField); | |||
addComponent(grid); | |||
} | |||
private Grid<ComplexPerson> createGrid() { | |||
Grid<ComplexPerson> grid = new Grid<>(); | |||
grid.setWidth("800px"); | |||
grid.addColumn(FIRST_NAME_IDENTIFIER, person -> person.getFirstName()) | |||
.setCaption("First Name"); | |||
grid.addColumn(LAST_NAME_IDENTIFIER, person -> person.getLastName()) | |||
.setCaption("Last Name"); | |||
grid.addColumn(ADDRESS_CITY_IDENTIFIER, | |||
person -> person.getAddress().getCity()) | |||
.setCaption("City Name"); | |||
grid.getEditor().setEnabled(true); | |||
return grid; | |||
} | |||
public static class CustomCitySelect extends CustomField<String> { | |||
private HorizontalLayout fieldLayout; | |||
private String[] values; | |||
private ComboBox<String> cityComboBox; | |||
private String cachedValue; | |||
public CustomCitySelect(String... values) { | |||
this.values = values; | |||
} | |||
@Override | |||
protected Component initContent() { | |||
fieldLayout = new HorizontalLayout(); | |||
fieldLayout.setWidth("100%"); | |||
cityComboBox = new ComboBox<>(); | |||
cityComboBox.setItems(values); | |||
if (cachedValue != null) { | |||
cityComboBox.setValue(cachedValue); | |||
cachedValue = null; | |||
} | |||
fieldLayout.addComponent(cityComboBox); | |||
fieldLayout.setExpandRatio(cityComboBox, 1.0f); | |||
Button addCountryButton = new Button("New"); | |||
fieldLayout.addComponent(addCountryButton); | |||
setFocusDelegate(cityComboBox); | |||
return fieldLayout; | |||
} | |||
@Override | |||
public String getValue() { | |||
if (cityComboBox == null) { | |||
return null; | |||
} | |||
return cityComboBox.getValue(); | |||
} | |||
@Override | |||
protected void doSetValue(String value) { | |||
if (cityComboBox == null) { | |||
getContent(); | |||
} | |||
cityComboBox.setValue(value); | |||
} | |||
} | |||
} |
@@ -1,9 +1,13 @@ | |||
package com.vaadin.tests.fieldgroup; | |||
import java.math.BigDecimal; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import java.util.Random; | |||
import com.vaadin.server.data.DataProvider; | |||
import com.vaadin.server.data.ListDataProvider; | |||
import com.vaadin.tests.util.TestDataGenerator; | |||
import com.vaadin.v7.data.util.BeanItemContainer; | |||
@@ -25,6 +29,10 @@ public class ComplexPerson { | |||
this.firstName = firstName; | |||
} | |||
public void setLastName(String firstName) { | |||
this.firstName = firstName; | |||
} | |||
public String getLastName() { | |||
return lastName; | |||
} | |||
@@ -90,6 +98,18 @@ public class ComplexPerson { | |||
return bic; | |||
} | |||
public static ListDataProvider<ComplexPerson> createDataProvider(int size) { | |||
List<ComplexPerson> list = new ArrayList<>(); | |||
Random r = new Random(size); | |||
for (int i = 0; i < size; i++) { | |||
ComplexPerson cp = ComplexPerson.create(r); | |||
list.add(cp); | |||
} | |||
return DataProvider.create(list); | |||
} | |||
public static ComplexPerson create(Random r) { | |||
ComplexPerson cp = new ComplexPerson(); | |||
cp.setFirstName(TestDataGenerator.getFirstName(r)); |
@@ -1,100 +0,0 @@ | |||
/* | |||
* 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.components.grid; | |||
import java.util.HashSet; | |||
import java.util.Set; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.tests.fieldgroup.ComplexPerson; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Component; | |||
import com.vaadin.ui.HorizontalLayout; | |||
import com.vaadin.v7.ui.ComboBox; | |||
import com.vaadin.v7.ui.CustomField; | |||
import com.vaadin.v7.ui.Grid; | |||
public class GridEditorCustomField extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Grid grid = new PersonTestGrid(100); | |||
grid.setWidth("800px"); | |||
grid.setColumns("firstName", "lastName", "address.city"); | |||
grid.setEditorEnabled(true); | |||
Set<String> cities = new HashSet<>(); | |||
for (Object o : grid.getContainerDataSource().getItemIds()) { | |||
ComplexPerson p = (ComplexPerson) o; | |||
cities.add(p.getAddress().getCity()); | |||
} | |||
CustomCitySelect cityEditor = new CustomCitySelect( | |||
cities.toArray(new String[cities.size()])); | |||
grid.getColumn("address.city").setEditorField(cityEditor); | |||
addComponent(grid); | |||
} | |||
public static class CustomCitySelect extends CustomField<String> { | |||
private HorizontalLayout fieldLayout; | |||
private String[] values; | |||
private ComboBox cityComboBox; | |||
public CustomCitySelect(String... values) { | |||
this.values = values; | |||
} | |||
@Override | |||
protected Component initContent() { | |||
fieldLayout = new HorizontalLayout(); | |||
fieldLayout.setWidth("100%"); | |||
cityComboBox = new ComboBox(); | |||
for (String value : values) { | |||
cityComboBox.addItem(value); | |||
} | |||
fieldLayout.addComponent(cityComboBox); | |||
fieldLayout.setExpandRatio(cityComboBox, 1.0f); | |||
Button addCountryButton = new Button("New"); | |||
fieldLayout.addComponent(addCountryButton); | |||
return fieldLayout; | |||
} | |||
@Override | |||
public Class<String> getType() { | |||
return String.class; | |||
} | |||
@Override | |||
protected void setInternalValue(String newValue) { | |||
super.setInternalValue(newValue); | |||
if (cityComboBox == null) { | |||
return; | |||
} | |||
cityComboBox.setValue(newValue); | |||
} | |||
@Override | |||
public String getInternalValue() { | |||
if (cityComboBox == null) { | |||
return null; | |||
} | |||
return (String) cityComboBox.getValue(); | |||
} | |||
} | |||
} |
@@ -13,17 +13,18 @@ | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.v7.tests.components.grid; | |||
package com.vaadin.tests.components.grid; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import org.openqa.selenium.Keys; | |||
import com.vaadin.testbench.TestBenchElement; | |||
import com.vaadin.testbench.customelements.ComboBoxElement; | |||
import com.vaadin.testbench.customelements.GridElement; | |||
import com.vaadin.testbench.elements.GridElement.GridEditorElement; | |||
import com.vaadin.testbench.parallel.TestCategory; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
import com.vaadin.testbench.customelements.GridElement; | |||
@TestCategory("grid") | |||
public class GridEditorCustomFieldTest extends MultiBrowserTest { | |||
@@ -43,4 +44,18 @@ public class GridEditorCustomFieldTest extends MultiBrowserTest { | |||
Assert.assertEquals("Oslo", grid.getCell(0, 2).getText()); | |||
} | |||
@Test | |||
public void tabReachesCustomField() { | |||
openTestURL(); | |||
GridElement grid = $(GridElement.class).first(); | |||
grid.getCell(0, 1).doubleClick(); | |||
GridEditorElement editor = grid.getEditor(); | |||
editor.getField(0).sendKeys(Keys.TAB, Keys.TAB); | |||
ComboBoxElement comboBoxInCustomField = editor.getField(2) | |||
.$(ComboBoxElement.class).first(); | |||
assertElementsEquals(comboBoxInCustomField.getInputField(), | |||
getActiveElement()); | |||
} | |||
} |