Object Instantiation in AFrameJS – Now Simplified Even More

This is an update to Object Instantiation in AFrameJS – Now Simplified, which is an update to AFrameJS Tutorial – A Response to “Backbone.js Tutorial – by noob for noobs”. Object instantiation has gotten even simpler – again. Every “class” that is created using AFrame.Class or AFrame.extend and that has an init function will have a “create” function attached as a static class member. The attached create function will call AFrame.create with the class constructor. The advantage is less but more readable code.

The Old Way

// Instantiating a plain AFrame.AObject.
var instance = AFrame.create( AFrame.AObject );

The New Way

// A few less bytes, but way more readable.
var instance = AFrame.AObject.create();

Options can be passed along to the create function, as shown in the next example.

Fuller Example

A working example can be found at JSFiddle

// HTML used
<button id="submitButton">Submit Button</button>

=====

    // Create a button class listening for a click
var Button = AFrame.Class(AFrame.Display, {
    domevents: {
        click: function(event) {
            alert('button clicked');
        }
    }
});

var button = Button.create({
    target: '#submitButton'
});

The final example from Object Instantiation in AFrameJS – Now Simplified is shown here, updated for this change:

Reworking the “Add Friend” Example

A working example can be found on JSFiddle.

$( function() {

    // Instead of creating a model, create a SchemaConfig.
    // A Model in AFrame is an instance of data combined
    // with a Schema.  The schema config will be used when
    // creating the model.
    var friendSchemaConfig = {
        name: { type: 'text' }
    };

    // Our friends collection is an array.  Instead of binding
    // directly to an event on the collection, when creating
    // the list, we bind the list to the collection.
    // The ListPluginBindToCollection will take care of
    // updating of the list.
    var friendsCollection = AFrame.CollectionArray.create( {
        plugins: [ [ AFrame.CollectionPluginModel, {
             schema: friendSchemaConfig
        } ] ]
    } );

    // This is the friends list.  It is bound to the
    // friendsCollection, so any time a model is added or
    //  removed from the friends collection, the list will update.
    var friendsList = AFrame.List.create( {
        target: '#friendList',
        listElementFactory: function( model, index ) {
            return AFrame.DOM.createElement( 'li',
                model.get( 'name' ) );
        },
        plugins: [ [ AFrame.ListPluginBindToCollection, {
             collection: friendsCollection
        } ] ]
    } );

    // we insert into the friendsCollection once we
    // have a name.  The list will be updated automatically.
    $( '#add-friend' ).click( function( event ) {
           var friend_name = prompt("Who is your friend?");
           // A new model will be created when adding
           // to the friend collection.
           friendsCollection.insert( { name: friend_name } );
    } );
} );

Read Object Instantiation in AFrameJS – Now Simplified to see more examples of the various ways to create an object.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

Import Configuration Items into an Object in AFrameJS

Importing Configuration Items into an Object in AFrameJS just became a lot easier. One of the most repeated tasks when initializing objects (in the init function) is to import configuration items from the “config” parameter. Each class was responsible for importing the config items that it needed, leading to init functions that only had several lines dedicated to importing, then a call to the superclass’ import function.

The Old Way

var Class = AFrame.Class( AFrame.AObject, {
    init: function( config ) {
        this.imported = config.imported;
        this.alsoImported = config.alsoImported;

        Class.sc.init.call( this, config );
    },
    ...
} );

Kind of repetitive and silly, isn’t it?

The New Way

var Class = AFrame.Class( AFrame.AObject, {
    importconfig: [ 'imported', 'alsoImported' ],
    ...
} );

This works on classes even if they inherit from another class, the entire class chain will be checked for items to import.

So much cleaner, isn’t it?

A demo of this in action can be found at JSFiddle

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

Declarative Events in AFrameJS

This is an idea borrowed from backbone.js, I take no credit for it. One extremely common pattern in AFrameJS is to have two objects, one we’ll call the broadcaster, and the other the listener. The broadcaster is initiated, and then injected into the listener whenever the listener is created. The reason these are called the broadcaster and listener is because the broadcaster broadcasts an event, any event, we’ll call it “somethingHappened.” When “somethingHappened” is triggered, the listener needs to take some action, it listens for the message. Within AFrame, this all happens using Observables, more documentation can be found under ObservablesMixin. For a long time, the only way to bind events was programatically in an object’s bindEvents function, which is verbose.

Fortunately, if using AFrame’s class declaration system, events can be declared in the class definition, reducing a lot of the manual labor needed to do this. A little known feature of AFrame is that the prototype chain of every object can be walked, even in Internet Explorer. There are no language tricks used for this, but some housekeeping is needed, AFrame.Class provides this. Because we can walk the prototype chain, we can declare events for on the prototype of each class without problem, even in inherited class structures.

But enough, an example.

Declaring Event Listeners

// The Listener classes declaration. The broadcaster is injected
// in the configuration and imported. Two events are listened for from
// the broadcaster, event1 and event2. 

// The key in the key value pair signifies the event to listen for and the
// name of the object which will trigger the event.
// The value in the key value pair is either a function or a string, if a string,
// the string must be the name of a class function.

// event1 is handled by an inline handler.
// event2 is handled by a class member, the name of the handler is given.
var Listener = AFrame.Class( AFrame.AObject, {
    importconfig: [ 'broadcaster' ],
    events: {
         'event1 broadcaster': function() {
              alert( 'inline event handler used for event1' );
         },
         'event2 broadcaster': 'event2Handler'
    },
    event2Handler: function() {
        alert( 'class function handler used for event2' );
    }
} );

A working example can be found at JSFiddle.

Declaring DOM Event Handlers

This can be used to listen for DOM events as well. Instead of using the “events” key, use “domevents”

var Display = AFrame.Class(AFrame.Display, {
    importconfig: ['broadcaster'],
    domevents: {
        mouseover: function() {
            this.getTarget().css( 'backgroundColor', 'orange' );
        },
        mouseout: function() {
            this.getTarget().css( 'backgroundColor', 'white' );
        },
        'click button': 'onButtonClick'
    },
    onButtonClick: function() {
        alert('The Button has been clicked');
    }
});

A working example can be found at JSFiddle.

More documentation can be found under AObject.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

AFrameJS is Now Compatible with Node.js/CommonJS

Today I did some initial work in making AFrameJS compatible with the CommonJS module format, which means AFrame can now be imported into node.js!

Since using AFrameJS on the server isn’t going to involve DOM manipulation (generally speaking), a special build has been added to the GitHub repository’s dist directory – the build removes all classes that deal with the DOM – things like Fields, Lists, and any of their related classes.

To use AFrameJS inside of your node.js project, download a build for node and place the file in your apps directory. I renamed the file to “aframe.js” from whatever the long name I downloaded.

Next, in your startup code:

   var AFrame = require( 'aframe' );

   // Use AFrame here.
   var MyClass = AFrame.Class( { /* class definition */ } );
   var myClassInst = AFrame.create( MyClass );

Sweet.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

Defining Classes in AFrameJS

Along with the updates to make object instantiation easier in AFrameJS, defining classes for the “80% case” has become much simpler.

In AFrameJS, most class constructors do absolutely nothing other than call its superclass constructor. Object initialization is deferred until the init function. The reason for this is so that Plugins can be created and bound to an object before the object is ever operated on. The late initialization allows Plugins to do things like place decorators on functions on the object, all of this happening before the object is operated on. 80% of the time, this is all that a constructor needs to do.

After developing a lot of classes, I began seeing this repeated over and over again:

var Class = function() {
    Class.sc.constructor.call( this );
};
AFrame.extend( Class, SuperClass, {
   // more code
} );

Identical class constructors as well as the AFrame.extend were being repeated over and over again. Booo..

A Better Way

It just made sense to combine all that repeated logic and cut down on that code. There is a shortcut now, AFrame.Class.

Defining a Class That Has a Superclass

The above example is reworked as:

var Class = AFrame.Class( SuperClass, {
   // more code
} );

Much simpler, isn’t it?

Defining a Class That Does Not Have a Superclass

If your class has no superclass, even easier

var Class = AFrame.Class( {
   // more code
} );

A working example of these two in action can be found on JSFiddle.

The 20% Case – Your Constructor Needs to Do Something

If for some reason your class constructor needs to do something critically important, you can still do this, it just takes a bit more work. We’ll just go back to the old way of doing this as outlined above.

var Class = function() {
    Class.sc.constructor.call( this );
};
AFrame.extend( Class, SuperClass, {
   // more code
} );

That’s all there is to it. Less code. Same functionality. Just as much if not more readability.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

Object Instantiation in AFrameJS – Now Simplified

Note: This article has been updated because of an even more simplified method of object creation as shown in Object Instantiation in AFrameJS – Now Simplified Even More.

As of today, AFrameJS’s AFrame.AObject compatible object instantiation is significantly improved. The old syntax for AFrame.construct was very readable but extremely verbose, resulting in code that sometimes had nearly as many lines to do instantiation as the base classes themselves. Bad jiji.

Because I like writing as little code as possible and still have maintainable code, I redid AFrame.construct, deprecating its use, replaced by AFrame.create, which too has been deprecated. All “Classes” that are created using AFrame.Class or AFrame.extend, and which have an init function, will have a “create” method attached as a static class function. Create can be called to create an instance of the class, create takes one parameter – the instantiation options.

In this post, I am going to give examples on how to use AFrame.create in its various incarnations. Then, I am going to show the updated “Add Friends” demo from the post “AFrameJS Tutorial – A Response to ‘Backbone.js Tutorial – by noob for noobs’”.

First a Little Background

Create is only added to classes that have the init function, in AFrame based applications, this normally means AFrame.AObject based classes. In AFrameJS, most classes do very little in their class constructors, instead deferring object initialization until the init function. This is so that Plugins can be bound to an object before the plugged object is initialized. This gives some advantages such as allowing plugins to add decorators to the plugged object, as well as the plugin being notified as soon as the plugged object is fully initialized.

To allow for the binding of objects and plugins, the normal sequence of object creation is:

  1. Instantiate the plugged object
  2. Instantiate, initialize, and bind plugins to plugged object
  3. Initialize the plugged object, passing to the init function any configuration

This is such a common paradigm in AFrameJS that the class’ create performs all of this when given a configuration object.

Examples

AFrame.AObject Instantiation, no configuration

// Instantiate an AFrame.AObject, give it no configuration
// The only parameter is a constructor
var obj = AFrame.AObject.create();

AFrame.AObject Instantiation, with configuration

// Instantiate an AFrame.AObject, give it a configuration object giving a
// cid for the object. The first parameter is the constructor, the second
// parameter is configuration
var obj = AFrame.AObject.create( {
   cid: 'SampleAObject'
} );

AFrame.AObject Instantiation, with a Plugin that has no configuration

// Instantiate an AFrame.AObject, give it a configuration object that
// contains an array of Plugins. The only Plugin as an AFrame.Plugin,
// with no configuration.
var obj = AFrame.AObject.create( {
   plugins: [ AFrame.Plugin ]
} );

AFrame.AObject Instantiation, with a Plugin that has configuration

This is the most complex case of instantiation, all others are variations of the examples already presented.
So that we can define which plugin to add as well as the configuration for that plugin, we use a 2d array.

// Instantiate an AFrame.AObject, give it a configuration object that
// contains an array of Plugins. The only Plugin as an AFrame.Plugin,
// with no configuration.
var obj = AFrame.AObject.create( {
   plugins: [ [ AFrame.Plugin, {
       someConfigItem: 'someConfigValue'
   } ] ]
} );

Putting It All Together

Now we are going to instantiate an object with multple plugins, one plugin without configuration, one plugin with.

// Instantiate an object with multple plugins, one plugin without
// configuration, one plugin with.
var obj = AFrame.AObject.create( {
   cid: 'SampleAObject',
   plugins: [ AFrame.FirstPlugin, [ AFrame.SecondPlugin, {
       someConfigItem: 'someConfigValue'
   } ] ]
} );

Reworking the “Add Friend” Example

A working example can be found on JSFiddle.

$( function() {

    // Instead of creating a model, create a SchemaConfig.
    // A Model in AFrame is an instance of data combined
    // with a Schema.  The schema config will be used when
    // creating the model.
    var friendSchemaConfig = {
        name: { type: 'text' }
    };

    // Our friends collection is an array.  Instead of binding
    // directly to an event on the collection, when creating
    // the list, we bind the list to the collection.
    // The ListPluginBindToCollection will take care of
    // updating of the list.
    var friendsCollection = AFrame.CollectionArray.create( {
        plugins: [ [ AFrame.CollectionPluginModel, {
             schema: friendSchemaConfig
        } ] ]
    } );

    // This is the friends list.  It is bound to the
    // friendsCollection, so any time a model is added or
    //  removed from the friends collection, the list will update.
    var friendsList = AFrame.List( {
        target: '#friendList',
        listElementFactory: function( model, index ) {
            return AFrame.DOM.createElement( 'li',
                model.get( 'name' ) );
        },
        plugins: [ [ AFrame.ListPluginBindToCollection, {
             collection: friendsCollection
        } ] ]
    } );

    // we insert into the friendsCollection once we
    // have a name.  The list will be updated automatically.
    $( '#add-friend' ).click( function( event ) {
           var friend_name = prompt("Who is your friend?");
           // A new model will be created when adding
           // to the friend collection.
           friendsCollection.insert( { name: friend_name } );
    } );
} );

