James Thomas

Notes on software.

Upcoming Talks

Next month I’ll be presenting at IBM IMPACT 2012, IBM’s premier customer conference in Las Vegas from April 29th until May 4th. I’ve had three sessions accepted, full details below. If you’re attending the conference and want to say hello, please let me know.

This week I was invited to present a preview of the joint session I’m doing with Dylan Schiemann at IMPACT for London AJAX. There was a really great crowd of over seventy developers waiting to hear all about AMD. The talk was recorded and can now be viewed online here. Due to an unexpected travel delay I was delayed by 30 minutes, you can see my appearance after that. Thanks for Dylan for carrying the show until I arrived!

During this year’s IBM IMPACT conference, there’s an official “unconference” running on the Wendesday. Anyone can submit ideas for talks, from full sessions to lightning talks, with the community voting on what they would like to see. I’ve submitted an idea for a lightning talk titled ”JavaScript Anti-Patterns - Moving from Java to JavaScript”. If you want to see this talk, visit the link and vote for the idea.

Once the conference has finished I’ll make all of the material available externally.

See you all in Vegas!

IBM IMPACT Schedule

  • TDW-2292: Optimizing Your Dojo Application Using The Dojo Build System

    • Session Type: Lecture
    • Date/Time: Tue, 1/May, 03:15 PM - 04:30 PM
    • Room: Venetian - Marcello 4401A
  • TDW-1537: Moving to Dojo 1.7 and the Path to 2.0

    • Session Type: Lecture
    • Date/Time: Thu, 3/May, 10:30 AM - 11:45 AM
    • Room: Venetian - Marcello 4402
  • TDW-2286: Beyond Dojo: The Rise of Asynchronous Module Definition (AMD)

    • Session Type: Lecture
    • Date/Time: Thu, 3/May, 08:45 AM - 10:00 AM
    • Room: Venetian - Marcello 4403

Creating Todo MVC in Dojo - Part 2: Views

In the previous article, we looked at defining our application Model using the Dojo MVC package. The model contained a list of todo tasks, each with a description and finished state, along with composite values representing the total completed and remaining task counts.

Dojo’s MVC package provides a series of widgets (Group, Output, Repeat, Generate) that assist the rendering of model attributes in our View, which automatically update when model values change. We’re going to look at using these widgets to build our TodoMVC Application View…

Defining a View template

For a long time, Dojo has had excellent support for creating widgets with HTML templates using modules from the Dijit package. Defining a new widget simply requires inheriting from a base class (_WidgetBase), adding in mixins for template support (_TemplatedMixin & _WidgetsInTemplateMixin) and providing a HTML template file that will be automatically rendered in the page by the Dojo parser. In our application, we’ve created a new templated widget todo.app, present in app.js along with a template file app.html.

The basic outline of this module is shown below.

Templated TodoMVC WidgetSource Link
1
2
3
4
5
6
7
8
9
10
11
12
define(["dojo/_base/declare",
        // Parent classes
        "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
        // Widget template
        "dojo/text!./app.html",
        ...
    function(declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, template) {
        return declare("todo.app", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
            templateString: template,
        });
    }
);

Defining our application as a templated widget lets us annotate HTML elements, using the data-dojo-type attribute, in the application page to be automatically instantiated into corresponding widgets at runtime by the Dojo parser. When this occurs, the view template will replace the annotated HTML element in the page and any child widgets in the view will be recursively created.

The HTML snippet below shows how we load Dojo, the parser, our application and turn on the automatic parsing on load to render our Todo widget within the page.

Loading TodoMVC App Within The PageSource Link
1
2
3
4
5
6
<script data-dojo-config="async:true, parseOnLoad:true, paths:{'todo':'../../todo'}, 
    deps:['dojo/parser', 'todo/app']" src="./js/dtk/dojo/dojo.js"></script>

...

<div class="content" data-dojo-type="todo.app"></div>

This templated widget is rendered within the page and represents our view. The view has three main tasks:

** Display the list of todo items * Allow a user to enter more tasks * Show statistics for the number of completed and remaining tasks.

We’ll look at each individually to see how we implemented those features using the Dojo MVC package.

Displaying Todo Tasks

We’ve used the <ul> element to represent the container for our todo tasks, each task being an <li> element with the same HTML template populated with different values. The content for each task and the number of tasks needs to be dynamically generated based upon the values in the model.

Dojo MVC provides a widget for this pattern, dojox.mvc.Repeat, letting the user specify an array in the model for binding to with a HTML template to be repeated for each element.

The HTML template for the repeating todo tasks is shown below.

Rendering Todo TasksSource Link
1
2
3
4
5
6
7
8
9
10
11
<ul class="todo-list" data-dojo-attach-point="todo_list" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: this.model.todos, exprchar: '#'">
    <li data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '#{this.index}'">
        <div class="todo">
            <input class="check" data-dojo-type="todo.form.CheckBox" data-dojo-props='ref: "isDone"'>
            <div class="todo-content dijitInline" data-dojo-type="dijit.InlineEditBox"
                data-dojo-props='ref: "todo_text", editor:"dijit.form.TextBox", autosave:true, width:"420px", style:"width:420px;"'></div>
            <span class="todo-destroy" data-model-id="#{this.index}">
            </span>
        </div>
    </li>
</ul>

Repeating View Templates

In the template, the containing <ul> element is registered as the dojox.mvc.Repeat widget using the data-dojo-type attribute. Using the data-dojo-props attribute, we can pass widget parameters to the newly created widget when it’s instantiated by the parser.

The first parameter, ref, provides a variable name for the model attribute to bind to. We’re using the model available on the widget instance, “this.model”, with the “todos” attribute, which contains an array of task objects. The second parameter, exprchar, is the character to use for substitution expressions in declarative child widget attributes. By default, this value is the ‘$’ character. As we’re using the declarative programming style, these expressions would be confused with normal template value substitutions and we use the ‘#’ character instead.

Under the <ul> element, we have the HTML template for each todo task, represented by the <li> element. Here we are using the dojox.mvc.Group widget, which provides the parent model context for any child widgets which use substituion expressions and references to access model values. Registering the parent context as an individual item within the model “todos” array is achieved by using the “#{this.index}” reference, this will be automatically incremented by the parent Repeat widget as it iterates through the model array.

Binding UI Controls

Each todo task has three UI controls, the task text (either as a read-only value or an inline edit box for modification), a checkbox representing the completed state of the widget and an icon to allow the removal of the task. Our chosen UI controls (InlineEditBox & CheckBox) are bound to model values by providing a “ref” attribute with the attribute name. These widgets will automatically be populated with the current model values during rendering.

This binding between the view and the model is bi-directional, changes to the model will automatically propagate to the view widgets and changes to the view widgets will flow back to the model.

When a user wants to remove a task, the “click” event generated by the icon in the view will be intercepted by the Controller. Allowing the controller to determine which todo task to remove from the model is provided by setting the current item index as a custom parameter on the HTML element. We will be looking at the code to perform the removal in a later article.

Showing Completed & Remaining Counts

Along with the todo tasks, we need to display stats for the number of completed and remaining tasks. These attributes are composite model values, being automatically calculated from other model attributes. The displayed values need to be updated live as the other model attributes change but won’t be directly modifable by the user. The code snippet below shows the HTML template in the view for this component.

Showing Task StatsSource Link
1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="todo-stats" data-dojo-attach-point="todo_stats">
    <span class="todo-count">
        <span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: this.model.incomplete" class="number"></span>
        <span class="word">items</span> left.
    </span>
    <span class="todo-clear">
        <a href="#" data-dojo-attach-event="onclick:removeCompletedItems">
            Clear
            <span class="number-done" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: this.model.complete" ></span>
            completed items
        </a>
    </span>
</div>

We’ve used simple HTML elements to display the values, rather than Dijit widgets, due to the lack of user interaction needed. Binding a HTML element to a Model property can be achieved using the dojox.mvc.Output widget. Again, we use the “ref” attribute to specify which model property the “innerHTML” value on the HTML element should be linked with.

Adding New Tasks

Finally, we need to let the user add new tasks. Using a normal HTML input field, we connect the “onkeypress” event to an internal event handler to allow the app to access the new tasks.

