Posted December 20, 2011 at 9:37 AM by Ben Nadel
Here's the non-trivial, yet small-in-scope practice problem I started working on. I thought it would be a good place to start; perhaps I was completely misguided:
| || || |
| || |
| || || |
I put the code up on GitHub so you could see what I was doing.
If you think you have the right advice to give me, shoot me an email: email@example.com. This is for-pay, so please let me know what your hourly consulting rate is, as well.
I want to understand this stuff so freakin' bad I can taste it! :D
UPDATE: December 22, 2011
After exchanging a few emails with Addy Osmani, I started to think through the event-driven communication a bit better. In this application, there are two view controllers: Agent and Bucket. The communication and interaction between these two elements is facilitated by a top-level controller, DragDrop:
- Agent announces dragStarted event.
- Controller tells all Buckets to start tracking said Agent so that they can tell when the Agent has hovered over or has been dropped on them, respectively.
- Buckets listen to "moved" event on given Agent.
- As Agent moves, Bucket determines if Agent is over drop-zone. If so, the drop-zone is activated.
- Bucket listens to "dragEnded" event.
- If Agent is over drop-zone when dragEnded event is fired, Bucket announces a "dropped" event.
- Controller responds to "dropped" event by telling said Bucket to take ownership (pushItem) of said agent.
Once an Agent becomes part of a given Bucket, the Bucket listens for reasons to remove the Agent.
- Bucket listens for dragStarted event.
- Bucket announces a "popped" event.
- Controller listens for popped event and tells given Bucket to release (popItem) the given Agent.
- Controller re-attaches agent to primary container.
If you want to see this in action, try my online demo here.
Right now, this does basically what I had envisioned. Other than that, though, I make no promise about the code (which can be seen on GitHub).
| || || |
| || |
| || || |
As always, I'm looking for feedback. I'd be more than happy to pay for a Code Review / analysis if you think you have some good insights and advice to offer. Please feel free to shoot me an email.
UPDATE: December 23, 2011
Today, I wanted to try and add a second Bucket to the application surface. I didn't think this would add much complexity as the Buckets are fairly modular and the top level DragDrop controller already has a sense of a Bucket "collection." What I did have to do, however, was add a way for the DragDrop controller to set the position of the bucket when it gets attached to the rendered container. To accomplish this, I simply added a "position" argument to the attachContainer() method:
- Bucket.attachContainer( container, initialPosition )
For sake of simplicity, the initialPosition object just gets passed directly to the css() method of the root DOM (Document Object Model) node. This means that the calling object (DragDrop controller) needs to explicitly define the top/right/bottom/left CSS properties.
Also, in response to Randall's comment below, I added an "ingredients" widget to each bucket that will list out the labels of the contained agents that have been dropped over the dropzone. Since I was already keeping references to the controllers, all I needed to do was add a getLabel() method to the agent.
Making these changes to the code was actually quite simple. I guess this is one of the benefits of modular code - the focused responsibility of each module makes the code easier to maintain and extend.
| || || |
| || |
| || || |
- Wanted: Full-Time ColdFusion Developer at Intoria Internet Architects
- Cold Fusion Senior Developer at Edge Information Management
- Back-End Web Developer-Information Technologist at Michigan State University
- ColdFusion Developer at Nonfat Media
- Mid-to-Senior Level Web Application Developer at SiteVision, Inc.
PS - love the site!
It was dark when I woke. This is a ray of sunihsne.
The drag and drop functionality is just incidental to the context in which I was trying to learn modularity. Under the hood, the code is still [trying] to be modular with communication all done via event systems and method invocation. If you look at the GitHub project, you'll see that the agent (square) and the bucket are being controlled by view modules. I'm currently working on creating a controller module to coordinate the communication between the two view instances (of which there may end up being N-instances).
Thanks for the kind words! I try to keep the site updated with new concepts and thought experiments :)
Ha ha, thanks :)
Dude, I wish I could help you as much as you have helped everyone else. But I am glad you found your help. Good luck!!!
(after 22 Dec update) Wow! PERFECT timing. I am dazzled by JQ's drag/drop and definitely want to use this in my code.
(Your demo) I drag-n'-dropped items 1, 2, 3, and 4 into the box. Then I dragged three and four back out. I then dragged #5 back in (thus the counter states "3").
Now what I need to see is upon a "submit", I want to know that #1, 2, and 5 are inside the drop zone. Have you made it that far yet? Or, what do I poll in order for the response to be, "1, 2, & 5"? Additionally, can I also know that 3, 4, and 6 are outside the drop zone?
I have updated the code / demo / post today to incorporate the concept of "ingredients". I couldn't think of a better word :) Basically, when you drag an agent onto the bucket, it now lists out the contained labels in addition to the simple count.
Starting with a Gateway object to interface between local code and a remote ColdFusion persistence store.
Just wanted you to know I have added you to my bookmarks. I've seen your other blog topics too and I can say you've got great ideas. Keep it up!