knockout.jsknockout-sortable

Copying an item rather than moving in the knockout sortable seating chart example


This is the seating chart example of knockout sortable: http://jsfiddle.net/UdXr4/ Based on the answers of this and this, I tried to change the seating chart example such that the items from available students copied rather than moved as in the jsfiddle here

The changes are shown below :

......
......
<div class="seats" data-bind="sortable: { data: students, allowDrop: $root.isTableFull, dragged: handleDraggedItem }">
......
......
<div class="new" data-bind="sortable: availableStudents">
        <div class="student available" data-bind="text: name"></div>
    </div>
.......
.......
Student.prototype.clone = function() {
    return new Student(this.id,this.name(),this.gender);
};
.......
.......
this.handleDraggedItem = function(item, event, ui) {
        console.log("handleDraggedItem");
        **return new Student(0,ui.item.text(),'');**
    };
.......
.......
$(".available").draggable({
    connectToSortable: ".seats",
    helper: "clone",
    start: function(event, ui) {
        ko.utils.domData.set(event.target, "ko_dragItem", true);
    }
});

The code that I'm unable to solve is the handledraggeditem [return new Student(0,ui.item.text(),'')]. How can I get the other values (id and gender) except name(this I'm able to get from text) such that I can send them here..

Due to this the $data for the dragged items have 0 as id and '' as gender as below..

{
          "id": 9,
          "name": "Kylie",
          "gender": "female",
          "group": "griffindor"
        },
        {
          "id": 0,
          "name": "Angel",
          "gender": "",
          "group": ""
        }

Any help is sincerely appreciated

Thanks


Solution

  • When the user starts to drag an element, you are currently attaching a value of true to it:

    $(".available").draggable({
        connectToSortable: ".seats",
        helper: "clone",
        start: function(event, ui) {
            ko.utils.domData.set(event.target, "ko_dragItem", true); // <---
        }
    });
    

    Whatever data you attach there is what the dragged: callback will receive as its first argument — in your case, handleDraggedItem:

    this.handleDraggedItem = function(item, event, ui) {
      // 'item' is now 'true'
      console.log("handleDraggedItem");
    };
    

    If you instead look up the Student that is bound to the dragged element with ko.dataFor and attach that:

    start: function(event, ui) {
      var student = ko.dataFor(event.target);
    
      ko.utils.domData.set(event.target, "ko_dragItem", student);
    }
    

    your handleDraggedItem handler will receive that Student as its first argument, and you can call your Student.prototype.clone method on it:

    this.handleDraggedItem = function(item, event, ui) {
      return item.clone();
    };