How would you organize this Javascript?

Posted by Anurag on Stack Overflow See other posts from Stack Overflow or by Anurag
Published on 2010-03-18T08:19:52Z Indexed on 2010/03/18 8:51 UTC
Read the original article Hit count: 382

How do you usually organize complex web applications that are extremely rich on the client side. I have created a contrived example to indicate the kind of mess it's easy to get into if things are not managed well for big apps. Feel free to modify/extend this example as you wish - http://jsfiddle.net/NHyLC/1/

The example basically mirrors part of the comment posting on SO, and follows the following rules:

  1. Must have 15 characters minimum, after multiple spaces are trimmed out to one.
  2. If Add Comment is clicked, but the size is less than 15 after removing multiple spaces, then show a popup with the error.
  3. Indicate amount of characters remaining and summarize with color coding. Gray indicates a small comment, brown indicates a medium comment, orange a large comment, and red a comment overflow.
  4. One comment can only be submitted every 15 seconds. If comment is submitted too soon, show a popup with appropriate error message.

A couple of issues I noticed with this example.

  • This should ideally be a widget or some sort of packaged functionality.
  • Things like a comment per 15 seconds, and minimum 15 character comment belong to some application wide policies rather than being embedded inside each widget.
  • Too many hard-coded values.
  • No code organization. Model, Views, Controllers are all bundled together. Not that MVC is the only approach for organizing rich client side web applications, but there is none in this example.

How would you go about cleaning this up? Applying a little MVC/MVP along the way?

Here's some of the relevant functions, but it will make more sense if you saw the entire code on jsfiddle:

/**
 * Handle comment change.
 * Update character count. 
 * Indicate progress
 */
function handleCommentUpdate(comment) {
    var status = $('.comment-status');

    status.text(getStatusText(comment));
    status.removeClass('mild spicy hot sizzling');
    status.addClass(getStatusClass(comment));
}

/**
 * Is the comment valid for submission
 */
function commentSubmittable(comment) {
    var notTooSoon = !isTooSoon();
    var notEmpty = !isEmpty(comment);
    var hasEnoughCharacters = !isTooShort(comment);

    return notTooSoon && notEmpty && hasEnoughCharacters;
}

// submit comment
$('.add-comment').click(function() {
    var comment = $('.comment-box').val();

    // submit comment, fake ajax call
    if(commentSubmittable(comment)) {
        .. 
    }

    // show a popup if comment is mostly spaces
    if(isTooShort(comment)) {
        if(comment.length < 15) {
            // blink status message
        }
        else {
           popup("Comment must be at least 15 characters in length.");
        }
    }
    // show a popup is comment submitted too soon
    else if(isTooSoon()) {
        popup("Only 1 comment allowed per 15 seconds.");
    }

});

© Stack Overflow or respective owner

Related posts about best-practices

Related posts about web-applications