Goper Leo Zosa
Goper Leo Zosa

Reputation: 1283

How to change elements being copied on dragging using Dragula JS Plugin

I have a page which is similar to page builder template editor. Im using Dragula.JS as a plugin for drag and drop and used their method copy to copy elements from other container. This is what it looks like: enter image description here

The problem is when I drag from right side columns and put in the left box elements are copied exactly what it is on the right columns. This is my code:

<div id="2col" class="collapse column-choices">
 <a href="#" class="list-group-item">
        <div class="row">
          <div class="layoutBorder one-half"></div>
          <div class="layoutBorder one-half"></div>
        </div>
      </a>
      <a href="#" class="list-group-item">
        <div class="row">
          <div class="one-four layoutBorder"></div>
          <div class="three-four layoutBorder"></div>
        </div>
      </a>
      <a href="#" class="list-group-item">
        <div class="row">
          <div class="three-four layoutBorder"></div>
          <div class="one-four layoutBorder"></div>
        </div>
      </a>
    </div>

and my JS:

 //  the `templateContainer is the right box container`
 dragula([document.getElementById('2col'), document.getElementById('templateContainer')], {
copy: true,
   });

When I drag things to left box container this code will be put on:

<a href="#" class="list-group-item">
        <div class="row">
          <div class="layoutBorder one-half"></div>
          <div class="layoutBorder one-half"></div>
        </div>
      </a>

That is not I want. Question is How to copy elements from right container and when put to left box container elements are going to changed this my aim. I will change elements to:

<div class="element-to-paste">
      This thing will be copy on the left box. From Right.
    </div>

Please point me on other drag and drop plugin that can make my objective.

Upvotes: 1

Views: 6759

Answers (1)

Graham T
Graham T

Reputation: 966

The way to do what your asking is to utilize the .drop Dragula callback.

.on("drop", function(el, container, source) {}

https://github.com/bevacqua/dragula#drakeon-events

I've built one app where the 'drop zone' only had one column, so all elements would be lined-up vertically.. Similar to a sortable list. I used Angular for my project and my whole drop-zone used an ng-repeat directive, which is just a way to loop through an array of data. For an example it could be:

var data = [
{
  index: 1,
  type: 'image',
  data: 'image.jpg'
},
{ 
  index: 2,
  type: 'textblock',
  data: 'lorem ipsum, blah blah'
}]

Then in your ng-repeat directive you can read the type property, and put in some HTML for it, like

<div ng-if="mydata.type='image'">
  <img src='{{ mydata.data}}'>
</div>

<div ng-if="mydata.type='text'">
  <p>{{ mydata.data }}</p>
</div>

To get the correct order for your elements, you could use the ng-orderBy directive using the object's index.

This way the dropping action is a facade. You actually remove the dragged element from the DOM and replace it with a new one.

Dragula appends a .gu-transit class to elements while they're being dragged, so within your .drop callback you can loop through the DOM elements in your drop-container, find the .gu-transit, then you know the index that it's at, and can assign it a correct index property when you push it into your data array.

I'm using Angular as an example because that's what I used, and I think using it or another framework substantially helped implement this functionality. I think it'd be a lot more difficult to do with straight jQuery.

Upvotes: 3

Related Questions