logo hoe.js

hoe.js

hoe.js is a lightweight javascript library designed to streamline the creation of user interface in HTML/javascript.

Why hoe.js ?

From one side you have toolkits like jQuery that simplifies DOM manipulation but lacks support for creating complex UI.

On the other side you have MVC frameworks that often impose a very heavy-weight mechanism to create applications.

hoe.js's goal is to let you write structured code for small components and let you scale up your application without "getting into your way". It relies on javascript protoypes and jQuery, just adding some missing pieces:

Example

hoe.js does not enforce any kind of structure for your code, but it was specially designed to help you create custom UI components. Here is an idiomatic example of how a "component" would look like.

var Calculator = hoe.Type(function(){
    // some data
    this.sum = 0;
    // reference to UI elements
    this.$sum = null;
});

// create UI
Calculator.prototype.render = function(){
   var $plus_one = button('+1');
   this.listen($plus_one, 'click', this.add_one);
   this.$sum = strong({style: "margin-left:5px"},
                      this.sum.toString());
   return [$plus_one, this.$sum];
};

// logic - event handler
Calculator.prototype.add_one = function(){
   // update data
   this.sum += 1;
   // update UI
   this.$sum.html(this.sum);
};

$(document).ready(function(){
  hoe.init(); // create DOM helper functions
  $('#calculator').html((new Calculator()).render());
});
      

DOM creation

hoe()
var row  = hoe('div', {'class':'row'}, 'foo');
//  <div class="row">foo</div>
      

The first argument is a string with tag name. It returns a jQuery object for the tag. It can take any number of extra arguments where:

  • plain javascript objects are element attributes
  • strings are appended to the element content
  • DOM element or jQuery object is appended to the element content
  • can also take an array of DOM/jQuery
hoe.partial()
var row  = hoe.partial('div', {'class':'row'});
row('foo');
//  <div class="row">foo</div>
row('bar');
//  <div class="row">bar</div>
       

hoe.partial() is used to create helper functions to generate composed tags and/or include tag attributes.

hoe.init()

hoe.init() defines function helpers to create most commonly used tags.

The function's name is the tag it creates. In this example tr() and td() are used.

hoe.init();
var row = tr(td('col1', {'class': "my_class"}));
//<tr>
//  <td class="my_class">col1</td>
//</tr>
      

You can customize the namespace and tags that will be created (check the API)

prototype helpers

hoe.inherit()

Create new types by "inheriting" from other types:

function Base(){
    this.x = 1;
}
Base.prototype.three = function(){
    return 3;
};

var Sub = hoe.inherit(Base, function(){
    this.x = 2;
});
var obj = new Sub();
obj.three();
      
  • the first argument is the function constructor to copy the prototype from
  • the second argument is optional. If present, defines the constructor otherwise the constructor from the base type is used
hoe.Type

hoe.Type is an abstract type that provides some convenience methods that keep the scope to the object when passing methods as callbacks. It also supports a basic event system to be used between objects.

When creating new type you should inherit from hoe.Type

var MyType = hoe.inherit(hoe.Type, function(){/*...*/});

// ... this shorthand has the same effect as above
var MyType = hoe.Type(function(){/*...*/});
      
hoe.Type.scope
Similar to jQuery.proxy() to be used in the current object scope.
var MyStuff = hoe.Type(function(){
    this.x = 5;
});
var my = new MyStuff();
var get_on_scope = my.scope(function() {return this.x;});
get_on_scope(); // 5
hoe.Type.forEach
Iterate through arrays or objects keeping the context to the current object.
var MyType = hoe.Type(function(){
    this.class = 'my_class';
    this.$ele = div();
};
MyType.prototype.add_span = function(content){
   this.$ele.append(span({'class': this.class}, content));
}

var my = new MyType();
my.forEach(['ele1', 'ele2'], this.add_span);
my.$ele.html();
// <div>
//    <span class="my_class">ele1</span>
//    <span class="my_class">ele2</span>
// </div>
      
hoe.Type.map
Iterate through arrays or objects keeping the context to the current object. Returned values in iteration are used to create an array.
var MyType = hoe.Type(function(){
    this.class = 'my_class';
};
MyType.prototype.create_span = function(content){
   return span({'class': this.class}, content);
}

var my = new MyType();
var span_array = my.map(['ele1', 'ele2'], this.create_span);
div(span_array);
// <div>
//    <span class="my_class">ele1</span>
//    <span class="my_class">ele2</span>
// </div>
      

Event system

DOM events
hoe.Type.listen() can be used to bind DOM events keeping the object context.
my_obj.listen($ele, 'click', function(){alert(this.my_attr)});

// is the same as plain jQuery
$ele.bind('click', $.proxy(function(){alert(this.my_attr)}, my_obj));
      
object events
Objects can create their own events with hoe.Type.fire().
my.fire('my-custom-event-name', "argument1", {arg: 2});
      
  • the first argument is the event name
  • other arguments will be passed to any event callback

Other objects can register callbacks to handle events in a similar way it is done for DOM events, but the first argument is an object that generates events instead of a DOM element.

var my2 = new MyType();
my2.listen(my, 'my-custom-event-name', function(val){
     this.ele.append(val);
});