Change listbox MVVM template with Java or how to let user change column order

asked 2015-04-20 16:03:12 +0800

Neus gravatar image Neus
1415 14

updated 2015-04-21 08:39:41 +0800

Hi, I want to give the user the posibility to change the order of the columns in a listbox using drag and drop. I'm using MVVM and I thought of the possibilty to change the template by java code when the user drops one listheader to a different position. But I don't know how can I achieve this goal.

Does anyone have any idea to help me?

Thank you!

delete flag offensive retag edit

2 Answers

Sort by » oldest newest most voted

answered 2015-04-21 09:33:31 +0800

chillworld gravatar image chillworld flag of Belgium
5357 4 9

updated 2015-04-22 09:35:00 +0800

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 :

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
            // swap related Listcell in all Listitem instances
            for (Listitem item : ((Listbox) lHead.getParent()).getItems()) {
                Component comp = item.getChildren().get(from);
            //early return cause we have swapped to the last index. 
    // 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 :



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 :

    <listheader label="Columna 1" draggable="true" droppable="true" onDrop="@command('drop')">
        <custom-attributes field="columna1"/>
    <listheader label="Columna 2" draggable="true" droppable="true" onDrop="@command('drop')">
        <custom-attributes field="columna2"/>
    <listheader label="Columna 3" draggable="true" droppable="true" onDrop="@command('drop')">
        <custom-attributes field="columna3"/>
    <listheader label="Columna 4" draggable="true" droppable="true" onDrop="@command('drop')">
        <custom-attributes field="columna4"/>
<template name="model" var="item" >
        <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)])"/>    

Updated fiddle.

Greetz chill.

link publish delete flag offensive edit


please change the method name, it was a quick and bad call to name it drop ^^

chillworld ( 2015-04-21 09:40:54 +0800 )edit

Hi, using your example I found a problem in it. Because it is modifying components and not modifying the template if, after repositioning the columns the model is changed, the data is loaded as it was defined in the template. So,the headers are in the order the user decided but the data is not.

Neus ( 2015-04-22 08:04:29 +0800 )edit

You can find my code here http://zkfiddle.org/sample/7qki4o/1-Change-column-position-with-MVVM Just click the "Añadir más filas" button to add data to the model and you will see what I'm explaining

Neus ( 2015-04-22 08:10:03 +0800 )edit

ha damn, indeed. I'll see if I can find a solution

chillworld ( 2015-04-22 08:38:58 +0800 )edit

Maybe it is not the best solution but it's a good idea and it works! Thank you very much chill!

Neus ( 2015-04-22 09:59:17 +0800 )edit

answered 2015-04-21 09:18:50 +0800

Darksu gravatar image Darksu
1991 1 4

Hello Neus,

You can get some very good pointers from the following ZK Fiddle:


*Note that you can use drag-and-drop from Column B->Column A

Best Regards,


link publish delete flag offensive edit


Thank you Darsu. But this Fiddle do not use MVVM. It is changing the componens directly

Neus ( 2015-04-21 09:25:56 +0800 )edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

1 follower



Asked: 2015-04-20 16:03:12 +0800

Seen: 37 times

Last updated: Apr 22 '15

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More