The original post with updated examples is at: AFrameJS Tutorial – A Response to “Backbone.js Tutorial – by noob for noobs”

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

AFrameJS Tutorial – A Response to “Backbone.js Tutorial – by noob for noobs”

Note: This article was updated on Feb 7, 2011 to use the new syntax of AFrame.create.

I am trying to follow the format given by Thomas Davis in “Backbone.js Tutorial – by noob for noobs”, so this is going to look *extremely* similar.

The basic theory behind AFrameJS is identical to Backbone.js, bring the MVC programming paradigm to Javascript applications. For too long, front end developers have been muddling their models, views, control, and data access code together resulting in very difficult to maintain/modify/reuse code. The goals of MVC are to first and most importantly, simplify the cognitive load on the developer. Code reuse, easier unit testing and all the other goodies that people talk about when referring to MVC are natural outcomes.

An MVC Primer

The main idea of MVC is to separate data, views of that data, and the bindings of the two into distinct units. Data and all operations on that data create a Model. Views are as the name implies, views of a piece of data. Controllers are the glue that bind the two together.

How does this “reduce the cognative load on the developer?” Well, simply put, by keeping these ideas separated in code, it helps you keep them separated in mind. The human mind is terrible at multi-tasking, by focusing on one thing at a time, we have a much easier time at getting that one thing right.

So what is a model? A model is a piece of data and any operations on that data. Sounds a bit like the standard definition of a Class. Well, it is, the model contains data and any operations/validations on that data. It is where “business logic” typically lives. When thinking about a model, we don’t have to think about how that data is presented, we only worry about what happens with that data.

What is a view? A view is how a piece of data is presented. A view doesn’t have to be graphical only, it could be purely textual, it could be a way of representing the model to transmit to an RSS reader, it can be any way of “viewing” the data. Views should be semi-dumb to the underlying business/validation logic of the data. The reason – say I write a way of inputting a piece of data today, but tomorrow I need a second way to input that same bit of data. Both of these use Views, but if I wrote the validation logic in the Views, I would have to write it in both views. Not very good. A view often times reacts to changes in its corresponding model. So, if data changes in the model, the view is updated to reflect that, it is preferable that all of this happens automatically.

On to the Code

First, download a copy of AFrameJS – Currently there is no CDN for it. There is a version of AFrameJS for jQuery, MooTools, and Prototype. This tutorial is going to use jQuery and the jQuery version of AFrameJS. All scripts are saved into the scripts subdirectory.

<!DOCTYPE html>
<html>

<head>
    <title>AFrame Introduction</title>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript" src="scripts/aframe-current-jquery.js"></script>
    <script type="text/javascript" src="scripts/demoapp.js"></script>
</head>

<body>

    <ul id="friendList">
    </ul>

    <button id="add-friend">Add Friend</button>
</body>

</html>

Setting Up the Main Controller

While I could, I am not going to create a “Main View” in the Backbone sense. A Display could be used for this purpose, but for startup, I prefer to create a “Main Controller – a controller that initializes up my Model and View objects and then gets rolling.

$( function() {

    $( '#add-friend' ).click( function( event ) {
           var friend_name = prompt("Who is your friend?");
           // We need to create a friend model with this information.
           // More on this later.
    } );

} );

Lists

Similarly to Backbone, AFrame requires that each View(Display) have a target. The target is where the View is displayed. The target can be updated from within the Display, but for now, we are going to use the list with the id “friendList” as the target of our List. Every list needs a listElementFactory. A listElementFactory is the equivalent of “addFriendLi” in the Backbone demo. We will bind this list to a collection of friends in a moment.

