The Legend Begins
On a recent project, I needed to wire up drag-and-drop functionality. I had some things in a list, and I needed to be able to sort them using the mouse. Not only did I need to drag things around inside of a list, I needed to drag things from one list of things, to another list of similar things. Typical drag’n’drop stuff.
So I spent some time looking for a community project that gave me the desired functionality.
From the looks of it, the defacto drag’n’drop bits all revolve around jQuery UI. My project doesn’t currently have a dependency on jQuery UI, so I really didn’t want to go that route. However, I also decided that if it was the best route, then I would add jQuery UI to our project.
My Quest: Find the Best Dragon
The word “Best” is a loaded word. Given different contexts, two different options could alternately become the best option. My decision of which library is the best would be based on: Does this library allow me to build the best possible experience for my users?
As the search continued, my buddy Trevor and I stumbled into a little gem, built by none other than the benevolent Brian T. Ford. My boy Brian has a github repo called Dragon Drop. My initial impression was that it may be too simple for my needs. And I almost walked away from it. But then I took another look at it, and really fell in love with it.
The following are reasons that Dragon Drop. Seemed like a great choice.
- No jQuery UI dependency.
- The library is extremely easy to read, which meant that adding to or modding the it would be easy.
- It embraces AngularJS’s API.
I downloaded it, added it to my project and immediately had drag’n’drop functionality, without some crazy, sick overhead. It was beautiful.
Train the Dragon
The easiest way to explain why Dragon Drop is such an awesome solution is: It is an awesome place to start. I was able to quickly make some changes to his code, and have it work exactly like I needed it to.
After an hour of working on it, I had a pretty amazing drag’n’drop bit going. I had made numerous changes to Brian’s project, and some of them made great sense. I would have felt really bad if I didn’t at least offer to submit a pull request with some of my changes. However, I didn’t want to force my changes onto Brian, so I chatted him on G+ prior to submiting the PR.
I asked him if he wanted to take his repo to the next level or keep it simple, as it was. He quickly replied, but differently than I thought he might. He mentioned that he had thought a bit about what Dragon should turn into, or if it should altogether stay the same. While he wasn’t certain of the direction of Dragon, he wanted to at least see the PR (I still need to submit it).
After thinking about it for a few days, I think that Dragon should stay as it is today, which is A Great Place To Start. It doesn’t include all of the features that you will need, but it doesn’t bombard you with functionality that you will never use either. If you need to add a feature, the library is only a few hundred lines long, so you can just add it.
Before mentioning some of the changes that I made, let me mention some of the reasons I like Dragon:
- It is simple to use, as it extends the functionality of the
- By default it allowed me to drag from on list to another.
- No external dependencies. Just AngularJS and jQuery.
- Literally, all you have to do it add it to your project and it just works.
Now let me list some of the changes that I made to Dragon, each if which was very simple to do:
- By default, Dragon removes the item you are dragging from it’s source list as soon as you click it to start dragging. I didn’t want it to remove the item from the source list until I dropped it onto a new list. This change was very easy to make (even if the new list was the same list).
- By default, dropping the item places it at the bottom of the list. It doesn’t respect the order that you dropped it in. I changed it to respect the drop order. If you drop an item on top of the item that is second on the list, your item will become the second item on the list, and everything else will shift down.
- By default, Dragon started firing the
Dragmethod as soon as you initially clicked the item on the DOM. This ruined the ability to click the item without dragging it. So, I made the drag stuff not happen on the mousedown event. You have to move the mouse one pixel before it will start the drag process. So, now I can have ngClicks on items in a Dragon list.
- By default, Dragon doesn’t have an onDrop event callback to notify you of a
dropevent. I added an onDrop callback so that I don’t have to
$watchfor changes. I can simply subscribe via a callback.
- No, I didn’t not remove the comment Dragon. As mentioned in the comments, he is very important to the library.
- The item that is beig dragged loses some of it’s styling from the parent. To minimize this, I made the Dragon respect the aspect of the original item.
- Dragon didn’t allow me to use a filter on my list. Using a filter would ruin the drop functionality. I modded it to allow for filters to be used in the
There are a few additional reasons. The more important thing is that you understand how easy it was for me, a non-guru, to make these changes. I actually enjoyed making them. Reading through Brian’s code was a cool experience as well. It is brilliant! I have never seen angular used like he uses it, and I loved it. I feel like a better dev because of it.
Prereqs to learning how to use Dragon are understanding
ng-repeat. Once you understand that, you are there.
Once you have downloaded and added the Dragon to your project, you merely do the following in you markup:
1 2 3 4 5
This will give you a list of things. Each of the things may be dragged around.
If you dat]re to make two lists, you can drag from one to the next, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
As you drag a thing, it follows your mouse, as you would expect. By dropping a thing from
setTwo, the thing in the array will be removed from
setOne and added to
setTwo, and the DOM will subsequently reflect that change in the model. It is all very genius, and very simple.
If you don’t believe me, go check it out here.
Special thanks to Brian. Make sure and tweet him if you agree that he is completely legit for sharing his art with us.