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:
<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:
<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:
.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:
Populating Tags for Unmapped Listview
First of all, we will generate list of our tag objects by defining array as:
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:
var unmappedtag_datasource = new kendo.data.DataSource({
data: unmappedtag_taglist
});
Our next step is to bind Datasource
to Listview
as:
$("#unmappedtag_listview").kendoListView({
dataSource: unmappedtag_datasource,
template: '<div class="tags move k-block"> #:Name# </div>'
});
Let's see the result:
Let's make it beautiful by CSS:
.tags
{
margin: 10px;
padding: 10px;
float: left;
color: #fff;
}
Let's check it again:
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.
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"}];
var mappedtag_datasource = new kendo.data.DataSource({
data: mappedtag_taglist
});
$("#mappedtag_listview").kendoListView({
dataSource: mappedtag_datasource,
template: '<div class="tags move k-block"> #:Name# </div>'
});
Let's check it.
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:
<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:
$("#mappedtag_listview").kendoListView({
dataSource: mappedtag_datasource,
template: kendo.template($("#mappedtagtemplate").html())
});
Below CSS trick is used to set close button beside tag:
.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.
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.
$("#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:
.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
.
$("#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.
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.
$("#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.
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:
<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:
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