Browse Source

Make it possible to reset single select values

Change-Id: I60c5d9f183d1955fbbd3341e3ac9f93aae755f80
tags/8.0.0.alpha8
Leif Åstrand 7 years ago
parent
commit
0d57c15577

+ 8
- 0
server/src/main/java/com/vaadin/ui/AbstractSingleSelect.java View File

@@ -39,6 +39,8 @@ import com.vaadin.ui.declarative.DesignContext;
import com.vaadin.ui.declarative.DesignException;
import com.vaadin.util.ReflectTools;

import elemental.json.Json;

/**
* An abstract base class for listing components that only support single
* selection and no lazy loading of data items.
@@ -241,6 +243,12 @@ public abstract class AbstractSingleSelect<T> extends AbstractListing<T>
}

doSetSelectedKey(key);

// Update diffstate so that a change will be sent to the client if the
// selection is changed to its original value
updateDiffstate("selectedItemKey",
key == null ? Json.createNull() : Json.create(key));

fireEvent(new SingleSelectionEvent<>(AbstractSingleSelect.this, true));
}


+ 18
- 0
server/src/main/java/com/vaadin/ui/ComboBox.java View File

@@ -52,6 +52,7 @@ import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
import com.vaadin.ui.declarative.DesignFormatter;

import elemental.json.Json;
import elemental.json.JsonObject;

/**
@@ -670,4 +671,21 @@ public class ComboBox<T> extends AbstractSingleSelect<T>
// ComboBox.
return (DataCommunicator<T, String>) super.getDataCommunicator();
}

@Override
protected void setSelectedFromClient(String key) {
super.setSelectedFromClient(key);

/*
* The client side for combo box always expects a state change for
* selectedItemKey after it has sent a selection change. This means that
* we must store a value in the diffstate that guarantees that a new
* value will be sent, regardless of what the value actually is at the
* time when changes are sent.
*
* Keys are always strings (or null), so using a non-string type will
* always trigger a diff mismatch and a resend.
*/
updateDiffstate("selectedItemKey", Json.create(0));
}
}

+ 48
- 0
server/src/test/java/com/vaadin/ui/ComboBoxTest.java View File

@@ -0,0 +1,48 @@
/*
* 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.ui;

import org.junit.Test;

import com.vaadin.shared.data.selection.SelectionServerRpc;
import com.vaadin.tests.util.MockUI;

public class ComboBoxTest {

@Test
public void testResetValue() {
ComboBox<String> comboBox = new ComboBox<>();
comboBox.setItems("one", "two");

// Reset value whenever it changes (in a real case, this listener would
// do something with the selected value before discarding it)
comboBox.addValueChangeListener(e -> comboBox.setValue(null));

// "Attach" the component and initialize diffstate
new MockUI().setContent(comboBox);
ComponentTest.syncToClient(comboBox);

// Emulate selection of "one"
String oneKey = comboBox.getDataCommunicator().getKeyMapper()
.key("one");
ComponentTest.getRpcProxy(comboBox, SelectionServerRpc.class)
.select(oneKey);

ComponentTest.assertEncodedStateProperties(comboBox,
"Selection change done by the listener should be sent to the client",
"selectedItemKey");
}
}

+ 52
- 0
uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxAutoresetValue.java View File

@@ -0,0 +1,52 @@
/*
* 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.combobox;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.ComboBox;

public class ComboBoxAutoresetValue extends AbstractTestUIWithLog {

public static final String RESET = "Reset";
public static final String CHANGE = "Change to something else";
public static final String SOMETHING = "Something else";

@Override
protected void setup(VaadinRequest request) {
ComboBox<String> comboBox = new ComboBox<>();
comboBox.setItems(RESET, CHANGE, SOMETHING);
comboBox.addValueChangeListener(e -> {
String value = e.getValue();
log("Value changed to " + value);

if (e.isUserOriginated()) {
if (RESET.equals(value)) {
e.getSource().setValue(null);
} else if (CHANGE.equals(value)) {
e.getSource().setValue(SOMETHING);
}
}
});
addComponent(comboBox);
}

@Override
public String getDescription() {
return "Changing the ComboBox value in its own value change listener should work";
}

}

+ 59
- 0
uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxAutoresetValueTest.java View File

@@ -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.tests.components.combobox;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.testbench.customelements.ComboBoxElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class ComboBoxAutoresetValueTest extends SingleBrowserTest {

@Test
public void testValueChanges() {
openTestURL();

ComboBoxElement comboBox = $(ComboBoxElement.class).first();

Assert.assertEquals("", comboBox.getValue());

comboBox.selectByText(ComboBoxAutoresetValue.RESET);

assertLogChange(1, ComboBoxAutoresetValue.RESET, 1);
assertLogChange(2, null, 0);
Assert.assertEquals("", comboBox.getValue());

comboBox.selectByText(ComboBoxAutoresetValue.CHANGE);
assertLogChange(3, ComboBoxAutoresetValue.CHANGE, 1);
assertLogChange(4, ComboBoxAutoresetValue.SOMETHING, 0);
Assert.assertEquals(ComboBoxAutoresetValue.SOMETHING,
comboBox.getValue());

comboBox.selectByText(ComboBoxAutoresetValue.SOMETHING);
// No new log items
assertLogChange(4, ComboBoxAutoresetValue.SOMETHING, 0);
Assert.assertEquals(ComboBoxAutoresetValue.SOMETHING,
comboBox.getValue());
}

private void assertLogChange(int sequenceNumber, String expectedValue,
int rowIndex) {
Assert.assertEquals(
sequenceNumber + ". Value changed to " + expectedValue,
getLogRow(rowIndex));
}
}

Loading…
Cancel
Save