For Pay: I Need A Few Hours Consulting On Modular JavaScript Application Architecture

Posted December 20, 2011 at 9:37 AM by Ben Nadel

Tags: Javascript / DHTML

I love JavaScript! I love it. Only, my understanding of JavaScript architecture is a bit old-school. For the last few months, I've been trying hard to wrap my head around taking that understanding into the modern era with modular, decoupled, asynchronously loaded code. Since I've discovered RequireJS, I've been trying hard to think about decoupled modules and how they can be instantiated on the fly. Only, I still can't quite see how this stuff all comes together.

I'm looking to hire a modular JavaScript consultant for an hour or two just to talk to me about how the following code should be organized. We don't need to write any code, necessarily - I'm struggling at the conceptual and philosophical levels. I figure something like a screen-share (Skype, GotoMeeting, etc.) and a phone call will be a good start. Maybe some sketching. Maybe some light code.

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: ben@bennadel.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:

  1. Agent announces dragStarted event.
  2. 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.
  3. Buckets listen to "moved" event on given Agent.
  4. As Agent moves, Bucket determines if Agent is over drop-zone. If so, the drop-zone is activated.
  5. Bucket listens to "dragEnded" event.
  6. If Agent is over drop-zone when dragEnded event is fired, Bucket announces a "dropped" event.
  7. 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.

  1. Bucket listens for dragStarted event.
  2. Bucket announces a "popped" event.
  3. Controller listens for popped event and tells given Bucket to release (popItem) the given Agent.
  4. 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.


 
 
 

 
 
 
 
 

Meta to the code, I also added a Require.js build / optimization file to the project. Now, in the scripts directory, there is an app.build.js file that tells the Require.js optimizer (r.js) how to find and compile the named modules. Now, the live demo only loads a single JavaScript file, main-build.js. This file contains all of the JavaScript modules, including the inlined-text of the HTML templates.




Reader Comments

Pat
Dec 20, 2011 at 10:47 PM // reply »
1 Comments

Hi - is your desire to understand more about jQuery Drag n' Drop or about "modular javascript" in general? The video seems to be focused on drag\drop while the text of the blog post is focused on modular js. Just wondering.

PS - love the site!


Dec 21, 2011 at 2:25 AM // reply »
1 Comments

It was dark when I woke. This is a ray of sunihsne.


Dec 21, 2011 at 9:24 AM // reply »
11,238 Comments

@Pat,

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 :)

@Josey,

Ha ha, thanks :)


Dec 22, 2011 at 11:28 AM // reply »
369 Comments

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!!!


Dec 22, 2011 at 3:20 PM // reply »
158 Comments

(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?


Dec 23, 2011 at 10:46 AM // reply »
11,238 Comments

@Randall,

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.


Dec 23, 2011 at 10:47 AM // reply »
11,238 Comments

@All,

I've also added a Require.js build / optimization configuration which was kind of cool. The demo now only loads one JavaScript file.


Dec 30, 2011 at 3:58 PM // reply »
11,238 Comments

@All,

Trying to continue the exploration of modular JavaScript application development - adding some "Model" stuff:

http://www.bennadel.com/blog/2304-Experimenting-With-A-JavaScript-Gateway-To-A-Remote-ColdFusion-Persistence-API.htm

Starting with a Gateway object to interface between local code and a remote ColdFusion persistence store.


Jan 6, 2012 at 3:50 AM // reply »
1 Comments

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!


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools