This patch adds the option of updating an existing data object. Update is done on the next client response to catch any possible changes before and after the update is initiated. Change-Id: I30ca4803dd7c47befcb8e5ae761860c09cbdb8bdfeature/databinding
@@ -98,6 +98,23 @@ public class DataSourceConnector extends AbstractExtensionConnector { | |||
sendDroppedKeys(); | |||
} | |||
} | |||
@Override | |||
public void updateData(JsonArray data) { | |||
List<JsonObject> list = ds.asList(); | |||
for (int i = 0; i < data.length(); ++i) { | |||
JsonObject json = data.getObject(i); | |||
String key = getKey(json); | |||
if (keyToJson.containsKey(key)) { | |||
int index = list.indexOf(keyToJson.get(key)); | |||
list.set(index, json); | |||
} else { | |||
dropKey(key); | |||
} | |||
} | |||
sendDroppedKeys(); | |||
} | |||
}); | |||
ServerConnector parent = getParent(); | |||
@@ -117,8 +134,8 @@ public class DataSourceConnector extends AbstractExtensionConnector { | |||
* dropped key | |||
*/ | |||
private void dropKey(String key) { | |||
droppedKeys.add(key); | |||
if (keyToJson.containsKey(key)) { | |||
droppedKeys.add(key); | |||
keyToJson.remove(key); | |||
} | |||
} |
@@ -199,6 +199,7 @@ public class DataProvider<T> extends AbstractExtension { | |||
private Collection<TypedDataGenerator<T>> generators = new LinkedHashSet<TypedDataGenerator<T>>(); | |||
private boolean reset = false; | |||
private final Set<T> updatedData = new HashSet<T>(); | |||
private Collection<T> data; | |||
private DataProviderClientRpc rpc; | |||
@@ -233,7 +234,19 @@ public class DataProvider<T> extends AbstractExtension { | |||
getRpcProxy(DataProviderClientRpc.class).resetSize(data.size()); | |||
pushData(0, data); | |||
reset = false; | |||
updatedData.clear(); | |||
} | |||
if (updatedData.isEmpty()) { | |||
return; | |||
} | |||
JsonArray dataArray = Json.createArray(); | |||
int i = 0; | |||
for (T data : updatedData) { | |||
dataArray.set(i++, getDataObject(data)); | |||
} | |||
rpc.updateData(dataArray); | |||
} | |||
/** | |||
@@ -369,4 +382,17 @@ public class DataProvider<T> extends AbstractExtension { | |||
markAsDirty(); | |||
} | |||
/** | |||
* Informs the DataProvider that a data object has been updated. | |||
* | |||
* @param data | |||
* updated data object | |||
*/ | |||
public void refresh(T data) { | |||
if (updatedData.isEmpty()) { | |||
markAsDirty(); | |||
} | |||
updatedData.add(data); | |||
} | |||
} |
@@ -66,4 +66,12 @@ public interface DataProviderClientRpc extends ClientRpc { | |||
*/ | |||
void drop(String key); | |||
/** | |||
* Updates an array of objects based on their identifying key. | |||
* | |||
* @param data | |||
* array of updated data | |||
*/ | |||
void updateData(JsonArray data); | |||
} |
@@ -16,8 +16,10 @@ | |||
package com.vaadin.tests.dataprovider; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
@@ -93,6 +95,8 @@ public class DummyDataProviderTest extends SingleBrowserTest { | |||
} | |||
private void createPersonObjects() { | |||
personObjects.clear(); | |||
for (ComplexPerson p : persons) { | |||
JsonObject j = Json.createObject(); | |||
j.put(DataProviderConstants.KEY, personToKeyMap.get(p)); | |||
@@ -153,4 +157,29 @@ public class DummyDataProviderTest extends SingleBrowserTest { | |||
assertNoErrorNotifications(); | |||
} | |||
@Test | |||
public void testEditFirstItem() { | |||
persons.retainAll(Arrays.asList(persons.get(0))); | |||
createPersonObjects(); | |||
openTestURL(); | |||
String json = personObjects.get(0).toJson(); | |||
String text = findElements(By.className("v-label")).get(1).getText(); | |||
assertEquals("Initial data did not match", json, text); | |||
$(ButtonElement.class).id("edit").click(); | |||
persons.get(0).setFirstName("Foo"); | |||
createPersonObjects(); | |||
json = personObjects.get(0).toJson(); | |||
assertFalse("JsonObject of edited person was not updated", | |||
json.equals(text)); | |||
text = findElements(By.className("v-label")).get(1).getText(); | |||
assertEquals("Modified data did not match", json, text); | |||
} | |||
} |
@@ -85,6 +85,10 @@ public class DummyDataProviderUI extends AbstractTestUI { | |||
Collections.sort(data, comparator); | |||
dataProvider.reset(); | |||
} | |||
public void update(ComplexPerson p) { | |||
dataProvider.refresh(p); | |||
} | |||
} | |||
public static final int RANDOM_SEED = 1337; | |||
@@ -128,13 +132,23 @@ public class DummyDataProviderUI extends AbstractTestUI { | |||
dummy.sort(nameComparator); | |||
} | |||
}); | |||
Button edit = new Button("Edit first", new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
ComplexPerson p = persons.get(0); | |||
p.setFirstName("Foo"); | |||
dummy.update(p); | |||
} | |||
}); | |||
// Button Ids | |||
remove.setId("remove"); | |||
add.setId("add"); | |||
sort.setId("sort"); | |||
edit.setId("edit"); | |||
addComponent(new HorizontalLayout(add, remove, sort)); | |||
addComponent(new HorizontalLayout(add, remove, sort, edit)); | |||
addComponent(dummy); | |||
} | |||
@@ -62,6 +62,15 @@ public class DummyDataConnector extends AbstractComponentConnector implements | |||
.toJson())); | |||
} | |||
} | |||
@Override | |||
public void dataUpdated(int firstRowIndex, int numberOfRows) { | |||
for (int i = 0; i < numberOfRows; ++i) { | |||
VLabel label = (VLabel) getWidget().getWidget( | |||
i + firstRowIndex); | |||
label.setText(dataSource.getRow(i + firstRowIndex).toJson()); | |||
} | |||
} | |||
}); | |||
} | |||
} |