Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Kendo UI Drag & Drop between Listviews Step by Step

4.86/5 (5 votes)
6 Nov 2013CPOL3 min read 41.9K  
A step by step tutorial for drag & drop between Kendo UI Listviews

Problem

Let's say we are making Tag map application in which we have two Kendo UI Listviews, one contains list of unmapped tags and the other contains list of mapped tags. Now we want to implement:

  • User can drag & drop items from UnmappedTag Listview to MappedTag Listview on drop, item should remove from UnmappedTag Listview and should added to MappedTag Listview.
  • Every item in MappedTag Listview contains a close button, on click this button item should be removed from MappedTag Listview and should be added to UnMappedTag Listview.

Setting up Environment

Create a new HTML file and add references of Kendo UI CSS & JS files as below:

HTML
<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.common.min.css" 
rel="stylesheet" />     
<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.flat.min.css" 
rel="stylesheet" />  
<script type="text/javascript" 
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>                                       
<script type="text/javascript" 
src="http://cdn.kendostatic.com/2013.2.716/js/kendo.web.min.js"></script>

For this tutorial, I have used Kendo UI web 2013.2.716 & Flat theme.

For more information about Kendo UI web, you can visit Kendo UI Web.

For more information about how to use Kendo UI CDN, you can visit How-To: Add Widgets with Kendo UI Web.

Test Layout

In this step, we will generate basic layout using HTML and CSS:

HTML
<div style="padding:30px;">
    <table>
        <tr>
            <td><h2>Unmapped Tags</h2></td>
            <td><h2>Mapped Tags</h2></td>
        </tr>
        <tr>
            <td>
                <div id="unmappedtag_listview" 
                class="tagcontainer"></div>        
            </td>
            <td>
                <div id="mappedtag_listview" 
                class="tagcontainer"></div>
            </td>
        </tr>
    </table>
</div>  

And CSS:

CSS
.tagcontainer
{
    float: left;
    margin-left: 10px;
    min-width: 400px;
    min-height: 510px;
    width: 400px;
}        
table > div
{
    border:1px solid #CDCDCD;
} 

By executing file, we will see result as:

Image 1

Populating Tags for Unmapped Listview

First of all, we will generate list of our tag objects by defining array as:

JavaScript
var unmappedtag_taglist = [{ "ID": 1, 
"Name": "ASP.NET" }, 
{ "ID": 2, "Name": "Kendo UI"},
{ "ID": 3, "Name": "CSharp"},{ "ID": 4, 
"Name": "Java Script"},
{ "ID": 5, "Name": "PHP"},{ "ID": 6, 
"Name": "Java"},{ "ID": 7, "Name": "CSS"},
{ "ID": 8, "Name": "HTML"},{ "ID": 9, 
"Name": "Unix"},{ "ID": 10, "Name": "Mac"}];

Now we use kendo.data.DataSource and convert array of objects to Datasource as:

JavaScript
var unmappedtag_datasource = new kendo.data.DataSource({
    data: unmappedtag_taglist
});

Our next step is to bind Datasource to Listview as:

JavaScript
$("#unmappedtag_listview").kendoListView({
    dataSource: unmappedtag_datasource,
    template: '<div class="tags move k-block">  #:Name# </div>'
});

Let's see the result:

Image 2

Let's make it beautiful by CSS:

CSS
.tags
{
    margin: 10px;
    padding: 10px;
    float: left;
    color: #fff;
}

Let's check it again:

Image 3

Populating Tags for Mapped Listview

This step is almost similar as the previous one, just one more work that is we have to create a close button beside tag. So that user removes tag from Listview by clicking on it.

JavaScript
var mappedtag_taglist = [{ "ID": 100, "Name": 
"Razor View" }, { "ID": 101, "Name": "JQuery"}, 
{ "ID": 102, "Name": "MS Sql"}, 
{ "ID": 103, "Name": "My Sql"}, 
{ "ID": 104, "Name": "Ruby"},
{ "ID": 105, "Name": "SQL"}];
JavaScript
var mappedtag_datasource = new kendo.data.DataSource({
    data: mappedtag_taglist
});
JavaScript
$("#mappedtag_listview").kendoListView({
    dataSource: mappedtag_datasource,
    template: '<div class="tags move k-block">  #:Name# </div>'
});

