Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

on drag change stylesheets for all dropzones (file upload)

I have multiple dropzones for uploading files on a webpage

How to highlight all dropzone elements as soon as a file is dragged into the browser, so the user knows where to drop the file? And when a file is dragged over one of the dropzones I need to add an additional class to indicate the user can release the file

update

kurideja pointed me in the right direction to Dragster

https://github.com/bensmithett/dragster

Now it almost works :)

  • If you drag over one dropzone and drag back out without releasing the file all dropzones are hidden

http://jsfiddle.net/L7v2f96z/9/

html

<div class="dropzone"></div>
<div class="dropzone"></div>

javascript

//    Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
    enter : function(){
        $(this).show().addClass('hover');
    },
    leave : function(){
        $(this).hide().removeClass('hover');
    }
});

//    Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
    enter : function(){
        $('.dropzone').show();
    },
    leave : function(){
        $('.dropzone').hide();
    }
})
//    Prevent defaults (file is openened in the browser) if user drops file outside a dropzone
.on('dragover', function(e){
    e.preventDefault();
})
.on('drop', function(e){
    e.preventDefault();
    w.trigger('dragleave');
});

css

.dropzone {
    width:200px;
    height:200px;
    background:#fff;
    display:none;
    border:2px dashed rgba(0,0,0,0.5);
    box-shadow:0 2px 5px rgba(0,0,0,0.1), inset 0 0 40px rgba(0,0,0,0.1);
    border-radius:2px;
    margin:10px;
}

.dropzone.hover {
    background:#e3e3e3;
}
like image 211
clarkk Avatar asked Jan 01 '15 15:01

clarkk


2 Answers

Main problem was: after leaving the dropzone area, dragster triggered leave twice, both on .dropzone and window. Simply adding e.stopPropagation() solves the problem. There are also few more fixes (removed show() and hide() inside dropzone dragster). Your code on Fiddle and also below:

// Add/remove class when file is dragged over the dropzone. Hover effect
$('.dropzone').dragster({
    enter: function() {
        $(this).addClass('hover');
    },
    leave: function(e) {
        e.stopPropagation(); //-- Critical point
        $(this).removeClass('hover');
    }
});

// Show/hide dropzones until a file is dragged into the browser window. Hide dropzones after file is dropped or dragging is stopped
var w = $(window).dragster({
    enter: function() {
        $('.dropzone').show();
    },
    leave: function() {
        $('.dropzone').hide();
    }
})
// Prevent defaults (file is openened in the browser) if user drop file outside a dropzone
.on('dragover', function(e) {
    e.preventDefault();
})
    .on('drop', function (e) {
    e.preventDefault();
    w.trigger('dragleave');
});
like image 122
skobaljic Avatar answered Nov 15 '22 12:11

skobaljic


You can use e.originalEvent.pageXand e.originalEvent.pageY on dragover and check if its in a range of the box. For this example I have copied the dropzone and I know the width and height of the div so I could hardcode the condition. You will have to come up with a way to store the position(top and left) of the dropzone areas and use that for comparison.

var drag_timer;
$(document).on('dragover', function (e) {
    var dt = e.originalEvent.dataTransfer;

    if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) {
        if (e.originalEvent.pageX <= 200 && e.originalEvent.pageY <= 200) {
            $('.dropzone').removeClass('highlight');
            $('.dropzone:eq(0)').addClass('highlight');
        } else if (e.originalEvent.pageX <= 400 && e.originalEvent.pageY <= 400) {
            $('.dropzone').removeClass('highlight');
            $('.dropzone:eq(1)').addClass('highlight');
        } else {
            $('.dropzone').removeClass('highlight');
        }

        $('.dropzone').show();
        window.clearTimeout(drag_timer);
    }
})
.on('dragleave', function (e) {
  drag_timer = window.setTimeout(function () {
    $('.dropzone').hide();
  }, 50);
});

Demo Fiddle

like image 2
anpsmn Avatar answered Nov 15 '22 13:11

anpsmn