Languages
[Edit]
EN

JavaScript - drag element from one container to other one

21 points
Created by:
sarah_ldp
1480

In this short article, we would like to show how in JavaScript write simple logic that lets' drag some elements from one place to another.

Item dragging from one place to another one.
Item dragging from one place to another one.

Using the below Dragger class we are able to create few independent draggable workspaces - items are draggable only between indicated groups.

Note: presented solution doesn't work on touched screens - mouse needed.

Simple usage:

var workspace = document.querySelector('.workspace');

var dragger = new Dragger(workspace);

dragger.addDropzone(workspace.querySelector('.dropzone-1')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-2')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-3')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-4')); // place to put draggable item
        
dragger.addDraggable(workspace.querySelector('.draggable-1')); // draggable item
dragger.addDraggable(workspace.querySelector('.draggable-2')); // draggable item

dragger.enable();

Practical example: 

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <script>

    var counter = 0;

    function checkDraggable(draggable) {
      	return draggable.$$_TYPE_$$ == 'DRAGGABLE'
    };

    function checkDropzone(dropzone, selection) {
      	return dropzone.$$_TYPE_$$ == 'DEROPZONE' && dropzone.$$_ID_$$ == selection.$$_ID_$$;
    };
    
    function Dragger(workspace) {
      
      	var id = ++counter;
        var enabled = false;
        var selection = null;
      
        var onDrag = function(e) {
            // nothing here ...
        };

        var onDrop = function(e) {
            if (selection) {
                var dropzone = e.target;
                if (checkDropzone(dropzone, selection)) {
                    dropzone.classList.remove('active');
                    dropzone.classList.add('default');  
                    dropzone.appendChild(selection);
                }
            }
        };

        var onDragstart = function(e) {
            var draggable = e.target;
            if (checkDraggable(draggable)) {
                draggable.classList.remove('default');
                draggable.classList.add('active');
            	selection = draggable;
            }
        };

        var onDragend = function(e) {
            if (selection) {
                var draggable = e.target;
                if (checkDraggable(draggable)) {
                  	draggable.classList.remove('active');
                    draggable.classList.add('default');
                	selection = null;
                }
            }
        };

        var onDragover = function(e) {
            e.preventDefault();
        };

        var onDragenter = function(e) {
          	if (selection) {
                var dropzone = e.target;
                if (checkDropzone(dropzone, selection)) {
                    dropzone.classList.remove('default');
                    dropzone.classList.add('active');
                }
            }
        };

        var onDragleave = function(e) {
          	if (selection) {
                var dropzone = e.target;
                if (checkDropzone(dropzone, selection)) {
                    dropzone.classList.remove('active');
                    dropzone.classList.add('default');
                }
            }
        };

        this.addDraggable = function(handle) {
            if (handle.$$_TYPE_$$) {
              	throw new Error('Element already in use.');
            }
            handle.draggable = true;
            handle.$$_ID_$$ = id;
            handle.$$_TYPE_$$ = 'DRAGGABLE';
            handle.classList.add('default');
        };
      
      	this.removeDraggable = function(handle) {
            if (handle.$$_TYPE_$$ == 'DRAGGABLE') {
                handle.draggable = false;
                delete handle.$$_ID_$$;
                delete handle.$$_TYPE_$$;
                handle.classList.remove('default');
            }
          	else
              	throw new Error('Element is not draggable.');
        };

        this.addDropzone = function(handle) {
            if (handle.$$_TYPE_$$) {
              	throw new Error('Element already in use.');
            }
            handle.$$_ID_$$ = id;
            handle.$$_TYPE_$$ = 'DEROPZONE';
            handle.classList.add('default');
        };
      
      	this.removeDropzone = function(handle) {
            if (handle.$$_TYPE_$$ == 'DEROPZONE') {
                delete handle.$$_ID_$$;
                delete handle.$$_TYPE_$$;
                handle.classList.add('default');
            }
          	else
            	throw new Error('Element is not dropzone.');
        };
      
      	this.enable = function() {
          	if (enabled == true) {
            	return;
            }
            workspace.addEventListener('drag', onDrag, false);
            workspace.addEventListener('drop', onDrop, false);
            workspace.addEventListener('dragstart', onDragstart, false);
            workspace.addEventListener('dragend', onDragend, false);
            workspace.addEventListener('dragover', onDragover, false);
            workspace.addEventListener('dragenter', onDragenter, false);
            workspace.addEventListener('dragleave', onDragleave, false);
          	enabled = false;
        };

        this.disable = function() {
            if (enabled == false) {
            	return;
            }
            workspace.removeEventListener('drag', onDrag, false);
            workspace.removeEventListener('drop', onDrop, false);
            workspace.removeEventListener('dragstart', onDragstart, false);
            workspace.removeEventListener('dragend', onDragend, false);
            workspace.removeEventListener('dragover', onDragover, false);
            workspace.removeEventListener('dragenter', onDragenter, false);
            workspace.removeEventListener('dragleave', onDragleave, false);
            enabled = true;	
        };
    }

  </script>