// This is the friends list.
var friendsList = AFrame.List.create( {
     target: '#friendList',
     listElementFactory: function( model, index ) {
         return AFrame.DOM.createElement( 'li',
             model.get( 'name' ) );
    }
} );

Modelling our Friends

Our Friends are going to have a very simple data model, in AFrameJS, the layout of our models is defined by a Schema and its schemaConfig.

Our Friend models are going to be created automatically by the way we associate our Collection with the friendSchemaConfig shown
below.

// To define data, create a SchemaConfig.  A Model in AFrame is an
// instance of data combined with a Schema.  The schema config
// will be used when creating the model.
var friendSchemaConfig = {
    name: { type: 'text' }
};

Do We Only Have One Friend? Collections of Friends

As Thomas says, a single model by itself isn’t the most exciting thing, imagine a world where you were only ever allowed to have one friend. So we are going to create a Collection to keep track of all of our friends. The collection used is going to be a CollectionArray. AFrameJS also offers a CollectionHash for when you want to access items by a key instead of an index.
In this instance, we know that all of the data inserted into our collection is going to be based on the same Schema, so to make our lives a bit simpler, we can associate a Schema with the Collection. Every time we insert data into the Collection, a model will be created automatically.

// Our friends collection is an array. Our Collection is going to
// use the friendSchemaConfig to define what each model looks like.
var friendsCollection = AFrame.CollectionArray.create( {
   plugins: [ [ AFrame.CollectionPluginModel, {
        schema: friendSchemaConfig
   } ] ]
} );

Tying Up Loose Ends

Now it is time to tie up the loose ends.

First, I bind the List to the Collection. Whenever items are added or removed from the Collection, these changes will be automatically reflected in the List.

// Updated friendsList, it is now bound to the friendsCollection,
//so any time a model is added or removed from the friends
// collection, the list will update.
var friendsList = AFrame.List.create( {
     target: '#friendList',
     listElementFactory: function( model, index ) {
         return AFrame.DOM.createElement( 'li',
             model.get( 'name' ) );
     },
     plugins: [ [ AFrame.ListPluginBindToCollection, {
            collection: friendsCollection
     } ] ]
} );

Finally, back to our initial “Controller” which is a button click handler that asks what our friend’s names are. When we have the name, we are going to call createFriendModel, which creates our model, then we are going to insert the model into the collection. This will cause the list to update.

// we insert into the friendsCollection once we have a name.
//  The list will be automatically updated.
$( '#add-friend' ).click( function( event ) {
       var friend_name = prompt("Who is your friend?");
       // Add a new friend model to our friend collection.
       // The Model will be created automatically from the data.
       friendsCollection.insert( { name: friend_name } );
} );

Putting it All Together

Now time for the completed code. A fully functioning demo can be found on JSFiddle. All code can be found on GitHub.

$( function() {

    // Instead of creating a model, create a SchemaConfig.
    // A Model in AFrame is an instance of data combined
    // with a Schema.  The schema config will be used when
    // creating the model.
    var friendSchemaConfig = {
        name: { type: 'text' }
    };

    // Our friends collection is an array.  Instead of binding
    // directly to an event on the collection, when creating
    // the list, we bind the list to the collection.
    // The ListPluginBindToCollection will take care of
    // updating of the list.
    var friendsCollection = AFrame.CollectionArray.create( {
        plugins: [ [ AFrame.CollectionPluginModel, {
             schema: friendSchemaConfig
        } ] ]
    } );

    // This is the friends list.  It is bound to the
    // friendsCollection, so any time a model is added or
    //  removed from the friends collection, the list will update.
    var friendsList = AFrame.List.create( {
        target: '#friendList',
        listElementFactory: function( model, index ) {
            return AFrame.DOM.createElement( 'li',
                model.get( 'name' ) );
        },
        plugins: [ [ AFrame.ListPluginBindToCollection, {
             collection: friendsCollection
        } ] ]
    } );

    // we insert into the friendsCollection once we
    // have a name.  The list will be updated automatically.
    $( '#add-friend' ).click( function( event ) {
           var friend_name = prompt("Who is your friend?");
           // A new model will be created when adding
           // to the friend collection.
           friendsCollection.insert( { name: friend_name } );
    } );
} );

Again, a fully functioning demo can be found on JSFiddle, and all code can be found on GitHub.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

AFrameJS Demo App – MobileNotes

