PDA

View Full Version : GroupingGridDropTarget for drag sorting in grouping grid



Arno.Nyhm
29 Jan 2010, 10:40 AM
thanks to Nico33 for the idea in the thread "DND for roerdering rows on a grouping grid" (http://www.extjs.com/forum/showthread.php?p=428006#post428006)



I created this Class you can use as a drop in replacement for GridDropTarget. but it is for the special case of moving items.

18511
18512




package com.mycompany.myapplication.client.gui.components;

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.dnd.GridDropTarget;
import com.extjs.gxt.ui.client.event.DNDEvent;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreSorter;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import java.util.List;

/**
*
* @author Arno.Nyhm
*/
public class GroupingGridDropTarget extends GridDropTarget {

public static final String ORDER_FIELD_NAME = "GroupingGridDropTarget-order";
private StoreSorter groupingStoreSorter = new StoreSorter() {

@Override
public int compare(Store store, ModelData m1, ModelData m2, String property) {
if (property == null) {
return super.compare(store, m1, m2, ORDER_FIELD_NAME);
} else {
return super.compare(store, m1, m2, property);
}
}
};

public GroupingGridDropTarget(Grid grid) {
super(grid);
}

@Override
protected void showFeedback(DNDEvent e) {
super.showFeedback(e);
// not a null node:
if (this.activeItem != null) {
ModelData source = ((List<ModelData>) e.getData()).get(0);
String groupState = ((GroupingStore) grid.getStore()).getGroupState();

if (activeItem == null || (groupState != null && !source.get(groupState).equals(activeItem.get(groupState)))) {
e.getStatus().setStatus(false);
}
}
}

@Override
protected void onDragDrop(DNDEvent e) {

GroupingStore store = ((GroupingStore) grid.getStore());

setOrder(store);
if (store.isGroupOnSort()) {
throw new IllegalArgumentException("GroupOnSort is not supportet by GroupingGridDropTarget");
}

checkStoreSorter(store);

if (activeItem != null) {
Integer currentOrder = store.getAt(insertIndex).get(ORDER_FIELD_NAME);
Integer newOrder = currentOrder - 1;

ModelData source = ((List<ModelData>) e.getData()).get(0);
source.set(ORDER_FIELD_NAME, newOrder);

}

super.onDragDrop(e);
}

public void setOrder(ListStore<ModelData> store) {

Integer count = 0;
for (ModelData modelData : store.getModels()) {
modelData.set(ORDER_FIELD_NAME, count);
count += 2;
}
}

private void checkStoreSorter(GroupingStore store) {
if (store.getStoreSorter() != groupingStoreSorter) {
store.setStoreSorter(groupingStoreSorter);
}
}
}

and here is a working example code:





package com.mycompany.myapplication.client.forumsnippets;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.dnd.DND.Feedback;
import com.extjs.gxt.ui.client.dnd.DND.Operation;
import com.extjs.gxt.ui.client.dnd.GridDragSource;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Element;
import com.unitymedia.umvi.client.gui.components.GroupingGridDropTarget;

final class MyValue extends BaseModel {

private static final long serialVersionUID = -3209667217029014368L;

public MyValue(String group, String name, String city) {
set("group", group);
set("name", name);
set("city", city);
}

public static List<MyValue> getValues() {
List<MyValue> list = new ArrayList<MyValue>();

for (int i = 1; i <= 5; i++) {

list.add(new MyValue("group 1", "Name " + i, "City " + i));

list.add(new MyValue("group 2", "OtherName " + i, "City " + i));
list.add(new MyValue("group 3", "Familyname " + i, "City " + i));
}
return list;
}
}

/**
*
* @author Arno.Nyhm
*/
public class ForumThread429942DragDropGroupingGrid2 implements EntryPoint {

public void onModuleLoad() {
Window window = new Window();
window.setSize(500, 600);
window.add(new GroupingGridExample());
window.show();
}

public class GroupingGridExample extends LayoutContainer {

int rowIndex = -1;

@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
setLayout(new FlowLayout(10));
GroupingStore<MyValue> store = new GroupingStore<MyValue>();
store.add(MyValue.getValues());
store.groupBy("group");

ColumnConfig group = new ColumnConfig("group", "group", 80);
ColumnConfig name = new ColumnConfig("name", "Name", 80);
ColumnConfig order = new ColumnConfig("city", "City", 80);
List<ColumnConfig> config = new ArrayList<ColumnConfig>();
config.add(group);
config.add(name);
config.add(order);
final ColumnModel cm = new ColumnModel(config);
GroupingView view = new GroupingView();
view.setShowGroupedColumn(false);
view.setForceFit(true);

final Grid<MyValue> grid = new Grid<MyValue>(store, cm);
grid.setView(view);
grid.setBorders(true);
ContentPanel panel = new ContentPanel();
panel.setHeading("Grouping Example");
panel.setCollapsible(true);
panel.setFrame(true);
panel.setSize(400, 550);
panel.setLayout(new FitLayout());
panel.add(grid);
add(panel);

new GridDragSource(grid);

GroupingGridDropTarget target = new GroupingGridDropTarget(grid);
target.setAllowSelfAsSource(true);
target.setOperation(Operation.MOVE);

target.setFeedback(Feedback.INSERT);

}
}
}

abbnet
27 Sep 2011, 4:37 AM
Hello,

I would like to have a grid with group and allow the user to change the order of row in a group.
This post seems to answer to my need, but it does not work correctly for me. Actually, when I drag and drop a row, the row is always put at the end (of the sub-group). It is as if the operation = "append" (and not "insert"). But I force and log, and it seems to be "insert" feedback.

I noticed that executing this kind of code : store.insert(source, insertIndex); => fires the event Add. So, I am supposing that the element is always "add" instead of "insert".

I am using GWT 2.4.0 and GXT 2.2.4.

My need is quite basic : drag and drop row in the grip with group (note: the feature that forbides moving element in another group is fine).
My issue is : the dragged row is always "append" instead of "insert" at the position.

abbnet
27 Sep 2011, 4:57 AM
thanks to Nico33 for the idea in the thread "DND for roerdering rows on a grouping grid" (http://www.extjs.com/forum/showthread.php?p=428006#post428006)

I have a look to this post, and I understand why I have the feeling of "appending the row at the end". It is due to the store.sort().
I explicitly add store.sort("myPersonnalColumnOrder", SortDir.ASC); => now the row is correctly sorted (and no visual effect of "append" at the end, anymore).