DEV Community

Cover image for Draggable elements between two lists
angelina-white
angelina-white

Posted on

1 1

Draggable elements between two lists

This is for a basic dragging and dropping capability in between two set spots.

Helpful resources

This is the documentation for GSAP draggable, which is what I used. I also watched this Youtube tutorial by Wael Yasmina that was helpful in getting an idea for what you're able to do with this function.

Image description
I found this CodePen by Steve Wojcik and worked from there. I wanted to get familiar with the basics so I removed a lot of extra features that was in it like dropShadow, dragGroup, and highlight. I tested each section to see if it would effect the main drag and drop function, and if it didn't, I just removed it. This also helped get an idea for what different parts do.

Imports

I used these scripts:
//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/utils/Draggable.min.js
//cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js
//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js

HTML

<div id="container" class="container">
  <h1 id="list1">List 1</h1>
  <h1 id="list2">List 2</h1>

  <div id="dropArea"></div>
  <div id="dropArea2"></div>
  <div id="dropArea3"></div>

  <div class="first">
    <h3>1</h3>
  </div>
  <div class="second">
    <h3>2</h3>
  </div>
  <div class="third">
    <h3>3</h3>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode
  • container: the boundary

  • lists: just the titles and will not be used

  • drop areas: where the boxes will drop under list 2

  • first/second/third: the draggable boxes

CSS

.container
{
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 400px;
  height: 330px;
  border-radius: 3px;
  border-style: solid;
  border-color: #fed3c1;
  border-width: 2px;
}

#list1 {
  margin-left: 100px;
  position: relative;
  margin-top: 35px;
}

#list2 {
  margin-left: 230px;
  position: absolute;
  margin-top: -58px;
}

.first
{
  position: absolute;
  top: 0px;
  left: 0px;
  width: 50px;
  height: 50px;
  background-color: pink;
  top: 100px;
  left: 106px;
  text-align: center;
}

#dropArea
{
  position: absolute;
  top: 100px;
  left: 242px;
  width: 50px;
  height: 50px;
}

.second
{
  position: absolute;
  top: 0px;
  left: 0px;
  width: 50px;
  height: 50px;
  background-color: pink;
  top: 175px;
  left: 105px;
  text-align: center;
}

#dropArea2
{
  position: absolute;
  top: 175px;
  left: 242px;
  width: 50px;
  height: 50px;
}

.third
{
  position: absolute;
  top: 0px;
  left: 0px;
  width: 50px;
  height: 50px;
  background-color: pink;
  top: 250px;
  left: 105px;
  text-align: center;
}

#dropArea3
{
  position: absolute;
  top: 250px;
  left: 242px;
  width: 50px;
  height: 50px;
}
Enter fullscreen mode Exit fullscreen mode

I added background colors to everything while I was working with it so I could see exactly where everything was. I pretty much kept everything in the same place except when adding a new box, I made the start and finish lower.

Javascript

var dropArea = "#dropArea";
var overlapThreshold = "60%";

Draggable.create(".first", 
{
  bounds: "#container",
  onDrag: function(e) 
  {
      TweenLite.to(".first", 0.2, 
      {
        scaleX:1.10,
        scaleY:1.10
      });
  },
  onDragEnd: function(e) 
  {
    if (this.hitTest(dropArea, overlapThreshold)) 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 136,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    } 
    else 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 0,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    }
  }
});


var dropArea2 = "#dropArea2";
var overlapThreshold = "60%";

Draggable.create(".second", 
{
  bounds: "#container",
  onDrag: function(e) 
  {
      TweenLite.to(".second", 0.2, 
      {
        scaleX:1.10,
        scaleY:1.10
      });
  },
  onDragEnd: function(e) 
  {
    if (this.hitTest(dropArea2, overlapThreshold)) 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 136,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    } 
    else 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 0,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    }
  }
});


var dropArea3 = "#dropArea3";
var overlapThreshold = "60%";

Draggable.create(".third", 
{
  bounds: "#container",
  onDrag: function(e) 
  {
      TweenLite.to(".third", 0.2, 
      {
        scaleX:1.10,
        scaleY:1.10
      });
  },
  onDragEnd: function(e) 
  {
    if (this.hitTest(dropArea3, overlapThreshold)) 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 136,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    } 
    else 
    {
      TweenLite.to(this.target, 0.2, 
      {
        x: 0,
        y: 0,
        scaleX:1,
        scaleY:1
      });
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

This has the same code base three times, one for each box. I just changed the variable names to reflect where the box should land.

  • bound: this is where you put the container you want to keep your draggable item in
  • onDrag: when the box is being dragged, it will look slightly bigger
  • onDragEnd: If the box is placed in the dropArea, it will stay there, else, it will go back to its original position under List 1

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay