MVC or not MVC? The Formation Engine for jQuery

Various JavaScript frameworks provide data binding facilities (Knockout, AngularJS, etc.) these days.

They are based on kind-of-MVC concept: you have some data (structure, model), view rendering that data in html and some code in between that commonly named as controllers.

How successful/convenient those frameworks are subject of separate topic. For me they are too intrusive I would say. On some views/pages they make sense, on others final solution looks too ugly.

Anyway, here is an alternative idea…

Instead of separating data structure and its view we simply can create construction that is a data model and its view at the same time 🙂

I named that magic “construction” as Formation. Formation is essentially a collection of DOM elements organized in a tree that reproduces structure of the data (or model if you wish). Value of the formation is JSON data structure – the model per se.

Consider this example

Here you see collection of inputs and subsections (on the top).
On the bottom/right corner you see the Formation tree created of <section#inputs> container.

On the left you see live data of the Formation (editable textarea). Changes there reflect state of elements. In the same way changes in inputs reflect text in this textarea.

The Formation implementation does two major things:

  • creates formation trees and
  • initializes custom DOM elements (check that in HTML source – that friends list).

Couple of words about custom elements support in formations:

When formation sees custom DOM element ( any DOM element with tag name containing ‘-‘ inside ) it tries to find its initializer in registry of jQuery plugins – that famous $.fn collection. And calls it if it was found. You can check js/jquery.list-input.js – it is normal jQuery plugin with the name matching that custom element tag name: “INPUT-LIST”.

To create/get formation of some container you can call either

  1. global [window.] formation( domel_or_$_wrapper ) function or
  2. $(selector).formation() plugin.

You can store created formation in some variable and access DOM elements in it in quite effective manner:

var inputs = $("section#inputs").formation();
$(inputs.firstName).on("change", function() {...});

Accessing formation members directly is faster than accessing them using jQuery selectors as these are just direct references.

You can download complete sample to play with from here.

Future Formation plans: to implement so called repeatable formations, so if you have this markup:

<ul repeatable name="stockItems">
   <li><output name="name">  <output name="price" type="currency"></li>
</ul>

and will feed it (through formation) by this data:

[
  {name:"Apple", price: 1.05 },
  {name:"Orange", price: 0.52 } 
]

it will render two <li>s in the list.

Another ng-inspired idea is to have class switches as Formation elements, this class declaration:

<div class="{someSwitch:collapsed|expanded}" >...</div>

will cause corresponding formation to have element named “someSwitch” that can be assigned false/true or 0|1 values to change class to either <div class=”collapsed”> or to <div class=”expanded”>…

UPDATE: see discussion about the Formation on jQuery forum : forum.jquery.com/topic/mvc-or-not-mvc-the-formation-engine

Sciter HTML parsing flavour

HTML parser in Sciter v.3 supports attribute shortcuts allowing to write HTML in more compact form. Compare these two declarations that are identical (to the Sciter):

Compact:

 
  <input|currency(itemPrice) value=1000> 

and standard:

 
  <input type="currency" name="itemPrice" value=1000> 

As you see the first one is slightly shorter and better readable (subjective of course).

Here is full list of supported attribute shortcuts:

  • #nameid, attribute name that starts from ‘#’ is parsed as id=”name”
  • .nameclass, this is an equivalent of class="name". Element may have multiple “dot attributes”. All of them are combined into single class attribute. So this <div.container.collapsed> is treated as this: <div class=”container collapsed”>
  • |nametype, attribute name that starts from ‘|’ is parsed as type="name"
  • (someName)name, attribute name enclosed into ‘(‘ and ‘)’ is parsed as name="someName"

Just in case 🙂

Sciter 3

Sciter 3 is officially out.

See its log file.

  • On Windows Vista/7 it uses Direct2D backend
  • On Windows XP it uses GDI+ backend

Known issue on Windows XP: rendering of linear and radial gradients is different from Direct2D backend as GDI+ has no notion of “open gradients”. I’ll fix it a bit later.

You shall expect that GDI+ rendering is not that effective as rendering by Direct2D so avoid animations affecting large areas. These two media rules allow to target different backends used:

 
  @media graphics-layer == 1 {
    /* GDI+ rules here.
       Less animation, etc. */
  }
  @media graphics-layer == 2 {
    /* Direct2D in WARP mode (software rendering but fast enough)        
     */
  }
  @media graphics-layer >= 3 {
    /* Direct2D in hardware mode, max performance. */
  }

But most of the time it is enough to have just two sections:

 
  @media graphics-layer == 1 {
    /* GDI+ rules here.
       Less animation, etc. */
  }
  @media graphics-layer > 1 {
    /* Direct2D, high performance. */
  }

In script you can check gfx backend used by reading view.backend (:integer) property.