Adding New TasksSource Link
1
2
3
4
<div class="create-todo">
    <input class="new-todo" data-dojo-attach-event="onkeypress:onKeyPress" placeholder="What needs to be done?" type="text"/>
    <span class="ui-tooltip-top" style="display:none;">Press Enter to save this task</span>
</div>

The application controller is responsible for handling the generated events, retrieving the new tasks and adding them into the model. We’ll be looking at exactly how this works in the next article. When new tasks are added, the task list in the view will be automatically re-rendered.

Conclusion

Following on from the first article, we’ve now looked at how the View component of our MVC application works. Using Dojo MVC widgets, we’ve been able to bind simple HTML elements and full Dijit widgets to show model values. This dynamic binding allows Model updates to automatically flow through to the View controls. Secondly, any user modified values automatically update the Model.

The dojox.mvc.Output widget was used to display Model attributes are read-only values in normal HTML elements. We also used the dojox.mvc.Repeat and dojox.mvc.Group widgets to generate a repeated view template for the todo tasks. Connecting user events from the view to the Controller used Dojo’s templated widget mixins.

In the final article, we’ll look at the last component the MVC pattern, Controllers. This includes adding new tasks to the Model, removing individual and completed tasks along with controlling the view components being displayed.

Creating Todo MVC in Dojo - Part 1: Models

In this first article, we going to look at using DojoX MVC to define our application Models, showing the use of the new StatefulModel class. Later in the series, we’ll look at binding our defined Model to a View template, rendering the HTML output and hooking into user events.

Introducing StatefulModels

DojoX MVC uses a specific class for representing Models in the MVC pattern, StatefulModel. By using or extending this class, applications have access to a native JavaScript data model that integrates with all the classes under the MVC package. StatefulModel extends the Dojo Stateful class, introduced in Dojo 1.6 to provide a way to monitor widget property changes, to support more complex behaviour, such as binding to and updating View component, validating of model values and much more.

StatefulModels are instantiated from a plain JavaScript object, representing the initial data structure for the model, or even from a Dojo Store (with support for both synchronous and asynchronous results). To assist the conversion of complex JavaScript objects, a factory function is provided that will traverse the source data, recursively converting all data properties to use the StatefulModel class.

Further details on the StatefulModel class can be found here.

Defining a Model

Reviewing the TodoMVC specification, our application Model needs to contain a list of todo tasks, each one containing a description and that task’s completed state. The task’s description will be provided by the user and can later be modified. As the task is completed, the task’s internal state must be updated. Representing the todo tasks as an array of objects will allow binding to a Repeat View, having a HTML template rendered for each task in the Model.

Looking at the application, there’s two additional properties in the View that are derived from other Model attributes, counts for the completed and remaining tasks. To allow automatic binding of these values into our View template, we’re going to represent these directly in our model. Later on, we’ll set up binding between Model values to allow those composite values to be calculated automatically.

1
2
3
4
5
6
7
8
9
10
11
12
var data = {
    todos: [
        {
            text: "Must write this blog article"
            isDone: false
        }
    ],
    remaining: 0,
    complete: 0
}

var model = dojox.mvc.newStatefulModel({data: data})

Once we’ve defined our Model as a native JavaScript object, we can use the StatefulModel factory to perform the conversion to StatefulModel classes, as shown in the sample above. The result of this function is our application Model, which we can then bind to our View and interact with via the Controller.

The StatefulModel class supports any native JavaScript type, we’re using strings for the description, booleans for the completed state and numbers for the computed totals.

Binding to Model changes

Once you’ve defined a model, you’ll want to be notified of any attribute changes. Using Dojo Stateful’s “watch” method, we can register a function to be executed whenever that model’s attributes are modified using the getter & setter pattern.

1
2
model.watch("attribute", function (attribute, new_value, old_value) {
});

The dojox.mvc.Bind module extends this functionality to cover two common patterns, listening to changes on a series of attributes and binding model properties together. The “bindInputs” function allows an array of model attributes to be passed in, executing a callback whenever any of the attributes change.

