section ActiveView section

Description

DOM based view programming in pure JavaScript.

ActiveView classes are created with ActiveView.create. The first argument is a function that will receive ActiveView.Builder and ActiveSupport.Element as it's arguments. This function is where the DOM nodes of your view are constructed, it must return a DOM node. Each instance of an ActiveView class takes an optional hash of parameters as the only argument to the constructor. These parameters are accessible via get and set instance methods. The DOM node the constructor returns is accessible with the getElement instance method.

MyViewClass = ActiveView.create(function(builder,dom){
  return builder.p(this.get('text'));
});
 var my_view_instance = new MyViewClass({text: 'test'});
document.body.appendChild(my_view_instance.getElement());

The second argument to the create method is an optional hash of instance methods.

MyViewClass = ActiveView.create(function(builder,dom){
  return this.generateElement();
},{
  generateElement: function(){
    var builder = ActiveView.Builder;
    return builder.p();
  }
});

Builder

All DOM nodes in ActiveView are generated by the builder library. Builder methods (tr, br, ul, li, etc) return Element objects. Builder methods accept a variable number of arguments in any order. The design of the library is meant to mimic the feel of declarative HTML as closely as possible.

builder.ul(
  builder.li(
    builder.p('Paragraph Text')
  )
)
 builder.table({cellpadding:0,cellspacing:0},
  builder.tbody(
    builder.tr(
      builder.td(
        'Cell Contents',
      ),
      this.methodReturningAnotherTableCell()
    )
  )
)

You can make inline assignments to local variables or object properties in order to create more compact and readable code.

var link_two;
var element = builder.p(
  this.linkOne = builder.a(),
  link_two = builder.a()
);
dom.observe(link_two,'click',function(event,stop){});

See ActiveView.Builder.tag for more usage possibilities.

DOM Library

The ActiveSupport.Element object is passed in as the second argument to the constructor. It does not extend built in objects (notably Element and Event), so it is more verbose than a proper Ajax library such as jQuery or Prototype. ActiveJS is framework agnostic and thus can be used with any other Ajax library.

Singletons

Since most structural elements of your appliction will only appear once most ActiveView classes should be used as singletons. In addition, any ActiveRoutes route must point to an instance of a view, not the view class.

To use a view as a singleton:

var instance = MyView.getInstance();

With ActiveRoutes:

ActiveRoutes.setRoutes({
  '/articles/:id': [ArticlesView.getInstance(),'show']
});

Events

All ActiveView classes and instances are extended by ActiveEvent and thus have notify and observe methods. Good application design with ActiveView usually involves having your views create events that other views observe:

FormView = ActiveView.create(function(builder,dom){
  var element = builder.form();
  dom.observe(element,'submit',function(event,stop){
    this.notify('saved');
    stop();
  },this);
});
 LayoutView = ActiveView.create(function(builder,dom){
  var form_instance = new FormView();
  form_instance.observe('saved',function(){
   });
  return builder.div(form_instance.getElement());
});

"attached" Event

Each view has an "attached" event which is called when the view becomes part of the document's DOM tree.

MyView = ActiveView.create(function(builder,dom){
  return builder.p();
});
MyView.observe('attached',function(){});
document.body.appendChild((new MyView()).getElement());
//attached observer called

Aspects

View aspects are similar to subclasses, but have no super functionality.

ArticleView = ActiveView.create(function(builder,dom){
  return builder.div(
    builder.h2(this.get('title')),
    builder.p(this.get('body')),
  );
});
 AdminArticleView = ActiveView.create(ArticleView,function(element,builder,dom){
  dom.insert(element,builder.a({href:'#'},'Edit'));
  dom.insert(element,builder.a({href:'#'},'Delete'));
  return element;
});

In the example above, when an AdminArticleView is created, the ArticleView nodes will be created first, the outer element being passed to the child as the first argument.

All events that the parent class creates will cascade to the child class.

Aliasing

It's useful in your instance methods to refer to the Builder and DOM libraries by in shorthand. Using the same variable names as the conrstuctor also makes it easier to refactor your code from the constructor into instance methods.

var builder = ActiveView.Builder;
var dom = ActiveSupport.Element;

Utilities

Namespaces