Question

I am trying to implement drag and drop files from desktop using knockout. The starting code is taken from html5rocks.

I tried to implement this using event binding, so my View looks something like this:

<div class="drop_zone" data-bind="event:{
    dragover:   function(data, e){ $root.dragover(e);},
    drop:       function(data, e){ $root.drop(e, $parent);},
    dragenter:  function(data, e){ $root.dragenter(e);},
    dragleave:  function(data, e){ $root.dragleave(e);}
}">Drop files here</div>

The $parent parameter was used in attempt to do something similar to my previous question, where parent was able to locate where exactly the element should be removed.

My ViewModel is an observableArray of observableArrays (many dropzones) and looks like this:

this.dropZones = ko.observableArray([{
    'elements' : ko.observableArray([])
},{
    'elements' : ko.observableArray([])
}]);

The full code can be found in jsFiddle, but the problem is that I can not properly add new files to the files element. Also I can not correctly highlight the element the person is dragEntering/Leaving.

I understand why I can not highlight the proper element (I just select every class, but I can not understand how to select the parent element), I am failing to understand why parent.elements.push(f.name); does not add the name of the file to the right parent.

Can anyone please tell me what is the problem and how can I fix it?

P.S. in jsFiddle I get the error:

TypeError: Cannot read property 'dataTransfer' of undefined

which tells me that I am passing wrong event, but the same code on my local server does not give me this problem. The error which I am getting on localhost is:

Uncaught TypeError: Cannot call method 'push' of undefined

which tells me that my idea of using parent was wrong.

Was it helpful?

Solution

1) { $root.drop(e, $data);} instead of { $root.drop(e, $parent);}

2) var files = e.dataTransfer.files; (without originalEvent)

Fiddle. (I've not fixed problem with css, do it youself :))

You should use $data instead of $parent because of elements is the property of each dropZone element. So, when you iterate with foreach: dropZones you have access to current element by $data, and you should send to $root.drop function current element (not parent) for get access to it elements array.

Update:
Solved CSS problem. (with help of $index() and jQuery .eq())

You could read about binding context (parent, data, index and etc.) here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top