Planbox at JS-Montreal: Discovering Enyo 2.0 and Blanket.JS

Thursday, November 15th, 2012

On Tuesday, I went to the 24th monthly meeting of JS-Montreal, which took place at CakeMail’s office. There were around 20 people in the room. Having previously attended HelsinkiJS in Finland, I was expecting to greet a similar crowd of developers with many years of experience under their belts. To my great surprise, I had the chance to meet many young developers like myself at JS-Montreal. In fact, for a good third of the attendees, it was their first time assisting the JS-Montreal monthly meetup. To me, it highlights the dynamism of Montreal’s JavaScript community, and the attractiveness of the language.

 

Alex Seville Nurun Developer

Alex Seville, developer at Nurun, did a presentation on Blanket.JS.


There were two presentations: one by Alex Seville about Blanket.JS, and the other by Olafur Arason about Enyo 2.0.

Blanket.JS is a code coverage library working on both the browser and Node.js. It is pluggable into unit Mocha or QUnit. Enyo 2.0 is a lightweight user interface library sponsored by HP. It works on normal screens, mobiles, and tablets. It brings an interesting concept of a component based architecture. These tools may not even meet your stability requirements, or they may still be too underground for serious adoption currently; but, they still bring a fresh breath of innovation to the JavaScript world.

 

Question for you:

Have you heard of Blanket.JS or of Enyo.JS before? Do you know some web sites that make heavy use of either one? Please share with us in the comments below.

line

Getting Started with NodeJS on Windows

Sunday, September 4th, 2011

Today I wanted to install NodeJS with Express on my Windows machine without having to compile anything on cygwin. Took me some time to find out how to do so easily. So here are those instructions for anyone else wanting to do so.

First, let’s create a dir to put everything in:

C:\Node

Install NodeJS

You can find pre-built and self-contained Windows binaries here: http://node-js.prcn.co.cc/. The latest stable is 0.4.11. Download that one and put everything in the Node folder. You should then have something like this:

C:\Node\bin
C:\Node\lib
...

Install Express

Next up you install Express. That requires Mime and Connect modules. You can find all on GitHub:

You need to put these in the C:\Node\lib\node_modules folder. You should then have something like this
C:\Node\lib\node_modules\connect\...
C:\Node\lib\node_modules\express\...
C:\Node\lib\node_modules\mime\...

Test and Run

Create this file C:\Node\test.js and put this in:

var express = require('express');
var app = express.createServer();
app.get('/', function(req, res){
    res.send('Hello World');
});
app.listen(80);

To run, open a command prompt, step into the Node folder and type:

bin\node.exe test.js

At this point, you may have this error:

Cannot find module 'qs'

If so, do a search and replace for ‘qs’ by ‘querystring’. That module was renamed in NodeJS, but Connect and Express may not have made the change yet. I had to change these 3 files:

  • C:\Node\lib\node_modules\connect\lib\middleware\bodyParser.js
  • C:\Node\lib\node_modules\connect\lib\middleware\query.js
  • C:\Node\lib\node_modules\express\lib\http.js

After the search and replace, run again and the server should run without any errors. Now in a Browser type http://localhost and you should see Hello World.

That’s it! Now you can start developing a NodeJS web app directly from your Windows machine. How great is that!

 

line

Browser send same request twice or multiple times

Monday, January 24th, 2011

Here at Planbox, we had a problem on a page where the browser was making the same request multiple times. In Firebug we saw something like this:

  • GET page
  • GET jquery-ui.js
  • GET page.css
  • GET page
  • GET loading.gif
  • GET page

