ui-bind reference: every command, option and attribute
<ui-bind> is the element that applies commands to the DOM when the value of its path changes. This page lists what each command does, the options that decide when it runs and the attributes that choose which element it changes.
The format is config="command:expression;command:expression". In an expression value is the value of the path and element (also el) is the element that is changed. A command can have a selector (text .name:value applies it to the elements .name inside) and attr takes the attribute name first (attr title:value).
Commands that change the element
| Command | What it does |
|---|---|
text:expr | sets the text; an empty value shows the empty text |
html:expr | sets the inner HTML (escape it yourself) |
value:expr | sets the value of a form control |
title:expr, href:expr, src:expr | sets that attribute |
attr name:expr | sets any attribute |
.class:expr | adds the class when the expression is true and removes it when false |
show:expr / hide:expr | adds or removes the class hidden |
visible:expr / invisible:expr | adds or removes the class invisible (the element keeps its space) |
checked:expr | checks or unchecks the input inside |
disabled:expr / enabled:expr | disables or enables the controls inside (input, select, textarea, button) and the ui-component elements inside |
required:expr | sets the required option of the ui-component elements inside (it does not touch a plain input) |
template | renders the Tangular template of the element (see the template recipe) |
exec:path / refresh:path | calls the function at that path with the value, the path and the element, for every SET of the path of the binder |
show and hide run first, then visible and invisible, and text, html and template run last, so that the visibility of the element is already known when the content is written. text, html and template are only written while the element is visible, unless forcerender:true is in the same config: then they are written even when the element is hidden.
Options: when the commands run
| Option | What it does | |
|---|---|---|
changes | skips the update when the value is the same as the last one | |
strict | only runs when the path of the binder itself changed, not when a child path changed (user.name does not run a binder of user) | |
track:a,b | only runs when one of those paths changed (a binder of user that tracks user.name ignores user.age); it runs again for every SET of a tracked path, even with the same value | |
once | runs once and then the binder is removed | |
check:path | calls the function at that path with (value, path, element); the commands only run when it returns true | |
delay:ms | waits that many milliseconds and renders once, even if the value changed several times meanwhile (100 when no value is given) | |
empty:text | the text shown instead of an empty value (--- when no text is given) | |
format:pattern | formats the value of text, html, value, attr, title, href and src with String.format | |
class:name | adds that class to the ui-bind element once, after the first render | |
assign:path | stores the binder instance at that path | |
helpers:path | the object at that path provides the helpers of the template: with helpers:hh and hh = { shout: fn }, the template can use {{ value | shout() }} |
Attributes: which element changes
By default the commands change the ui-bind element. These attributes pick another one:
element="#target"any element of the page (a jQuery selector)child=".inner"an element inside theui-bindparent=".card"the closest ancestor that matches
The path can start with ! (path="!user.nick"): the binder then ignores the moments when the value is null or undefined. A command name can also start with ! or ~: the prefix is accepted and ignored, the command works as without it.
Attribute commands
- Use one attribute per command: write
title:valueandalt:valueas two commands.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jComponent</title>
<link rel="stylesheet" href="//cdn.componentator.com/spa.min@20.css" />
<script src="//cdn.componentator.com/spa.min@20.js"></script>
</head>
<body>
<ui-bind path="user.age" config="visible:value > 17" id="visible"><span>adult</span></ui-bind>
<ui-bind path="user.age" config="invisible:value > 17" id="invisible"><span>minor</span></ui-bind>
<ui-bind path="user.name" config="text:value;class:marked" id="classonce"></ui-bind>
<ui-bind path="user.name" config="text:(window.counter_changes = (window.counter_changes || 0) + 1) && value;changes" id="changes"></ui-bind>
<ui-bind path="user" config="text:(window.counter_strict = (window.counter_strict || 0) + 1);strict" id="strict"></ui-bind>
<ui-bind path="user" config="text:value.name;track:user.name" id="track"></ui-bind>
<ui-bind path="user.name" config="text:value;once" id="once"></ui-bind>
<ui-bind path="user.name" config="text:value;check:isready" id="check"></ui-bind>
<ui-bind path="user.name" config="exec:onname" id="exec"></ui-bind>
<ui-bind path="user.name" config="text:value;assign:binders.main" id="assign"></ui-bind>
<ui-bind path="!user.nick" config="text:value" id="notnull"></ui-bind>
<ui-bind path="user.name" config="text:value" element="#target" id="element"></ui-bind>
<div id="target"></div>
<ui-bind path="user.name" config="text:value" child=".inner" id="child"><b class="inner"></b></ui-bind>
<ui-bind path="user.name" config="text .a:value;text .b:value.toUpperCase()" id="selector"><i class="a"></i><i class="b"></i></ui-bind>
<ui-bind path="user.name" config="show:false;text:value;forcerender:true" id="force"></ui-bind>
<ui-bind path="user.name" config="show:false;text:value" id="noforce"></ui-bind>
<ui-bind path="user.admin" config="required:value;disabled:!value" id="flags"><input type="text" /></ui-bind>
<ui-bind path="user.admin" config="checked:value" id="checked"><input type="checkbox" /></ui-bind>
<ui-bind path="user.name" config="title+alt:value" id="clone"></ui-bind>
<ui-bind path="user" config="text:(window.counter_track = (window.counter_track || 0) + 1);track:user.name" id="track2"></ui-bind>
<ui-bind path="user.name" config="template;helpers:hh" id="helpers"><script type="text/html"><b>{{ value | shout() }}</b></script></ui-bind>
<ui-bind path="user.none" config="text:value;empty" id="emptydef"></ui-bind>
<ui-bind path="user.name" config="focus"><input type="text" id="f1" /></ui-bind>
<ui-bind path="user.name" config="!text:value" id="bang"></ui-bind>
<ui-bind path="user.name" config="~text:value" id="tilde"></ui-bind>
<ui-bind path="user.name" config="text:el.attr('id') + '/' + element.attr('id')" id="elvar"></ui-bind>
<div class="card"><ui-bind path="user.name" config="attr data-n:value" parent=".card" id="parentbind"></ui-bind></div>
<script>
window.hh = { shout: s => String(s).toUpperCase() };
window.isready = function(value, path, element) {
return value !== 'blocked';
};
window.exec_log = [];
window.onname = function() {
window.exec_log.push(Array.prototype.slice.call(arguments).map(a => typeof a === 'object' ? (a && a.nodeType ? 'element' : a && a.path ? 'path' : 'object') : String(a)).join('|'));
};
SET('user', { name: 'Ann', age: 30, admin: false });
</script>
</body>
</html>Edit the example and run it. It runs in an isolated frame in your browser; nothing is sent to our server.
Preview