View Full Version : GroupingGridDropTarget for drag sorting in grouping grid

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.


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() {

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) {

protected void showFeedback(DNDEvent 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)))) {

protected void onDragDrop(DNDEvent e) {

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

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


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);



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) {

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());

public class GroupingGridExample extends LayoutContainer {

int rowIndex = -1;

protected void onRender(Element parent, int index) {
super.onRender(parent, index);
setLayout(new FlowLayout(10));
GroupingStore<MyValue> store = new GroupingStore<MyValue>();

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>();
final ColumnModel cm = new ColumnModel(config);
GroupingView view = new GroupingView();

final Grid<MyValue> grid = new Grid<MyValue>(store, cm);
ContentPanel panel = new ContentPanel();
panel.setHeading("Grouping Example");
panel.setSize(400, 550);
panel.setLayout(new FitLayout());

new GridDragSource(grid);

GroupingGridDropTarget target = new GroupingGridDropTarget(grid);



27 Sep 2011, 4:37 AM

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.

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).