Looking at the HTTP request headers, I noticed the 1st call was accepting text/html but the 2nd and 3rd calls were accepting image/*.

So I googled and found this article from Michael Morton. Other articles also touch on the subject but these are potential causes:

  • Empty src attribute on an img tag
  • Empty url definition on a CSS property
  • Empty href attribute on an a tag.

It had to be one of those. So I opened up Notepad++ and started searching and didn’t find anything.

Then my colleague Seb suggested I used jQuery to find it. Of course! So here’s a quick code snippet to find bad tags. Just run this in the console of Firebug.

$('img[src=""],a[href=""]')

In a snap I found the culprits. They were a couple of Javascript functions generating img tags on the fly but leaving the src attribute empty.


line

Javascript Simple Search Engine

Monday, December 6th, 2010

Today I’m happy to release Planbox‘s first contribution to the open source community. It is a small Javascript search engine called JSSE (pronounced Jesse). It is a single Javascript file you can use to index strings and perform rapid lookup. JSSE performs partial matching (a.k.a trailing wildcard query) for all or any search terms.

We have developed JSSE to increase performance of auto-completes, client-side.  To see a demo, go here.

To make use of it, include it in your HTML header. Then create an instance like this:

se = new Jsse();

Index a text found in a document like this:

se.add('Instant search in Google is awesome!', 'quote');
se.add('It will work find after you install that patch.', 'instruction');
se.add('I bought a red car.', 'mid-life crisis');

Find a match like this:

se.match('inst');

Returns:

['quote', 'instruction']

JSSE is dynamic. You can remove what you’ve previously added.

se.remove('Instant search in Google is awesome!', 'quote');

JSSE is hosted here: www.planbox.com/code

If you find bugs or would like to suggest enhancements, please post them here.

line

Javascript MVC Framework for Rich Web Applications

Monday, November 29th, 2010

Planbox is a complex UI beast. Notably the Plan page which handles tons of different user interactions. Take for example when you complete a task (1).  The holding item gets updated (2) and the user and initiative progress as well (3 & 4). Oh, by the way Planbox is an Agile Project Management Tool, for those who are just coming to this blog.

To perform this magic, we rely heavily on John Resig’s jQuery and AJAX calls to the Planbox Engine. However as our code grows, we find ourselves struggling to maintain a growing number of Javascript functions to handle all of this.

So we head out searching for a Javascript framework which could solve my problem. My requirements were simple:

  1. Must be minimalist. No bloated Javascript framework with 90% of stuff we won’t use.
  2. Must implement MVC. We want to keep presentation and data decoupled.
  3. Must be easy to understand and extend. Clean and easy to read code please.

Not long ago I was brought to look at Jeremy Ashkenas’ Backbone JS. It’s brand new on the block (released October 13th) and fits most of my requirements. Here’s how Jeremy describes Backbone:

Backbone supplies structure to JavaScript-heavy applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.

At that point, my mouth was watering. But then I also read this sentence:

Backbone is a 2 kilobyte include that provides just the core concepts of models, events, collections, views, and persistence.

I was sold. My quest was over.

Binding Events on Data

I’ve been prototyping with Backbone for a few weeks now. And I really like it. The core power comes in binding events to data. In Backbone Models represent data. You can bind events on a Model and trigger a handler when the Model changes. That is powerful. Views on the other hand listen to the Model and update DOM. Here’s a little code snippet of a View:

ItemView = Backbone.View.extend({
	tagName: "li",
	template: _.template($('#item_template').html()),
	initialize: function(options) {
		_.bindAll(this, 'render');
		this.model.bind('change', this.render);
	},
	render: function() {
		$(this.el).html(this.template(this.model.toJSON()));
	}
});

Backbone also integrates a template engine to facilitate with the presentation layer (you can choose to plug in your own if you prefer). For example here is the item template from the above example. It simply outputs the item name and status inside the div element (specified in the View’s tagName property):

Things to Improve

A couple caveats though:

  1. Server interaction is too restrictive. The Sync function and Controllers assume a near one-to-one object mapping between the client and server. And Backbone assumes that mapping is to be shown in the URL hash tag.
  2. Events are too primitive and don’t behave as expected in some situations. For example, it is not yet possible to unbind an event in the bound event handler itself.

Fortunately Backbone is extensible. You can easily overwrite any method using the Underscore extend function. And as I said, Backbone is still young and evolving. So existing limitations will surely be overcome over time.

Underscore – A Pleasant Discovery

In working with Backbone I also discovered another powerful library: Underscore by Jeremy Ashkenas. It includes tons of useful Javascript functions. It has become an integral part of my Javascript toolkit along with jQuery and json2.js. I encourage you to have a look.

So for those of you looking for an elegant way to decouple business data and presentation in Javascript, have a look at Backbone JS. It may be the thing you’re looking for.

P.S. Thanks to Mathieu for the discovery of Backbone JS (http://www.mathieusavard.info).


line

jQuery UI Sortable – Slow to bind

Friday, August 20th, 2010

We broke down the time it took to generate a Planbox plan page and realized that all that Javascript binding was taking much of the time. Out of that time, the vast majority of the time was spent applying .sortable() to enable drag & dropping of all elements. It turns out that time is vastly reduced if we removed the connectWith option, but then user cannot drag&drop items from an iteration container to another..

By playing with this today I realized that we can save a lot of processing and time by setting the connectWith option AFTER the .sortable() is initialized!!

Before:

  $(container).sortable({
    distance: 5,
    axis:"y",
    "connectWith", '#story>.iteration_frame>.iteration_container.allowdrop'
    cancel: 'div.disabled,div.opened,div.plan_table_message'
  });

After:

  $(container).sortable({
    distance: 5,
    axis:"y",
    cancel: 'div.disabled,div.opened,div.plan_table_message'
  }).sortable( "option", "connectWith", '#story>.iteration_frame>.iteration_container.allowdrop' );
  // For whatever reason setting this option AFTER initialization saves us 4X the time!!

The bottom line?

Here are times to do JS bindings (browser is blocked for that time so it’s a time the user feels!)

Plan, large page, all initiatives all items everybody,

Before: 16 935ms, 253437 calls

After: 5 617ms, 179336 calls


Work page, same selection

Before: 1200ms, 136 668 calls

After: 510ms, 39565 calls


The more sortable elements on the page the bigger the benefit!

Ticket #5886 was opened on jQuery UI to resolve this.

line