Introducing MooModel: A Javascript Framework

Posted by anup.narkhede on September 05, 2010

Introduction

MooModel is a javascript framework built on top of mootools, to simplify the use of objects and classes in javascript. It comes with an elegant syntax and built in support for object oriented features. Additionally it provides observable attributes, ActiveModel like validations and a REST persistence adapter.

MooModel makes use of the powerful object oriented features provided by mootools. With the latest introduction of server side mootools, it is possible to use same javascript on your browser and server. The current version of MooModel (0.0.1) is not CommonJS compliant and does not support server side mootools either. However, I am working to release a server edition soon. Follow this article to know more about using mootools as server side javascript.

Getting Started

To define a class:

To create new instances of Person class:

Attribute values can be accessed using getter and setter functions:

The Base class provides a collection array to store instances and they can be added as:

The collection belongs to the page context when used in a browser. Records can be fetched by using the finders as:

  • Person.find(id)
  • Person.all()
  • Person.first()

Custom Methods

Instance methods and class methods can be defined as shown below:

  • foo.speak() => instance method invoked!
  • Person.custom_finder() => class method invoked!

Inheritance

Mootools uses Javascript’s native prototype inheritance model. MooModel uses this built in support to give you access to all instance and class methods from a subclass.

  • Employee.custom_finder() => class method invoked!
  • bob.speak() => instance method invoked!

Class Mixin

Implements is a mootools class mutator, used to include properties from one or more classes without inheritance. It is useful while implementing a default set of properties in multiple classes.

  • person.can_login() => true

Events

MooModel uses ObservableHash internally to store attributes. This brings all coolness of attaching functions to attribute change events. Check the examples below:

Initialize

Observe set event on ‘name’ attribute:

  • person.set(’name’, ‘railsbob’) => Console: value changed to railsbob

Observe get event on ‘name’ attribute:

Observe erase event on ‘name’ attribute:

Observe add event on the class collection:

  • Person.add(new Post({id: 1, name: “bean”})) => Console: added bean

Observe remove event on the class collection:

  • Person.remove(person.get(’id’)) => Console: removed bean

Validations

MooModel provides a full validation framework. The following example shows an implementation of a custom validation, defined on an attribute with a regex matcher.

  • person = new Person({id: 1, employeeNumber: ‘12345′ })
  • person.valid() => true
  • person.set(’employeeNumber’, ‘123ASDF’)
  • person.valid() => false
  • person.errors() => ['employeeNunber', 'should be a 5 digit number']
  • person.errors.on(’employeeNumber’) => ['should be a 5 digit number']

MooModel provides a set of standard validation rules, as listed below:

Presence

Length

Options:

  • minimum: Number
  • maximum: Number
  • within: [0, n] (Array)

Numericality

Exclusion

Inclusion

Within a given range

These tests provide more information on usage of these validation rules.

Dirty Attributes

MooModel provides ActiveModel like dirty attributes to track attribute changes.

  • person.has_changed() => false
  • person.set(’name’, ‘anup’)
  • person.has_changed() => true

Which attribute/s changed?

  • person.changed() => ["name"]

And what were the changes on ‘name’ attribute?

  • person.changes(”name”) => ["railsbob", "anup"]

To Reset an attribute and restore the previous value:

  • person.reset(”name”)
  • person.get(”name”) => railsbob
  • person.has_changed() => false
  • person.changed() => []

To reset all attributes:

  • person.reset()

Persistence

Currently MooModel supports REST persistence for client side use. MooModel uses ActiveSupport style inflections to define the routes. For ex: resource_name: ‘person’ corresponds to route /people/:id. A .save() call on an object fires an ajax json request to the route url. Refer rest persistence tests for more information.

  • person.resource_path() => ‘/people/10′
  • person.collection_path() => ‘/people’

The resolved route can be overridden by passing in a route option as follows:
Ex:

  • person.resource_path() => ‘/employees/10′
  • person.collection_path() => ‘/employees’
  • person.save() => posts attributes to the appropriate path using ajax

The project is hosted on Github. For any issues and suggestions, contact me at anup[dot]narkhede[at]gmail.com.

Next Steps

  • Make moo-model compliant with server side mootools
  • CommonJS compliance
  • MongoDB persistence adapter for use on server side
  • For updates on latest features, follow me on twitter.

    MooTools: Class Methods and Inheritance

    Posted by anup.narkhede on July 12, 2010

    In my last project, I enjoyed scripting using mootools and started exploring it more deeply. One of my extensive use was to define UI elements’ functionality in classes and then create multiple instances for re-usability.

    Mootools makes use of Javascript’s native prototype model for inheritance. To extend a base functionality into sub class, mootools provide ‘Extends’ method. However, if you have class methods in your base model, Extends is insufficient to get them into the sub classes. After some research, I managed to solve this by using Class Mutators and overriding the Mootools ‘Extends’ to take care of class methods inheritance.

    First of all, we need to define a ClassMethods mutator. Mutators belong to a class, not to their instances and they are called only when we define a new Class.

    Next, we need to redefine Mootools Extends mutator:

    Check out the example below:

    You can see the above code working here.
    http://jsfiddle.net/rZvJE/11/