1
2
mvc.bindInputs([model.first_attr, model.second_attr, ...], function (attribute, new_value, old_value) {
});

More usefully, the “bind” function sets up a one way coupling between a source and destination model attribute. Whenever the source attribute value changes, the destination model attribute will be automatically updated with the same result. If you want to transform the source value before it’s updated in the destination model, an optional function callback can be passed in. This will be called with the new attribute value and the return value used to update the destination model.

1
2
3
mvc.bind(source_model, "attr", dest_model, "attr", function (attribute, new_value, old_value) {
    // Return transformed value to update dest_model with
});

Creating composite model values

In the TodoMVC application our model has two attributes, “remaining” & “completed”, that need to computed automatically from other model values.

Calculating the “completed” total is performed by looping through the “todos” array and counting the tasks which have an “isDone” attribute as true. Whenever a task’s “isDone” value changes we want to re-calculate and update the “completed” total. Whenever a new task is added, we automatically bind the new item to our calculating function, which updates the composite value with the new count if any of our model tasks are modified.

1
2
3
4
5
6
7
8
9
bindIsDone: function (item) {
    mvc.bindInputs([item.isDone], lang.hitch(this, "updateTotalItemsLeft"));
},

updateTotalItemsLeft: function () {
    this.remaining.set("value", array.filter(this.todos, function (item) {
        return item && !item.isDone.value;
    }).length);
}

Once we have the “completed” total, the “remaining” attribute can be easily calculated if we know the total number of tasks. Using the “bind” method ensures this happens automatically, using optional transform function to create the new composite value.

1
2
3
mvc.bind(this.remaining, "value", this.complete, "value", lang.hitch(this, function (value) {
    return this.todos.get("length") - value;
}));

Extending StatefulModel

Defining our Model requires application code to declare the composite (completed, remaining) attributes, bind to changes on the current (and future) todo tasks and deal with persisting data to local storage. Rather than having this code in the application controller, we can extend the StatefulModel class to encapsulate all this logic. Using Dojo’s Declare module, we can create a new class which extends StatefulModel, allowing us to set the initial model properties as class attributes rather than having to call the dojox.mvc.newStatefulModel() factory manually. The skeleton outline for our StatefulModel extension is shown below, we’ve removed some internal methods for brevity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorage", "dojox/mvc"],
    function(declare, StatefulModel, LocalStorage, mvc) {

    return declare([StatefulModel], {
        data: {
            id: "local_storage_todos",
            todos : [],
            remaining: 0,
            complete: 0
        },

        store: new LocalStorage(),

        constructor: function () {
            var data = this.store.get(this.data.id) || this.data;
            this._createModel(data);

            this.setUpModelBinding();
            this.updateTotalItemsLeft();
        },

        setUpModelBinding: function () {
            mvc.bind(this.incomplete, "value", this.complete, "value", lang.hitch(this, function (value) {
                return this.todos.get("length") - value;
            }));
            array.forEach(this.todos, lang.hitch(this, "bindIsDone"));
            this.todos.watch(lang.hitch(this, "onTodosModelChange"));
        },

        updateTotalItemsLeft: function () {
            this.incomplete.set("value", array.filter(this.todos, function (item) {
                return item && !item.isDone.value;
            }).length);
        }
    });
);

The internal “data” and “store” attributes correspond to properties on the base StatefulModel class. StatefulModel’s constructor will automatically transform raw JavaScript objects, set via the “data” property, into the corresponding StatefulModels.

Unfortunately, it doesn’t contain code for automatically populating the initial model from the “store” property, this is handled in the “dojox.mvc.newStatefulModel” factory. Therefore, we manually construct the initial model values from the store, if available, and re-call the “_createModel” function in our constructor.

Once the model has been instantiated, we can declare and initialise our composite model bindings as well as binding to the initial todo tasks pulled from persistent storage.

You can see the source code for the final version of the TodoModel class here.

Conclusion

In this first article, we’ve reviewed how to use DojoX MVC’s StatefulModel class to create application Models that we can later bind to Views within the application. Using the StatefulModel class, we can bind to model properties, having callbacks executed when one or more attribute values changed.

