Welcome to OJ.
OJ(S) (OJ.js || OpenJS || Orange Julius || whatever you like) is a framework upon which to build web applications in pure (sometimes functional)
OJ is packaged for Node and Bower. Other options abound.
bower install --save ojs
- From NPM last stable
npm install --save ojs
- Clone from Git
git clone firstname.lastname@example.org:somecallmechief/oj.git
OJ is written in CoffeeScript. The distribution folder has the complete CS and JS for the project.
gulp compile task.
Once compiled, feel free to use OJ in either flavor.
While OJ probably doesn't have a lot of utility in the context of Node, I have made an effort to keep it Node-compatible--although there is absolutely no testing to this effect.
At its heart, OJ provides a simple API to build out the DOM:
div = OJ.body.make 'div', text: "Aloha! Ahoy! Hola! Prevet!" cell11 = div.make 'table' .cell 1, 1, text: 'Ahoy, column 1, row 1!' .cell 2, 1, text: 'Aloha, column 1, row 2!' span = cell11.make 'span', text: 'Aloha! Ahoy! Hola! Prevet!'
Nearly all standard nodes are accessible via chaining, starting with the body element. Every OJ node is chainable against the entire set of compatible child nodes. For example:
div = OJ.body.make 'div' select = div.make 'select' .make 'button' #not terribly rational, but valid semantic .make 'option' #more reasonable chained method fieldSet = div.make 'fieldset' .make 'legend' ol = div.make 'ol' .make 'span' #not a great idea, but entirely possible .make 'li' #preferable child node .make 'div' #another valid child of li .make 'ul' #valid child of div .make 'p' #suboptimal but valid .make 'li' #valid child of li
In most cases, the
make method is your start and end point for chaining node creation. In a few cases, specific classes such as
table provide an additional convenience
method or two to make chaining simpler:
table = OJ.body.make 'table' #returns an instance of table table.cell 1, 1, text: 'Ahoy, column 1, row 1!' #the table.cell method provides a simple abstraction over table.make 'tr' and table.make 'td' table.make 'tr' #Still valid, creates a new row .make 'td' #Still valid, creates a new cell
The element table class provides a unique
cell method which takes in the ordinal position of the cell (row, column) and guarantees that the cell you want is in the correct location.
Further, it guarantees that the table is fully populated.
table = OJ.body.make 'table' #returns an instance of table table.cell 14, 7, text: 'Ahoy, column 7, row 14!' #cell() guarantees that rows 1-13 are created and that each row has at least 7 columns (filled with non-breaking whitespace if absent) table.cell 14, 12, text: 'Ahoy, column 12, row 14' #cell() now guarantees that all existing rows also have 14 columns (filled with non-breaking whitespace if absent)
Likewise, the component grid class provides a unique
tile method which accomplishes the same effect for Bootstrap grids as
table.cell does for tables.
grid = OJ.body.make 'grid' #returns an instance of grid grid.tile 2, 1, widths: xs: 12, sm: 6, md: 4 #Guarantees that at least 2 Bootstrap rows exist, each with 1 column
This simple semantic makes it possible to build more complex web components, which are encapsulated as OJ classes.
div.make 'grid' #creates a Bootstrap grid .tile 1, 1 #creates row 1, column 1 .make 'grid' #creates a nested grid on previous tile .tile 1, 1 #creates nested row, nested column
Components are currently a work in progress, but several functional components include jQuery Sparkline, jQuery Flotchart, and Bootstrap grids.
In order for OJ to scale, it has to be fast. By far, the fastest way to insert nodes into the DOM is by calling
someElement.appendChild. Unfortunately, this is a tedious process to do manually. Rather than revert to anti-patterns like setting innerHTML, OJ leverages the speed of ThinDOM for light, fast, semantically accurate DOM insertion. This does come at a slight cost, but ThinDOM outperforms jQuery insertions by at least an order of magnitude--so it's a logical choice for the core of OJ's DOM manipulation.
While ThinDOM may be the fastest choice for getting your nodes into the DOM, it doesn't offer the cross-browser support and flexibility of jQuery's API--so for everything else you need to do to your nodes, OJ wraps around jQuery to provide access to all of the
on that you might need.
By default, OJ does not add element IDs to any of the nodes it creates. This is configurable. If desired, enable element ID creation by setting:
OJ['GENERATE_UNIQUE_IDS'] = true
If enabled, OJ will generate unique element IDs for every node created. Any element ID is accessible via the
divId = div.getId()
You are always