Bindux - Bind the User eXperience
Powerful and modern data binding (like Angular, Ember, ...) + templating + DOM manipulation (like jQuery, Zepto, jqLite, ...) in only 23kb minified (7kb gzipped).
Bindux in a few words:
- Near of native JS and HTML5 / CSS3.
- DOM manipulation (if you prefer, you can use Bindux with jQuery).
- Native data-binding, Bindux use
Object.observe()
, you can use a polyfill for old browsers. - Some useful helpers to manipulate the DOM, data-binding, values, HTML, ...
- Standart compliant, no need for <%=foo%> or {{foo}} assignments.
- Templating based on HTML, HTML is a great markup langage and natively evaluated by the browser.
- Not brilliant meta language, hieroglyphic or any other symbol to remember. Only HTML we already know.
- DSL-free (Domain Specific Languages), if needed you can use with any template engine.
- Note: DOM templating with Domain Specific Languages (suck as <%=foo%> or {{foo}}) is SLOW. All template engines require parsing and rendering phases.
- Easy to use
- Extensible
This is the alpha version, the documentation is in progress.
Install
Download dist/bindux.min.js.
Usage
Bindux expose the variables bindux
and a shortcut ux
.
// trueconsole;
bindux.noConflict()
to redefine in your sauce:
var ui = bindux; // now `ui` is `bindux` objectconsole; // now is undefinedconsole; // now is undefinedconsole;
DOM
Documentation in progress, the following is some quick examples:
ux; // or jQuery likevar $ = uxdom;;
Some methods:
var $ = uxdom;var elements = ; elements;elements;elementstext'some text';elements;elements;elements;elements;elements;elements;elements;elements;elementsparent;elements;elements;elements;elements;elements;elements;elements;elements; elements; // each nodeelements;
Traverse the tree of node
and keep only the text nodes:
var textNodes = $;
Observe DOM mutations and bind with the items
object:
var items = {}; $;
... and more, see the API in the code source.
Binders
TODO: doc
Binders are used to make the link between the JS code and the HTML document.
Like the AngularJS directives (ng-repeat, etc).
Each binding is linked by an attribute and an object (named the scope
).
All binding attributes are prefixed by n-
(n = node). You can change the prefix like this:
uxoptbinderprefix = 'ux-';
All scopes are stored in ux.scopes
object.
If a property passed from HTML to a binder is a function, then it will be executed and its return value will be used by the binder.
Init the binding with ux.init()
:
// define the controllers of your applicationuxctrlsheader = headerCtrl;uxctrlsnavBar = navBarCtrl;uxctrlschat = chatCtrl;uxctrlsarticle = articleCtrl;uxctrlsuser = userCtrl; // initialize the bindingux;
ctrl
The controller which manages the scope.
The use of controllers is not mandatory, you can define directly a scope ux.scopes.something
but the controllers are convenient for code organization.
When defining a controller, a scope of the same name is automatically created if it does not exist.
HTML
JS
/** * My controller * * @param * @param */uxctrls { };
each
Like ng-repeat
of AngularJS, the binder each
instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item.
HTML
If you prefer the Angular way (message in
messages):
JS
scopemessages = ; scopemessages;scopemessages;
It's also possible to use an object or an array of objects.
Example with an array
of object
:
HTML
JS
scopeusers = ; scopeusers; scopeusers;
el
Handles directly an element.
HTML
JS
scopelogoUrl = '/assets/img/logo.png';
Use only a callback which manages the element:
HTML
JS
scope { // current element var node = datanode; console;};
html
Add the property value performed as HTML.
HTML
JS
scopecontents = '<strong>Hello world</strong>';
Displays:
Hello world
text
Add the property value performed as text. The HTML tags are natively escaped by the browser (TextNode).
HTML
JS
scopecontents = '<strong>Hello world</strong>';
Displays:
<strong>Hello world</strong>
on
Binds an event listener on the element using the event specified.
Attribute value: event:listener
.
HTML
Click me!
JS
scope { text'clicked :)';};
scope
Define the scope to bind in the HTML. It's useful to bind another scope easily.
HTML
<!-- Without controller --> <!-- Uses the scope "b" -->
Filters
Transform a value. Example, HELLO to Hello:
JS
scopeval = 'HELLO';
HTML
List:
- lc Make a string lowercase
- lcFirst Make a string's first character lowercase
- uc Make a string uppercase
- lcFirst Make a string's first character uppercase
- rmSpace Remove space
- escape Escape a string (replace HTML tags and some character by HTML entities)
- e Shortcut of escape filter
- unescape Converts the HTML entities in escaped string (with escape / e filter), to their corresponding characters
Create a new filter:
uxfilters { return '<strong>' + str + '</strong>';};
Then use:
Parser
Parsing:
var value = uxexpr;
Note: expression
is passed to all parsers (by default Bindux have only one parser pipe
).
use a specific parser:
var value = uxexpr;
Create a new parser:
uxexprparsers { // parse ... return str;};
Note: context
is an optional argument to pass context data.
Then use:
var value = uxexpr;
When calling ux.expr.parse()
, all parsers are used (also the new parser something
).
If needed, you can pass the context
:
var value = uxexpr;
events
Bindux inherits of evemit.
ux; ux;
Methods:
- ux.on(event, fn, [context])
- ux.once(event, fn, [context])
- ux.emit(event, [...arg])
- ux.off(event, fn)
- ux.listeners([event])
See the doc of Evemit.
Internal events
preLoad
Emitted by ux.init()
on preloading.
load
Emitted by ux.init()
on loading.
postLoad
Emitted by ux.init()
on postloading.
scopes.{scope name}.changes
Emitted when a scope object was changed.
Example a scope defined with ux.scopes.user
emit scopes.user.changes
.
ctrls.{controller name}.preLoaded
Emitted on preloading of a controller.
Example a controller defined with ux.ctrls.user
emit ctrls.user.preLoad
.
ctrls.{controller name}.preBoot
Emitted on prebooting of a controller.
ctrls.{controller name}.postBoot
Emitted on postbooting of a controller.
binders.each.scopes.{scope name}.{property name}.changes
Emitted by ux.binders.each
when a property (or an array
key) of a scope was changed.
Example, consider a scope named app
(ux.scopes.app
):
Scope object:
// if this code is in a controller,// `scope` variable is passed by argumentvar scope = uxscopesapp; scopeusers = nico: job: 'developer' age: '32' country: 'France' avatar: '/img/avatars/default.png' ;
Binder:
When scope.users
changes:
scopeusersnicoavatar = '/img/avatars/tux.png';
The event emitted is binders.each.scopes.app.users.changes
ux.color
In a application it is common to manipulate the colors via hexa and RGB(A).
The ux.color
object is an handy helper to facilitate the transition from one to the other.
toRgb(color, alpha)
Convert a given color
to RGB(A).
// rgb(255,255,255)uxcolor; // rgb(255,255,255)uxcolor; // rgb(255,255,255)uxcolor; // rgb(255,255,255)uxcolor; // rgb(255,255,255,0.8)uxcolor
toHex(color)
Convert a given color
to Hexa.
// #ffffffuxcolor; // #ffffffuxcolor; // #ffffffuxcolor; // #ffffffuxcolor; // #ffffffuxcolor;
names
Some color names.
// #008000console; // see all colorsconsole;
ux.html
getFirstTag(str)
Get the first HTML tag.
Returns the tag (lowercase) if found, null
otherwise.
var attr str; str = 'some text before <div id="layout" class="active">' + '<span class="something">contents</span>' + '</div> some text after'; attr = uxhtml; // divconsole;
getAttrs(str)
Get attributes from a string. Returns attribute(s) name=value pairs in object.
var attrs str; str = '<div id="layout" class="active">' + '<span class="something">contents</span>' + '</div>'; attrs = uxhtml; // Object {id: "layout", class: "active"}console;
toNode(str)
Convert a given string / HTML to Node
instance (Element
or TextNode
).
var node; // TextNode// (node.nodeType === Node.TEXT_NODE)node = uxhtml; console; // Element (strong)// (node.nodeType === Node.ELEMENT_NODE)// (node.nodeName === 'STRONG')node = uxhtml; console;
stripTags(str, allowed)
Returns the string (str
) without HTML tag, or only with allowed
tag(s).
Remove all tags:
// Who are youuxhtml;
Remove all tags except <i>
and <b>
:
// Who <b>are</b> <i>you</i>uxhtml;
Browser support
Bindux is near of the native features and standart compliant. Bindux is based on the native capabilities of standarts supported by the major modern browsers: Chrome 29+, Firefox 24+, Opera 24+, IE 11+, Safari 6.1+ and browsers based on its.
No hack imposed to the modern browsers, so it's very well for the performance. The hacks are only necessary for the old browsers and should be handled independently.
For make that the old browsers support the modern features you can use polyfills:
- es5-shim, provides ES5 (EcmaScript 5)
- DOM4, provides DOM4 spec
- es6-collections, provides WeakMap, Map and Set
Development of Bindux core
Bindux is developped in ES6 (EcmaScript6) in src directory and is compiled to ES5 in the dist/bindux.min.js.
Build a minified distributable, in the terminal:
gulp
Develop with the automatic rebuilds (the distribulable and the unit tests):
gulp dev
Unit tests
Bindux is unit tested with Unit.js and Mocha.
TODO: There are still things to test.
LICENSE
MIT (c) 2014, Nicolas Tallefourtane.
Author
Bindux is designed and built with love by
Nicolas Talle |