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 »
10,743 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 »
347 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 »
154 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 »
10,743 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 »
10,743 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 »
10,743 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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 21, 2012 at 1:58 AM
Updated: Converting A ColdFusion Query To CSV Using QueryToCSV()
Hi Ben, why do you need to have so many double quotes when adding the field and field name to the row data? ----------------------------------------- <cfset LOCAL.RowData[ LOCAL.ColumnIndex ] = ... read »
AXL
May 21, 2012 at 1:24 AM
URL Rewriting And ColdFusion's WriteToBrowser Image Functionality (CFFileServlet)
@Mounir, Open your lower case URL Rewrite rule and add the following condition. Condition input: {REQUEST_URI} Check if input string: Does Not Match the Pattern Pattern: ^/CFFileServlet/_cf_ca ... read »
May 20, 2012 at 4:28 AM
Understanding The Complex And Circular Relationships Between Objects In JavaScript
@Will Vaughn I tried your javascript example but got this error:- foo.print is not a function ... read »
May 19, 2012 at 5:37 AM
A Graphical Explanation Of Javascript Closures In A jQuery Context
Thanks for this article, but I fear you missed an important point. If variables in the outer context change, these changes affect the inner anonymous functions as well. That means: if you change the ... read »
May 18, 2012 at 3:39 PM
Parsing CSV Data With An Input Stream And A Finite State Machine
Can you use file upload button with this? and read live? or does the file have to already be on the server saved? ... read »
May 18, 2012 at 1:06 AM
VIRGO (Aug. 23-Sept. 22): Dead On The Money!
A friend of mine and I were arguing about astrology and she told me that he believes in astrology. She hasn't provided me with any evidence that the belief makes any sense to me. She she been telling ... read »
May 17, 2012 at 11:32 PM
Using ColdFusion to Handle 404 Errors (Page Not Found) On Development Server
Very easy the configuration. I read a lot pages and I can't find the solution. I open the administrator and change this Administrator/server settings/Error Handlers/Missing Template Handler and p ... read »
May 17, 2012 at 3:13 PM
LOCAL Variables Scope Conflicts With ColdFusion Query of Queries
I never cease to be amazed that almost EVERY random CF issue I come across lands me on your site. Thank you for documenting your findings for the world. ... read »