Reordering Table / Container

Hi

How can I easily re-order items in a table? I have “move up” and “move down” buttons that should move the selected item (only one selected) up or down when clicked.

Currently I make a IndexedContainer that is used as table container, and “move down” does roughly the following:

  1. Get the currently selected item
  2. Get the id from the IndexedContainer using indexOfId()
  3. Get all item properties and store them temporarily
  4. Remove the selected item from the table/container
  5. Re-add the item to the container at position (id+1)
  6. Loop through all container properties and re-set them for the item.

This seems unneccessary complicated for such a simple task.

How about adding a nonvisible property “order” to the container and keeping the indexed container sorder by it?

Then I would have to run table.sort() after each move? Doesn’t sound very efficient if the table contains thousands of items.

Also I would like to avoid extra fields like this because for every extra field there is some extra work that needs to be done when inserting an item.

Enhancing Container API has been noted. We will most likely add more helper functions in coming releases.

In the meantime you can add this to com.itmill.toolkit.data.util.IndexedContainer:

{{{
public void switchItems(Object itemId, int newIndex) {
int index = indexOfId(itemId);
if (index < 0 || newIndex < 0 || newIndex >= itemIds.size()) {
return;
}

itemIds.set(index, itemIds.get(newIndex));
itemIds.set(newIndex, itemId);
}
}}}

Above method switches itemId to index newIndex and original item at newIndex is placed to original place of itemId (two items are switched).

Thanks! Sounds great that you plan to include that functionality!

Another question:

Will the same fix work for the Tree component? I need to move a tree node up/down and can’t seem to find any good way to do it. I can’t even find a method for getting the next / previous sibling in the tree.

In short, no. But we’ll most likely provide similar enhancement that works for Tree too. They are quite simple to implement because of Container API.

Hi

By adding the following methods to HierarchicalContainer you get the functionality you need.


	public void swapChildren(Object parent, Object child1, Object child2) {
		if (noChildrenAllowed.contains(parent))
			return;

		LinkedList c =  (LinkedList) children.get(parent);
		int index1 = c.indexOf(child1);
		int index2 = c.indexOf(child2);
		
		if (index1 < 0 || index2 < 0)
			return;
		
		c.set(index1, child2);
		c.set(index2, child1);
	}
	
	public void swapChildWithPreviousSibling(Object child) {
		Object parentId = getParent(child);
		LinkedList c =  (LinkedList) children.get(parentId);
		int index = c.indexOf(child)-1;
		if (index <0 )
			return;
		
		swapChildren(parentId, child, c.get(index));
	}
	
	public void swapChildWithNextSibling(Object child) {
		Object parentId = getParent(child);
		LinkedList c =  (LinkedList) children.get(parentId);
		int index = c.indexOf(child)+1;
		if (index  >= c.size())
			return;
		
		swapChildren(parentId, child, c.get(index));
	}

Be sure to remember to set the containerDataSource for the tree by using

[code]

tree.setContainerDataSource(container)
[/code] so that a container of your type will be used.

Hi there,

I am looking for exactly that functionality in the HierarchicalContainer. Artur’s solution looks great but how can I add the methods to HierarchicalContainer? HierarchicalContainer is a Vaadin class and it’s fields are private which means I can’t even subclass it, right?

Thanks for any hints.

Andrea