-
5 Jan 2012 4:34 AM #1
DualListField improvements
DualListField improvements
I've recently integrated GWT RequestFactory and GXT 3.0 beta. And wrote some extended widgets.Here is my improved DualListField. It has interconnected stores so if you add some values to the right list, they will be removed from the left automatically.
The following algorithm is used to edit existing entity:
1. Populate right list with children from editable entity.
2. Populate left list with async request to the reference on the server.
Code:package ru.mesotron.jpauc.client.widget.form; import java.util.ArrayList; import java.util.List; import com.google.gwt.cell.client.Cell; import com.google.gwt.uibinder.client.UiConstructor; import com.google.web.bindery.requestfactory.shared.EntityProxy; import com.sencha.gxt.core.client.ValueProvider; import com.sencha.gxt.data.shared.ListStore; import com.sencha.gxt.data.shared.event.StoreAddEvent; import com.sencha.gxt.data.shared.event.StoreAddEvent.StoreAddHandler; import com.sencha.gxt.widget.core.client.ListView; public class DualListField<M extends EntityProxy, T> extends com.sencha.gxt.widget.core.client.form.DualListField<M, T> { protected ListStore<M> fromStore; protected ListStore<M> toStore; protected ListView<M, T> fromView; protected ListView<M, T> toView; @UiConstructor public DualListField(final ListStore<M> fromStore, final ListStore<M> toStore, ValueProvider<M, T> valueProvider, Cell<T> cell) { super(fromStore, toStore, valueProvider, cell); // Inheritance fix this.fromStore = fromStore; this.toStore = toStore; fromView = getFromView(); toView = getToView(); // If 'toStore' receives some item then the item should be removed from 'fromStore'. toStore.addStoreAddHandler(new StoreAddHandler<M>() { @Override public void onAdd(StoreAddEvent<M> event) { for (M item : event.getItems()) { M deleteItem = null; for (M existingItem : fromStore.getAll()) { if (existingItem.stableId().equals(item.stableId())) { deleteItem = existingItem; } } if (deleteItem != null) { fromStore.remove(deleteItem); } } } }); // If the item already exists in 'toStore' then it shoul be removed from 'fromStore' fromStore.addStoreAddHandler(new StoreAddHandler<M>() { @Override public void onAdd(StoreAddEvent<M> event) { for (M entity : event.getItems()) { for (M existing : toStore.getAll()) { if (existing.stableId().equals(entity.stableId())) { fromStore.remove(entity); } } } } }); } @Override protected void onAllLeft() { List<M> sel = new ArrayList<M>(toStore.getAll()); toStore.clear(); fromStore.addAll(sel); } @Override protected void onAllRight() { List<M> sel = fromStore.getAll(); toStore.addAll(sel); } @Override protected void onRight() { List<M> sel = fromView.getSelectionModel().getSelectedItems(); if (sel.size() > 0) { toStore.addAll(sel); toView.getSelectionModel().select(sel, false); } } }
-
5 Jan 2012 9:34 AM #2
Gr8 news
Gr8 news
Now I can use DualListField with GWT Editor. Also added getters for stores.
I do love GXT 3 flexibility!
Code:package ru.mesotron.jpauc.client.widget.form; import java.util.ArrayList; import java.util.List; import com.google.gwt.cell.client.Cell; import com.google.gwt.uibinder.client.UiConstructor; import com.google.web.bindery.requestfactory.shared.EntityProxy; import com.sencha.gxt.core.client.ValueProvider; import com.sencha.gxt.data.shared.ListStore; import com.sencha.gxt.data.shared.event.StoreAddEvent; import com.sencha.gxt.data.shared.event.StoreAddEvent.StoreAddHandler; import com.sencha.gxt.widget.core.client.ListView; public class DualListField<M extends EntityProxy, T> extends com.sencha.gxt.widget.core.client.form.DualListField<M, T> { protected ListStore<M> fromStore; protected ListStore<M> toStore; protected ListView<M, T> fromView; protected ListView<M, T> toView; @UiConstructor public DualListField(final ListStore<M> fromStore, final ListStore<M> toStore, ValueProvider<M, T> valueProvider, Cell<T> cell) { super(fromStore, toStore, valueProvider, cell); // Inheritance fix this.fromStore = fromStore; this.toStore = toStore; fromView = getFromView(); toView = getToView(); // If 'toStore' receives some item then the item should be removed from 'fromStore'. toStore.addStoreAddHandler(new StoreAddHandler<M>() { @Override public void onAdd(StoreAddEvent<M> event) { for (M item : event.getItems()) { M deleteItem = null; for (M existingItem : fromStore.getAll()) { if (existingItem.stableId().equals(item.stableId())) { deleteItem = existingItem; } } if (deleteItem != null) { fromStore.remove(deleteItem); } } } }); // If the item already exists in 'toStore' then it shoul be removed from 'fromStore' fromStore.addStoreAddHandler(new StoreAddHandler<M>() { @Override public void onAdd(StoreAddEvent<M> event) { for (M entity : event.getItems()) { for (M existing : toStore.getAll()) { if (existing.stableId().equals(entity.stableId())) { fromStore.remove(entity); } } } } }); } @Override protected void onAllLeft() { List<M> sel = new ArrayList<M>(toStore.getAll()); toStore.clear(); fromStore.addAll(sel); } @Override protected void onAllRight() { List<M> sel = fromStore.getAll(); toStore.addAll(sel); } @Override protected void onRight() { List<M> sel = fromView.getSelectionModel().getSelectedItems(); if (sel.size() > 0) { toStore.addAll(sel); toView.getSelectionModel().select(sel, false); } } @Override public List<M> getValue() { return getToStore().getAll(); } @Override public void setValue(List<M> value) { onAllLeft(); if (value != null) { getToStore().addAll(value); } } public ListStore<M> getToStore() { return toStore; } public ListStore<M> getFromStore() { return fromStore; } }
-
1 Feb 2012 6:01 PM #3
The Button Bar of DualListField is crowded
The Button Bar of DualListField is crowded
I propose to split it into two bars, one in the middle for moving items between the two lists, add another bar at right to host the two buttons for adjusting the order of items in the right list. Please see the attachment.
-
14 Feb 2012 4:03 AM #4
I agree with that idea and I did a few experiments on this. It's quite impractical to actually do this. I'll try to put something together using the original ListField source and suggest that as an update for GXT, since it seems like the best solution from my experiments. But that will probably not be before the next beta.


Reply With Quote