Drag&Drop between listview with sorting

4 posts, 0 answers
  1. marco
    marco avatar
    33 posts
    Member since:
    Sep 2007

    Posted 25 Apr 2015 Link to this post

    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>

  2. Atanas Korchev
    Admin
    Atanas Korchev avatar
    8462 posts

    Posted 29 Apr 2015 Link to this post

    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!
     
  3. Kendo UI is VS 2017 Ready
  4. marco
    marco avatar
    33 posts
    Member since:
    Sep 2007

    Posted 29 Apr 2015 in reply to Atanas Korchev Link to this post

    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

  5. Genady Sergeev
    Admin
    Genady Sergeev avatar
    1596 posts

    Posted 01 May 2015 Link to this post

    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!
     
Back to Top
Kendo UI is VS 2017 Ready