Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Codementor Plunker AngularJS Office Hours - Making things draggable in plunker

101,032 views

Published on

https://www.codementor.io/officehours/2913050604/angular-plunker

Geoff Goodman is the creator of Plunker, which is an entirely Angular-built way to support...you guessed it, Angular projects! The real-time previews and strong sense of feedback has made Plunker a very popular online community for creating, collaborating on and sharing web development ideas.

We'll be sitting down with Geoff to discuss the thought process and design decisions involved in building a low-level angular drag-and-drop library for Plunker.

Published in: Technology
  • Be the first to comment

Codementor Plunker AngularJS Office Hours - Making things draggable in plunker

  1. 1. Making stuff draggable in Plunker (and other places) Creating a drag and drop directive for Angular.js CodeMentor – 9 March 2015 Geoff Goodman (@filearts)
  2. 2. Who is this guy? Hi, I’m Geoff Goodman Twitter: @filearts Github: @ggoodman During the day, I value businesses at EY (Ernst & Young) At night, I build Plunker which is an in-browser editor for front-end code.
  3. 3. • Like I said, Plunker is an in-browser code editor • A code editor is only half done if you can’t drag things around…
  4. 4. FAIL
  5. 5. Prior art • https://github.com/codef0rmer/angular- dragdrop - Wraps jQuery UI • https://github.com/a5hik/ng-sortable - Comprehensive, dependency-free list reordering and transferral • https://github.com/logicbomb/lvlDragDrop - Also low-level, dependency-free drag and drop based on html5 api
  6. 6. Figuring out what I needed • I know that I have things that I want to drag • I know that there are only certain places to drop stuff • I know that only certain things can be dropped in certain places
  7. 7. Making this in Angular.js • Angular lets me define how I want certain things to behave straight in the markup – These are called directives – They are not the easiest thing to learn and understand – But they are crazy powerful • HTML5 also defines a great API for drag and drop (Spec)
  8. 8. Overcome API limitations • The drag and drop pioneer is now a black sheep • IE only allows Text and URL as the data types • Using our own layer on top, we can support any data
  9. 9. Angular internals • Three directives: 1. drag-container 2. drop-container 3. drop-area • And one service to share drag state between the directives: $dragging.
  10. 10. What I came up with: <div drag-container="model" mime-type="text/whatever"> <!-- Container that is draggable --> </div> <div drop-container accepts="['text/x-plunker-file']"> <div drop-target="left" on-drop=“dropL(data)"></div> <div drop-target="right" on-drop=“dropR(data)"></div> <!-- You can put any markup here --> </div>
  11. 11. drag-container • Determines the data being dragged (drag- container attribute) and the type of that data (mime-type attribute) • Call preventDefault() on the dragstart event and the browser will start dragging! In the event handler, I set the drag data. <div drag-container="model" mime-type="text/whatever"> <!-- Container that is draggable --> </div>
  12. 12. drop-container • Defines a region that will accept any drop that passes the ‘accept’ test. • Accepts event handlers, figures out appropriate target and delegates event. <div drop-container accepts="['text/x-plunker-file']"> <div drop-target="left" on-drop=“dropL(data)"></div> <div drop-target="right" on-drop=“dropR(data)"></div> <!-- You can put any markup here --> </div>
  13. 13. Delegating to targets • Create a virtual point for each target • Calculate minimum distance b/w mouse and point top top-right right bottom-rightbottombottom-left left top-left center
  14. 14. drop-target • Defines a potential region of the drop- container that can respond to drag and drop events • Can by styled by css to give drop hints <div drop-container accepts="['text/x-plunker-file']"> <div drop-target="left" on-drop=“dropL(data)"></div> <div drop-target="right" on-drop=“dropR(data)"></div> <!-- You can put any markup here --> </div>
  15. 15. Linking the directives up • drop-targets require an instance of a drop-container in their DDO: .directive("dropTarget", ["$parse", function ($parse) { return { restrict: "A", require: ["^dropContainer", "dropTarget"], controller: "DropTargetController", controllerAs: "dropTarget", link: function ($scope, $element, $attrs, ctrls) { var dropContainer = ctrls[0]; var dropTarget = ctrls[1]; var anchor = $attrs.dropTarget || "center"; dropContainer.addDropTarget(anchor, dropTarget);
  16. 16. drop-targets are just attachment points • They are not designed to have content • When active, an -active css class is added so that they can: e.g. be shown or given dashed borders • Creating them gives you regions of the drop- container that can respond to events that relate only to that region
  17. 17. Event handling • HTML5 gives us a bunch of events. I chose a few to expose: – on-drag-start, on-drag-end – on-drag-enter, on-drag-leave – on-drag-over – on-drop • Angular can inject special objects exposed to those handlers, like $event and data <div drop-container accepts="['text/x-dragular-piece']" on-drag-enter="game.swap($index, data)">
  18. 18. What this let’s you do • Trello-style storyboards lists: DEMO • Re-orderable lists by: – Having a leading and trailing drop-target for each list item – Splicing before or after the target element on- drag-enter • Sliding puzzle: DEMO • More complex behaviours: DEMO
  19. 19. Caveats • Determining if something is draggable must be synchronous • This means zip-building
  20. 20. But what about the code? • The code is MIT-licensed on github: https://github.com/ggoodman/angular-drag- drop • Feel free to ping me if you have questions on Twitter: @filearts or @plnkrco
  21. 21. One more thing… • With a hack here and some duct tape there… DEMO
  22. 22. THANKS FOR LISTENING!

×