Let's check it.

Image 4

Looking good but Mapped Tag Listview is missing close button. Let's add it with the help of Kendo UI Templates & CSS. New template for tag is:

JavaScript
<script type="text/x-kendo-tmpl" 
id="mappedtagtemplate">        
    <div style=""display:inline-block"">
        <div class="tags k-block"> #:Name# </div>
        <a href="javascript:" class="k-button tagitemcls">
            <span class="k-icon k-i-close"></span>
        </a>
    </div>
</script>

Now our Listview code will be as:

JavaScript
$("#mappedtag_listview").kendoListView({
    dataSource: mappedtag_datasource,
    template: kendo.template($("#mappedtagtemplate").html())
});

Below CSS trick is used to set close button beside tag:

CSS
.tagitemcls
{
    width: 24px;
    float: left;
    margin-left: -18px;
    margin-top: 10px;
    padding-top: 6px;
    padding-bottom: 8px;
    padding-left: 2px;
}

Let's check the result.

Image 5

Adding Drag & Drop Support

We have completed our basic layout, now first of all we are going to add drag support to unmapped Listview by kendoDraggable, it’s a just line of code and that’s it. We use move class as filter so that every element in list having move class acts as a draggable item.

JavaScript
$("#unmappedtag_listview").kendoDraggable({
    filter: ".move",
    hint: function (element) {
        return element.clone();
    }
}); 

Here is the CSS for move, we want to change cursor as 'move' when on tag item:

CSS
.move
{
    cursor: move;
}

Our next task is to add drop support to mapped tag Listview by kendoDropTarget so that user can drag tags from Unmapped Listview and drop to Mapped Listview.

JavaScript
$("#mappedtag_listview").kendoDropTarget({
    dragenter: function (e) {
        e.draggable.hint.css("opacity", 0.6);                  
    },
    dragleave: function (e) {
        e.draggable.hint.css("opacity", 1);                  
    }
});   

Let's check the result.

Image 6

Now we can drag tags from Unmapped Listview when it enters in Mapped Listview its opacity changes and on dropping nothing happened.

Now we are going to use benefits of drop event of kendoDropTarget. When this event is raised, we will get object data associated with this tag from Unmapped tag Datasource, once we have get it our next step is to add this data object to Mapped tag Datasource and remove this data object from Unmapped tag Datasource. Kendo Datasource implements observable collection very efficiently. So any change in Datasource reflects change to binding control immediately.

JavaScript
$("#mappedtag_listview").kendoDropTarget({
    dragenter: function (e) {
        e.draggable.hint.css("opacity", 0.6);                  
    },
    dragleave: function (e) {
        e.draggable.hint.css("opacity", 1);                  
    },
    drop: function (e) {                                                        
        var item = unmappedtag_datasource.getByUid(e.draggable.hint.data().uid);
        mappedtag_datasource.add(item);                    
        unmappedtag_datasource.remove(item);                    
    }
});

Let's check the result.

Image 7

Adding Removing Tag Support

Until now, we can drag Tags from Unmapped Listview and drop to Mapped Listview, each tag after dropping is added to Mapped Listview and removed from Unmapped Listview.

We are just one step away from our goal and that is to remove tag from Mapped Listview by clicking on close button.

For doing so, we have to change our template and add onclick event to it as:

JavaScript
<script type="text/x-kendo-tmpl" id="mappedtagtemplate">        
    <div style="display:inline-block">
        <div class="tags k-block"> #:Name# </div>
        <a href="javascript:" class=""k-button tagitemcls" 
        onclick="removeitem(this,'#:uid#')">
            <span class="k-icon k-i-close"></span>
        </a>
    </div>
</script>

Our final step is to add a JavaScript function removeitem as:

JavaScript
function removeitem(e, id) {
    var item = mappedtag_datasource.getByUid(id);
    unmappedtag_datasource.add(item);
    mappedtag_datasource.remove(item);
    $(e).parent().remove()
}

That's the end.

For a working on-line demo, you can visit:

History

  • 6th November, 2013: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)