This is a migrated thread and some comments may be shown as answers.

Drag&Drop between listview with sorting

3 Answers 344 Views
Drag and Drop
This is a migrated thread and some comments may be shown as answers.
marco
Top achievements
Rank 2
marco asked on 25 Apr 2015, 12:30 PM

Hi,

 

I've been able to make drag&drop between two listview, but the dropped elements always go at the end of stack.

I'd like to position the dropped elements exactly where they are dropped, among the others, and then keep them sortable inside the listview.

Something like this: http://www.jqueryrain.com/?cy_emSfj

 

Currently my code is the following, but I'm not able to manage the position drop and sorting:

 

<div id="listA"></div>
<div id="listB"></div>
 
<script type="text/x-kendo-tmpl" id="template">
    <div class="bitem">
        Name: #: item # (#: position #)
        <a class="k-button k-button-icontext k-delete-button" id="delete_user"  href="javascript:delusr(this)"><span class="k-icon k-delete"></span>X</a>
    </div>
</script>
 
 
<script>
    //create dataSource
    var listA_DS = new kendo.data.DataSource({
        data: [
            { id: 1, item: "Label", position:0 },
            { id: 2, item: "Text", position: 0 },
            { id: 3, item: "Radio", position: 0 },
            { id: 4, item: "DropDown", position: 0 },
            { id: 5, item: "CheckBox", position: 0 }
        ],
        schema: {
            model: {
                id: "id",
                fields: {
                    id: { type: "number" },
                    item: { type: "string" },
                    position: { type: "number" }
                }
            }
        }
    });
 
    //display dataSource's data through ListView
    $("#listA").kendoListView({
        dataSource: listA_DS,
        template: "<div class='item'>Name: #: item #</div>"
    });
 
 
    //create a draggable for the parent container
    $("#listA").kendoDraggable({
        filter: ".item", //specify which items will be draggable
        dragstart: function (e) {
            var draggedElement = e.currentTarget, //get the DOM element that is being dragged
                dataItem = listA_DS.getByUid(draggedElement.data("uid")); //get corresponding dataItem from the DataSource instance
 
            console.log(dataItem);
        },
        hint: function (element) { //create a UI hint, the `element` argument is the dragged item
            return element.clone().css({
                "opacity": 0.6,
                "background-color": "#0cf"
            });
        }
    });
 
    var listB_DS = new kendo.data.DataSource({
        data: [ /* still no data */],
        schema: {
            model: {
                id: "id",
                fields: {
                    id: { type: "number" },
                    position: { type: "number" },
                    item: { type: "string" }
                }
            }
        }
    });
    $("#listB").kendoListView({
        dataSource: listB_DS,
        //template: "<div class='item'>ListB: #: item #</div>"
        template: kendo.template($("#template").html())
    });
 
    function addStyling(e) {
        this.element.css({
            "border-color": "#F00",
            "background-color": "#e0e0e0",
            "opacity": 0.6
        });
    }
 
    function resetStyling(e) {
        this.element.css({
            "border-color": "black",
            "background-color": "transparent",
            "opacity": 1
        });
    }
 
    var dest;
    $("#listB").kendoDropTarget({
        dragenter: addStyling, //add visual indication
        dragleave: resetStyling, //remove the visual indication
        drop: function (e) { //apply changes to the data after an item is dropped
            var draggableElement = e.draggable.currentTarget,
            dataItem = listA_DS.getByUid(draggableElement.data("uid")); //find the corresponding dataItem by uid
 
            dataItem.item = "ListB";
            dest = $(e.target);
            if (dest.get("id")) {
                //reorder the items
                var tmp = target.get("position");
                target.set("position", dest.get("position"));
                dest.set("position", tmp);
 
                listB_DS.sort({ field: "position", dir: "asc" });
            }
            else {
 
            }
 
            //listA_DS.remove(dataItem); //remove the item from ListA
            listB_DS.add(dataItem); //add the item to ListB
            $("#listB").height("+=60");
            resetStyling.call(this); //reset visual dropTarget indication that was added on dragenter
        }
    });
 
     
    function delusr(elem) {
        var item = $(elem).closest("[role='option']");
        var data = listB_DS.getByUid(item.data("uid"));
        alert(item);
    }
 
</script>
 
<style>
    #listA, #listB {
        width: 300px;
        height: 280px;
        float: left;
        margin-right: 30px;
        border: 3px solid black;
        border-radius: 3px;
    }
 
    .item, .bitem {
        margin: 5px;
        padding: 5px;
        text-align: center;
        border: 2px solid #ccc;
        border-radius: 5px;
        width:260px;
    }
</style>

3 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 29 Apr 2015, 06:12 AM
Hello Marco,

You can try the Kendo UI Sortable widget which integrates easily with the ListView.

Regards,
Atanas Korchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
marco
Top achievements
Rank 2
answered on 29 Apr 2015, 06:52 AM

Hi Atanas,

 

I've already tried to use sortable widget, but with no result. Maybe because there's a conflict with Kendo Drag&Drop or maybe because the listview to sort is initially empty.

I have used the following code:

$("#listB").kendoSortable({
    filter: ".bitem",
    cursor: "move",
    placeholder: function (element) {
        return element.clone().css("opacity", 0.1);
    },
    hint: function (element) {
        return element.clone().removeClass("k-state-selected");
    },
    change: function (e) {
        var skip = listB_DS.skip(),
            oldIndex = e.oldIndex + skip,
            newIndex = e.newIndex + skip,
            dataItem = listB_DS.getByUid(e.item.data("uid"));
 
        listB_DS.remove(dataItem);
        listB_DS.insert(newIndex, dataItem);
    }
});

 

Please note that the expected behaviour must be both drag&droppable and sortable, like the example provided in the previous post and like JQuery UI does with connected list: https://jqueryui.com/sortable/#connect-lists

 

Thanks

0
Genady Sergeev
Telerik team
answered on 01 May 2015, 01:26 PM
Hi Marco,

The implementation that you currently use assumes that ListView B as a whole is the drop target, whereas the jQuery UI example uses drop targets set to the individual items in the list.

You can try using kendoDragTargetArea instead of kendoDragTarget and provide a filter to filter the items in ListView B. kendoDragTarget can be used initially, while ListView is still empty (i.e. no target items available).

Regards,
Genady Sergeev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Drag and Drop
Asked by
marco
Top achievements
Rank 2
Answers by
Atanas Korchev
Telerik team
marco
Top achievements
Rank 2
Genady Sergeev
Telerik team
Share this question
or