* Fixes #10937 - Previously if selected value is null, then index is set to -1; in current implementation if value is null and emptySelection is allowed then set the index to 0. (The position for the empty selection) - Also, if changing the allowEmptySelection on the fly, ensure, that either index is to-reset to -1 by setting the selected value to null on the client-side (the value before was null) or preserve the value(value was different than empty). * Change the test case Since in this pr the behaviour of the NS is changed, therefore old test need to be adjusted. Change: setting null as value will select empty selection. Before that nothing would be selected and value will be cleared. Behaviour change in PR: Allow selecting null as valuetags/8.7.0.alpha1
@@ -29,6 +29,7 @@ import com.vaadin.shared.ui.nativeselect.NativeSelectState; | |||
public class VNativeSelect extends FocusableFlowPanelComposite { | |||
private final ListBox listBox = new ListBox(); | |||
private boolean emptySelectionAllowed = true; | |||
/** | |||
* Creates a new {@code VNativeSelect} instance. | |||
@@ -55,7 +56,11 @@ public class VNativeSelect extends FocusableFlowPanelComposite { | |||
*/ | |||
public void setSelectedItem(String value) { | |||
if (value == null) { | |||
getListBox().setSelectedIndex(-1); | |||
if (emptySelectionAllowed) { | |||
getListBox().setSelectedIndex(0); | |||
} else { | |||
getListBox().setSelectedIndex(-1); | |||
} | |||
} else { | |||
for (int i = 0; i < getListBox().getItemCount(); i++) { | |||
if (Objects.equals(value, getListBox().getValue(i))) { | |||
@@ -132,4 +137,23 @@ public class VNativeSelect extends FocusableFlowPanelComposite { | |||
return getListBox().getVisibleItemCount(); | |||
} | |||
/** | |||
* Returns true if empty selection is allowed. | |||
* | |||
* @since | |||
* @return empty selection is allowed | |||
*/ | |||
public boolean isEmptySelectionAllowed() { | |||
return emptySelectionAllowed; | |||
} | |||
/** | |||
* Sets true if empty selection is allowed. | |||
* | |||
* @since | |||
* @param emptySelectionAllowed | |||
*/ | |||
public void setEmptySelectionAllowed(boolean emptySelectionAllowed) { | |||
this.emptySelectionAllowed = emptySelectionAllowed; | |||
} | |||
} |
@@ -95,10 +95,14 @@ public class NativeSelectConnector | |||
ListBox listBox = getWidget().getListBox(); | |||
boolean hasEmptyItem = listBox.getItemCount() > 0 | |||
&& listBox.getValue(0).isEmpty(); | |||
getWidget().setEmptySelectionAllowed(getState().emptySelectionAllowed); | |||
if (hasEmptyItem && getState().emptySelectionAllowed) { | |||
listBox.setItemText(0, getState().emptySelectionCaption); | |||
} else if (hasEmptyItem && !getState().emptySelectionAllowed) { | |||
listBox.removeItem(0); | |||
if (getWidget().getListBox().getSelectedIndex() == 0) { | |||
getWidget().setSelectedItem(null); | |||
} | |||
} else if (!hasEmptyItem && getState().emptySelectionAllowed) { | |||
listBox.insertItem(getState().emptySelectionCaption, 0); | |||
listBox.setValue(0, ""); |
@@ -50,6 +50,9 @@ public class AbstractSingleSelection extends AbstractTestUI { | |||
.newInstance(); | |||
select.setItems("Foo", "Bar", "Baz", "Reset"); | |||
select.setSelectedItem("Bar"); | |||
if (select instanceof NativeSelect) { | |||
((NativeSelect) select).setEmptySelectionAllowed(false); | |||
} | |||
select.addValueChangeListener(event -> { | |||
if ("Reset".equals(event.getValue())) { |
@@ -0,0 +1,36 @@ | |||
package com.vaadin.tests.components.nativeselect; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.NativeSelect; | |||
import com.vaadin.ui.Button; | |||
public class NativeSelectSetNull extends AbstractTestUI { | |||
public static String EMPTY_SELECTION_TEXT = "Empty Selection"; | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
NativeSelect<Integer> select = new NativeSelect<>("Native Selection"); | |||
// Add some items | |||
select.setItems(1, 2, 3, 45, 6); | |||
select.setEmptySelectionAllowed(true); | |||
select.setEmptySelectionCaption(EMPTY_SELECTION_TEXT); | |||
Button changeSelect = new Button("Set value to 3", | |||
e -> select.setValue(3)); | |||
changeSelect.setId("changeSelect"); | |||
Button setNull = new Button("Set value to null", | |||
e -> select.setValue(null)); | |||
setNull.setId("setNull"); | |||
Button clear = new Button("Clear", e -> select.clear()); | |||
clear.setId("clear"); | |||
Button disable = new Button("Disable", e -> select | |||
.setEmptySelectionAllowed(!select.isEmptySelectionAllowed())); | |||
disable.setId("disable"); | |||
addComponent(select); | |||
addComponents(changeSelect, setNull, clear, disable); | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
package com.vaadin.tests.components.nativeselect; | |||
import com.vaadin.testbench.elements.NativeSelectElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.WebElement; | |||
import static junit.framework.TestCase.assertEquals; | |||
public class NativeSelectSetNullTest extends MultiBrowserTest { | |||
@Before | |||
public void setUp() { | |||
openTestURL(); | |||
} | |||
@Test | |||
public void testCaptionSelected() { | |||
getButtonOnId("setNull"); | |||
assertEquals(NativeSelectSetNull.EMPTY_SELECTION_TEXT, | |||
getSelect().getValue()); | |||
} | |||
@Test | |||
public void changeSelectedValue() { | |||
getButtonOnId("changeSelect").click(); | |||
assertEquals(3, Integer.valueOf(getSelect().getValue()).intValue()); | |||
} | |||
@Test | |||
public void clearSelection() { | |||
getButtonOnId("clear").click(); | |||
assertEquals(NativeSelectSetNull.EMPTY_SELECTION_TEXT, | |||
getSelect().getValue()); | |||
} | |||
@Test | |||
public void valuePreservedAfterAllowEmptySelectionChanged() { | |||
getSelect().setValue("2"); | |||
getButtonOnId("disable").click(); | |||
assertEquals(2, Integer.valueOf(getSelect().getValue()).intValue()); | |||
getButtonOnId("disable").click(); | |||
getButtonOnId("setNull").click(); | |||
assertEquals(NativeSelectSetNull.EMPTY_SELECTION_TEXT, | |||
getSelect().getValue()); | |||
} | |||
protected NativeSelectElement getSelect() { | |||
return $(NativeSelectElement.class).first(); | |||
} | |||
protected WebElement getButtonOnId(String id) { | |||
return findElement(By.id(id)); | |||
} | |||
} |