</head>
<body>
  <style>

    .list > * + * {
        margin: 10px 0 0 0;
    }

    .draggable {
        width: 200px;
        height: 20px;
        text-align: center;
    }

    .draggable.default {
        background: white;
        opacity: 1.0;
    }

    .draggable.active {
        background: orange;
        opacity: 0.5;
    }

    .dropzone {
        padding: 10px;
        background: #fbea68;
        width: 200px;
        height: 20px;
    }

    .dropzone.default {
        border: 3px solid #FFFFFF;
    }

    .dropzone.active {
        border: 3px dotted #c5b858;
    }

  </style>
  
  <div style="display: flex">
    
    <div class="workspace list">
      <div class="item dropzone">
        <div class="item draggable">
          Drag me down!
        </div>
      </div>
      <div class="item dropzone"></div>
      <div class="item dropzone"></div>
      <div class="item dropzone"></div>
    </div>

    <div class="workspace list">
      <div class="item dropzone">
        <div class="item draggable">
          Drag me down!
        </div>
      </div>
      <div class="item dropzone"></div>
      <div class="item dropzone"></div>
      <div class="item dropzone"></div>
    </div>

  </div>

  <script>

    // Usage example:

    /*
    	var workspace = document.querySelector('.workspace');

    	var dragger = new Dragger(workspace);

        dragger.addDropzone(workspace.querySelector('.dropzone-1')); // place to put item
        dragger.addDropzone(workspace.querySelector('.dropzone-2')); // place to put item
        dragger.addDropzone(workspace.querySelector('.dropzone-3')); // place to put item
        dragger.addDropzone(workspace.querySelector('.dropzone-4')); // place to put item
        
		dragger.addDraggable(workspace.querySelector('.draggable-1')); // draggable item
        dragger.addDraggable(workspace.querySelector('.draggable-2')); // draggable item

      	dragger.enable();
    */

    //NOTE: Below code lets' to enable items dragging on all detected workspaces.

    function prepareDropzones(dragger, workspace) {
    	var dropzones = workspace.querySelectorAll('.dropzone');
      	for (var j = 0; j < dropzones.length; ++j) {
            dragger.addDropzone(dropzones[j]);
        }
    }
    
    function prepareDraggables(dragger, workspace) {
        var draggables = workspace.querySelectorAll('.draggable');
		for (var j = 0; j < draggables.length; ++j) {
            dragger.addDraggable(draggables[j]);
        }
    }
    
    function prepareWorkspace(workspace) {
    	var dragger = new Dragger(workspace);
		prepareDropzones(dragger, workspace);
      	prepareDraggables(dragger, workspace);
      	dragger.enable();
    }
    
    function prepareWorkspaces() {
        var workspaces = document.querySelectorAll('.workspace');
        for (var i = 0; i < workspaces.length; ++i) {
            prepareWorkspace(workspaces[i])
        }
    }
    
    prepareWorkspaces();

  </script>
</body>
</html>
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join