Search
Drag and Drop in a ListView

This tutorial will show you how to build two lists whose items can be moved by drag and drop. You can only move items within the list and within the group.

.

I. References

You must load the following JavaScript files used by the UI controls:

JavaScript  Copy Code

<script src="drawing.js" type="text/javascript"></script>
<script src="controls.js" type="text/javascript"></script>
<script src="common.js" type="text/javascript"></script>
<script src="common-collections.js" type="text/javascript"></script>
<script src="common-ui.js" type="text/javascript"></script>

We will use a custom CSS style for the lists. We add the code for it in the <HEAD> section as well:

HTML  Copy Code

<style type="text/css">
/* The css class for the static list items. */
.static
{
 background-color: #000 !important;
 text-transform: uppercase;
}
</style>

II. The Lists

We create an array with the data to be used by the ListView instances. Then we add to the data array the data for a static, inactive ListItem:

JavaScript  Copy Code

var data = [];
data.push({ title: "Static Top", interactive: false, cssClass: "static" });

Then we create the data for the other ListItems:
 
JavaScript  Copy Code

for (var i = 1; i < 5; i++)
{
    data.push({ title: "Item" + i.toString() });
}

and we finish with another static item:

JavaScript  Copy Code

data.push({ title: "Static Bottom", interactive: false, cssClass: "static" });

This array will be loaded to the list by the fromObject method. We add a mapping to MindFusion.Common.UI namepsace and create the first list:

JavaScript  Copy Code

var ui = MindFusion.Common.UI;

// Create a new ListView control.
var list1 = new ui.ListView();
list1.theme = "business";
// Load the items data.
list1.fromObject(data);

We create the ListView through the constructor without parameters. In this case the ListView will be bound to a newly created <div> element. We need to add this element to the DOM tree of the page, somewhere between calling its draw and attach methods:

JavaScript  Copy Code

// Draw the control and append it to the page DOM.
document.body.appendChild(list1.draw());
// Prepare the control for user interaction.
list1.attach();

The second list is created in the same way as the first one with the difference that the two static items mark the beginning of the two groups of items. Here is the code for it:

JavaScript  Copy Code

// Create new data for the second list view.
var data = [];
data.push({ title: "Group 1", interactive: false, cssClass: "static" });
for (var i = 1; i < 5; i++)
{
 data.push({ title: "Item" + i.toString() });
}
data.push({ title: "Group 2", interactive: false, cssClass: "static" });
for (var i = 1; i < 5; i++)
{
 data.push({ title: "Item" + i.toString() });
}

// Create a new ListView control.
var list2 = new ui.ListView();
list2.left = ui.Unit.pixel(20);
list2.theme = "business";
list2.fromObject(data);

document.body.appendChild(list2.draw());
list2.attach();


III. Events

The first list supports the desired functionality by default: the active items can be dragged and dropped everywhere onto the list. We need some event handling for list2, where we would like to stop the user from dragging items from one group and dropping them on the other. In order to do this we handle the dragDrop event:

JavaScript  Copy Code

// Add event handlers
list2.dragDrop.addEventListener(listDragDrop);


The event handler method receives two arguments. The first one is the list that has sent the event. The second one is an instance of the DragDropEventArgs class, which provides valuable data for the event. We get the dropped item from the dropTarget property of the args parameter. Once we have it we can get its index with the indexOfItem method. We use the dragItem property to learn which is the item that was dragged and which its index is. Then we check if the two indexes belong to the same group e.g. if they are both less than or more than 5. If not, we cancel the action by setting the cancel property to true.

JavaScript  Copy Code

function listDragDrop(sender, args)
{
 var refItem = args.dropTarget.item;
 var refIndex = sender.items.indexOfItem(refItem);
 if (args.dropTarget.position == 1) refIndex += 1;

 var itemIndex = sender.items.indexOfItem(args.dragItem);

 if ((itemIndex < 5) && (refIndex > 5)) args.cancel = true;
 if ((itemIndex > 5) && (refIndex <= 5)) args.cancel = true;
}