I had a request for a demo application to better show off the syntax and capabilities of AFrameJS. While it is still extremely basic, MobileNotes makes use of many of the low level capabilities given by AFrameJS. It is using Models, Collections, Lists, DataForms, and Fields. That’s pretty much all the major parts.

MobileNotes makes use of WebSQL in browsers that support it – Chrome, Safari, or Opera on the desktop, as well as the default browsers on iPhone/iPad and Android mobile devices. In these browsers, your notes will be persisted across browser sessions, without data ever being sent to the server.

MobileNotes is making use of jQuery 1.4.4, jQuery Mobile 1.0 Alpha 2, as well as DateJS.

Source to MobileNotes can be found on GitHub. Comments, suggestions, and improvements are gladly accepted.

Take a look, trace through, create your own app using AFrameJS, contribute, and make the library even better!

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

AFrame Now Supports jQuery, MooTools, and Prototype

AFrame has been refactored so that its previous jQuery dependency has been removed! All core DOM manipulation goes through a DOM adapter, with adapters being written for jQuery, MooTools and Prototype. This means that you can now use AFrame along side of your current favorite DOM manipulation library without adding any new dependencies.

If you are only using AFrame for its data modelling capabilities, then the next section will not be of much interest to you. For those using AFrame for its Display capabilities, the following are examples on how to use AFrame to create a display in each of jQuery, MooTools, and Prototype.

Creating a Display in jQuery

// create the firstNameTarget element and attach it.
var firstNameTarget = $( '<input id="firstNameInput" type="text" name="first_name" />' ).appendTo( $( 'form' ) );

// Method 1.  Passing the firstNameTarget directly.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: firstNameTarget
     }
} );

// Method 2.  Using a selector.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: '#firstNameInput'
     }
} );

Creating a Display in MooTools

This looks amazingly similar to the jQuery method – the only difference is in the creation of the input element.

// create the firstNameTarget element and attach it.
var firstNameTarget = new Element( 'input', {
    type: 'text',
    id: 'firstNameInput',
    name: 'first_name'
} );
$$( 'form' ).adopt( firstNameTarget );

// Method 1.  Passing the firstNameTarget directly.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: firstNameTarget
     }
} );

// Method 2.  Using a selector.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: '#firstNameInput'
     }
} );

Creating a Display in Prototype

This too, looks amazingly similar to the jQuery method and even more closer to the MooTools method.

// create the firstNameTarget element and attach it.
var firstNameTarget = new Element( 'input', {
    type: 'text',
    id: 'firstNameInput',
    name: 'first_name'
} );
$$( 'form' )[ 0 ].insert( firstNameTarget );

// Method 1.  Passing the firstNameTarget directly.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: firstNameTarget
     }
} );

// Method 2.  Using a selector.
var field = AFrame.construct( {
     type: AFrame.Field,
     config: {
         target: '#firstNameInput'
     }
} );

They all look pretty much the same. That’s a good thing since it means that AFrame can work with your DOM library’s native element objects. You do not have to change anything about the way you write your DOM code, you do not have to do any sort of translation, AFrame is ready to take your library’s DOM objects as is. You can use your DOM library to do your DOM manipulations, but still use AFrame to do the jobs it was meant to do – manage MVC logic.

Check it out!

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

SOOOO Many AFrameJS Updates!

There have been SOOOOO many AFrameJS updates since the project was first put up on GitHub, the ideas just keep flowing, plus it helps that I am working through a lot of the peculiarities on a new project (which is not my own, so it has to remain under wraps). The documentation is coming along nicely, the API is becoming more uniform, and so many features have been added that it is silly. There are now full fledged models, data validation on both the model and HTML5 based form validation, enumerables have been added where it makes sense, the event system has undergone some major transformations and the tutorial now shows some good examples.

But, my plans are to keep going, making a clean project that is useful to me, and hopefully to others writing MVC apps in Javascript as well. My immediate plans are to do two builds of the project, one with only the model related items, and one full build. Models, schemas and observables and the other model related items are powerful enough to stand on their own, plus it will have no jQuery dependency.

I’d like to remove the jQuery dependency completely and have all DOM related functionality go through an adapter, with adapters for each of jQuery, MooTools, Prototype, and maybe YUI. No need to constrain ourselves here!

Ahhh, this project makes me happy.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Google Buzz Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati