answered
2015-04-21 09:33:31 +0800
chillworld
5357 ● 4 ● 9
https://github.com/chillw...
Hey Neus,
You know I just like to share the code so after reading this topic on SO,
it looks like the drag and drop play I had to use.
So starting to convert the method to MVVM and I found out a minor point that when I drag from left to right the item was always placed before in stead of after.(so you never set something at the last column)
After some modifications, I came up to the following method :
@Command
public void drop(@ContextParam(ContextType.TRIGGER_EVENT) DropEvent event) {
Listheader dragged = (Listheader) event.getDragged();
Listheader droppedOn = (Listheader) event.getTarget();
Listhead lHead = (Listhead) dragged.getParent();
// then get their indexes.
int from = lHead.getChildren().indexOf(dragged);
int to = lHead.getChildren().indexOf(droppedOn);
if (from < to) {
if (to < lHead.getChildren().size() - 1) {
// left to right modification cause there is no insertAfter.
droppedOn = (Listheader) lHead.getChildren().get(++to);
} else {
// swap the positions
lHead.removeChild(dragged);
lHead.appendChild(dragged);
// swap related Listcell in all Listitem instances
for (Listitem item : ((Listbox) lHead.getParent()).getItems()) {
Component comp = item.getChildren().get(from);
item.removeChild(comp);
item.appendChild(comp);
}
//early return cause we have swapped to the last index.
return;
}
}
// swap the positions
lHead.insertBefore(dragged, droppedOn);
// swap related Listcell in all Listitem instances
for (Listitem item : ((Listbox) lHead.getParent()).getItems()) {
item.insertBefore(item.getChildren().get(from), item.getChildren().get(to));
}
}
This is very generic code what you could set in a abstractVM and as long you set the draggable, droppable and the onDrop correct this would work for every listbox.
I created the following fiddle :
http://zkfiddle.org/sample/3g4uaer/1-listbox-dynamicly-headers-MVVM
Edit:
After comment of bug when a notifychanged is happened that the listcells are back at default place.
I first wanted to change the Template
itself but that is almost impossible from java.
Next one I wanted to try was making the template so that he must see in the header what he needed to load.
With this approach I came up to the following, what is maybe not the best solution but it is one solution :
<listhead>
<listheader label="Columna 1" draggable="true" droppable="true" onDrop="@command('drop')">
<custom-attributes field="columna1"/>
</listheader>
<listheader label="Columna 2" draggable="true" droppable="true" onDrop="@command('drop')">
<custom-attributes field="columna2"/>
</listheader>
<listheader label="Columna 3" draggable="true" droppable="true" onDrop="@command('drop')">
<custom-attributes field="columna3"/>
</listheader>
<listheader label="Columna 4" draggable="true" droppable="true" onDrop="@command('drop')">
<custom-attributes field="columna4"/>
</listheader>
</listhead>
<template name="model" var="item" >
<listitem>
<listcell label="@load(item[self.listheader.getAttribute('field',Component.COMPONENT_SCOPE)])"/>
<listcell label="@load(item[self.listheader.getAttribute('field',Component.COMPONENT_SCOPE)])"/>
<listcell label="@load(item[self.listheader.getAttribute('field',Component.COMPONENT_SCOPE)])"/>
<listcell label="@load(item[self.listheader.getAttribute('field',Component.COMPONENT_SCOPE)])"/>
</listitem>
</template>
Updated fiddle.
Greetz chill.