An open-source JavaScript framework for developing web applications.
JavaScript
MVC

home > mvc | learn more | documentation | benefits | forum | google code


Demos

Comment IT - Instantly provide comments for any webpage.

Traffik - Google Maps and Calendar mashup featured in Google Code and Ajaxian.

Note IT - Simple note and todo organizer.


License

JavaScript MVC is liscensed under the Apache Public License.

Model View Controller.

JavaScript MVC is designed to help developers build web applications efficiently. This is done by enforcing a Model-View-Controller (MVC) design pattern. The MVC design pattern organizes code by separating it into logical layers. This has several benefits:

The remainder of this page provides source examples from Comment IT.


Model

The model is the domain-specific representation of the information on which the application operates. It wraps your services and makes sense of their data. Through introspection, JavaScript MVC adds a lot of functionality to your models. But you can easily add your own.

Example

The following is an example of a Jester model. By default, Jester models connect to REST XML services. Besides declaring the model, we add two instance functions. created_ago() returns a string describing how long ago a comment was created. action_view() returns a random verb. This will be useful in the view.

Resource.model("Comment",{
  created_ago: function(){
    var now = new Date()
    var seconds = ( now - this.created_at) / 1000
    var min = parseInt(seconds/ 60)
    var hours   = parseInt(seconds/ (60*60))
    var days    = parseInt(seconds /(60*60*24))
    var mon  = parseInt(days / 30)
    var years   = parseInt(days / 365)
  
    if(seconds < 30) return 'seconds ago'
    if(minutes < 1)  return 'less than a minute ago'
    if(min < 60 )    return min.toString()+' miniutes ago'
    if(hours < 24  ) return hours.toString() + ' hours ago'
    if(days < 30)    return days.toString() + ' days ago'
    if(mon < 12)     return mon.toString() + ' months ago'
    return years.toString()+' years ago'
  },
  action_verb: function(){
    var verbs = ['said', 'announced', 'articulated',
                 'related','voiced','penned', 'noted',
                 'wrote','scrawled','declared']
    return verbs[parseInt(Math.random()*verbs.length)]
  }
)

Jester, as well as JMVC.ActiveRecord, support a syntax like Rails' own ActiveRecord. For example, you can call:

var comments = Comment.find('all');
var comment = Comment.new_instance({text: 'Hello World'});
comment.update({title: "I am not original."})
comment.save();

In the case of Jester, these requests get mapped directly to your REST services. For example, Comment.find('all') makes a request to /comments.xml.

Controller

A controller processes and responds to page requests. Typically, it uses the models to gather and process data and directs that data to the appropriate view for rendering.

To send data to a view, the data simply needs to be add as a controller instance variable (this.attribute = data).

Example

The following is an example of asynchronous actions loading and displaying comments.

CommentController  = Class.create(JMVC.Controller, {
  prepare_list: function(params){
    Comment.find('all', {}, 
      this.continue_to({put_first_argument_in: 'comments'}));
  },
  list: function(params){
    this.comment = new Comment({email: '', 
                                name: '',
                                website: ''})
  }
})

If the user navigated to the url #comment/prepare_list the following would take place:

  1. A new CommentController instance would be created.
  2. prepare_list would be called with {action_name: 'prepare_list', controller_name 'comment'} as the parameters.
  3. An asyncronous request would be made to http://yourdomain.com/comments
  4. When the request returns, it will place the comments in the CommentController instance attribute named 'comments'. It will then call list on the CommentController instance.
  5. In list, a new comment will be a created, but not saved to the database. This is used to display a form for a new comment.
  6. Finally, the template app/views/comment/list.jst is automatically rendered to the page.

View

A view renders data into a form suitable for interaction, typically a user interface element. We use eJS templates that work just like ERB templates in ruby.

JavaScript between <% %> is executed, and the result of JavaScript between <%= %> is written to the page.

Example

The following view template shows a list of comments. It also includes a template that creates a new comment form.

<h4>Comments</h4>
<% comments.each(function(comment){ %>
  <div class='bubble'>
    <blockquote>
      <%=comment.comment%>
    </blockquote>
    <cite>
      <span>
        <a href='<%=comment.website%>'>
          <%=comment.name%>
        </a>
      </span>
      <strong>
        <%=comment.action_verb()%>
      </strong>
      <%=comment.created_ago()%>
    </cite>
  </div>
<%})%>
<div id='commentit_new_comment'>
  <%= render({partial: 'create'}) %>
</div>

Summary

This code was taken from Comment IT. You just learned 90% of the code in Comment IT. Congrats!

Thanks to TrimQuery, Ejs, Real Simple History, Prototype, and Jester.

Questions/Comments? 847-247-0530

  Grabbing code by the 00's