Taking this further, we can bind model properties together, creating dynamic models whose properties automatically update as others change. Combining this functionality, we defined composite model attributes for the “completed” and “remaining” properties that were automatically calculated as the todo tasks’ state changed, wrapping this code within an extension of the StatefulModel class.

Next time, we’ll be looking at another component of the MVC pattern, Views. Using the TodoMVC application as our example, we’ll show how to define View templates, bind our Model with the View to generate the application’s HTML and ensure user interactions with the todo tasks automatically update the Model.

Creating Todo MVC in Dojo - Overview

Before Christmas, Addy Osmani sent out the following tweet asking for a Dojo-version of the TodoMVC application.

Reviewing their Github page, the project aims to allow developers to compare MVC frameworks by providing implementations of a sample Todo application using different toolkit’s MVC support. They currently have over a dozen entries for toolkits, including Backbone, JavascriptMVC and Spine with more coming soon but, unfortunately, no entry for The Dojo Toolkit.

Introducing DojoX MVC

With the 1.6 release, The Dojo Toolkit introduced a new DojoX module that experimented with better MVC support, utilising recent features that provide automatic widget property monitoring. The module goes beyond simple data binding between models and views, including mapping model attributes to appropriate UI controls, model data validation, data store integration and others. Further improvements were introduced in the recent 1.7 release of The Dojo Toolkit and it is still under active development. For full details on DojoX MVC, see the reference guide.

I’ve been wanting to play with this module for a while and taking up Addy’s challenge provided an ideal opportunity. With help from Ed Chatelain and others, we created and refined our entry over the past two months, ready in time for the 0.3 release of the project.

Being a new part of the toolkit, there weren’t many examples of using the module for building non-trivial applications. Dojo’s TodoMVC entry should provide a good starting point for developers who want to explore DojoX MVC and compare its approach to other toolkits.

Walk-through series

Over the coming weeks, I’m going to walk-through building of the TodoMVC application using DojoX MVC in a series of articles. It will cover defining a model with composite attributes, generating views from the model, binding user actions to model attributes and using local storage for persisting items offline. I’ll also cover some common issues that developers might encounter when using the module.

Check back soon for the first part….

Update (26/05/12)

All articles are now available and the links are below…

Can’t wait?

If you want to dive straight in, the finished application is in my fork of the TodoMVC project, under the “todo-example/dojo” directory. The entry’s pull request has a good discussion about issues encountered, re-factoring, enhancements, etc.

Moving to Dojo 1.7 and the Path to 2.0

Dojo 1.7 was released this month, giving users early access to lots of features that are going to be standard in Dojo 2.0, due late 2012. We’ve already been using early releases of Dojo 1.7 since the summer in my day-to-day role with IBM working on Watson, as we wanted to take advantage of the new module format, better mobile support and much more. With 1.7 now available, I wanted to share my experiences using it on a real project, showing developers what new features are available, how they can use them and what advantages this brings.

Last week I gave an hour long presentation inside IBM to colleagues from the European and US Development Laboratories, sharing my experiences with Dojo 1.7 on the Watson project. The extended version of the slides are now available on slideshare.

The theme of the talk was that Dojo 1.7 provided an opportunity to start upgrading your project to use these (optional) new features today, migrating away from older features that are now deprecated and will be unsupported in 2.0. By beginning to move your codebase across now, the upgrade path to 2.0 will be straightforward and painless.

DojoConf 2011 - Building Dojo in the Cloud

September saw this year’s Dojo Conference hit Washington, D.C for two days. Attending as one of this year’s speakers, I was given the second slot on Saturday morning to talk about the Dojo Web Builder. The presentation covered why we built the tool, what it can do (including a live demo), a high-level overview of the architecture and finished looking at how users have been using the tool since it launched in April.

The slides are now available on slideshare and the audio will soon follow. I’ve also uploaded other recent presentations, including Debugging Mobile Web Apps from London AJAX Mini-Conf in July.

Both Dojo Conf and CapitolJS, which followed the next day, were fantastic, undoubtedly due to the enormous hardwork of the organisers - Chris and Laura Williams (JSConf). I’m looking forward to DojoConf 2012 already…