Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and drop in multiple browser windows / tabs

Wrote some code to drag and drop elements to other elements. This works fine.

var currentDragElement = null;
var draggableElements = document.querySelectorAll('[draggable="true"]');


[].forEach.call(draggableElements, function(element) {
    element.addEventListener('dragstart', handleDragStart, false);
    element.addEventListener('dragenter', handleDragEnter, false);
    element.addEventListener('dragover', handleDragOver, false);
    element.addEventListener('dragleave', handleDragLeave, false);
    element.addEventListener('drop', handleDrop, false);
    element.addEventListener('dragend', handleDragEnd, false);
});

function handleDragStart(event) {
    currentDragElement = event.target;
    event.dataTransfer.setData("text/plain", event.target.dataset.uuid);
}


function handleDragOver(event) {
    event.preventDefault();

    event.dataTransfer.dropEffect = 'move';
    return false;
}

function handleDragEnter(event) {
    this.classList.add('over');
}

function handleDragLeave(event) {
    this.classList.remove('over');
}

function handleDrop(event) {
    event.stopPropagation();
    event.preventDefault();

    if(currentDragElement == event.target) {
        return;
    }

    console.log('dragged element ', currentDragElement.dataset.uuid , ' on element ', event.target.dataset.uuid)

    return false;
}

function handleDragEnd(event) {
    [].forEach.call(draggableElements, function (element) {
        element.classList.remove('over');
    });
}
section {
    border: solid 5px green;
    margin: 20px;
    float: left;
    width: 40%;
}

[draggable="true"]:hover {
    opacity: 0.6;
}

[draggable="true"] {
    cursor: move;
    background-color: #acacac;
    padding: 10px;
    margin: 10px;
}

.over[draggable="true"] {
    background-color: orange;
}
<section>
    <div draggable="true" data-uuid="1.1">draggable 1.1</div>
    <div draggable="true" data-uuid="1.2">draggable 1.2</div>
    <div draggable="true" data-uuid="1.3">draggable 1.3</div>
</section>

<section>
    <div draggable="true" data-uuid="2.1">draggable 2.1</div>
    <div draggable="true" data-uuid="2.2">draggable 2.2</div>
    <div draggable="true" data-uuid="2.3">draggable 2.3</div>
</section>

But what I want is the ability to have two open windows from the same browser and then drag and drop the draggable="true" elements from one window into the other.

As my code is now that does not work because

var currentDragElement = null;

remains null if draging from other window/tab. The question is how can I get the drag start element if started in other window or tab of same browser? So I want the console to state the same if dragging from different windows as it does now if drag and drop in same window.

Please NO jQuery answers, thanks for helping!

like image 229
caramba Avatar asked Apr 06 '17 11:04

caramba


Video Answer


1 Answers

As @Mouser pointed out localstorage does the trick even without any ajax request or the like..

Tested in Google Chrome only

The use of localstorage is not permitted in SO fiddles so if anyone wants to try this out copy the following file save it, open it in two browser windows and have fun with drag and drop

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>drag - drop - demo</title>
    <style>

        section {
            border: solid 5px green;
            margin: 20px;
            float: left;
            width: 40%;
        }

        [draggable="true"]:hover {
            opacity: 0.6;
        }

        [draggable="true"] {
            cursor: move;
            background-color: #acacac;
            padding: 10px;
            margin: 10px;
        }

        .over[draggable="true"] {
            background-color: orange;
        }

    </style>
</head>
<body>

<section>
    <div draggable="true" data-uuid="1.1">draggable 1.1</div>
    <div draggable="true" data-uuid="1.2">draggable 1.2</div>
    <div draggable="true" data-uuid="1.3">draggable 1.3</div>
    <div draggable="true" data-uuid="1.4">draggable 1.4</div>
    <div draggable="true" data-uuid="1.5">draggable 1.5</div>
</section>

<section>
    <div draggable="true" data-uuid="2.1">draggable 2.1</div>
    <div draggable="true" data-uuid="2.2">draggable 2.2</div>
    <div draggable="true" data-uuid="2.3">draggable 2.3</div>
    <div draggable="true" data-uuid="2.4">draggable 2.4</div>
    <div draggable="true" data-uuid="2.5">draggable 2.5</div>
</section>

<script>

    var draggableElements = document.querySelectorAll('[draggable="true"]');

    [].forEach.call(draggableElements, function(element) {
        element.addEventListener('dragstart', handleDragStart, false);
        element.addEventListener('dragenter', handleDragEnter, false);
        element.addEventListener('dragover', handleDragOver, false);
        element.addEventListener('dragleave', handleDragLeave, false);
        element.addEventListener('drop', handleDrop, false);
        element.addEventListener('dragend', handleDragEnd, false);
    });

    function handleDragStart(event) {
        localStorage.setItem('currentDragElement', event.target.dataset.uuid);
        event.dataTransfer.setData("text/plain", event.target.dataset.uuid);
    }


    function handleDragOver(event) {
        event.preventDefault();
        event.dataTransfer.dropEffect = 'move';
        return false;
    }

    function handleDragEnter(event) {
        this.classList.add('over');
    }

    function handleDragLeave(event) {
        this.classList.remove('over');
    }

    function handleDrop(event) {
        event.stopPropagation();
        event.preventDefault();

        if(localStorage.getItem('currentDragElement') == event.target.dataset.uuid) {
            return;
        }

        currentDragElement = document.querySelector('[data-uuid="'+localStorage.getItem('currentDragElement')+'"]');

        console.log('dragged element ', currentDragElement , ' on element ', event.target)

        localStorage.setItem('currentDragElement', null);

        return false;
    }

    function handleDragEnd(event) {
        [].forEach.call(draggableElements, function (element) {
            element.classList.remove('over');
        });
    }


</script>

</body>
</html>
like image 126
caramba Avatar answered Oct 09 '22 03:10

caramba