ForgejComponent
en

jComponent

ui-bind reference: every command, option and attribute

jComponent 20 · jcomponent@20 jcomponentfrontendbindingreference Executed with jComponent 20

<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

CommandWhat it does
text:exprsets the text; an empty value shows the empty text
html:exprsets the inner HTML (escape it yourself)
value:exprsets the value of a form control
title:expr, href:expr, src:exprsets that attribute
attr name:exprsets any attribute
.class:expradds the class when the expression is true and removes it when false
show:expr / hide:expradds or removes the class hidden
visible:expr / invisible:expradds or removes the class invisible (the element keeps its space)
checked:exprchecks or unchecks the input inside
disabled:expr / enabled:exprdisables or enables the controls inside (input, select, textarea, button) and the ui-component elements inside
required:exprsets the required option of the ui-component elements inside (it does not touch a plain input)
templaterenders the Tangular template of the element (see the template recipe)
exec:path / refresh:pathcalls 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

OptionWhat it does
changesskips the update when the value is the same as the last one
strictonly 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,bonly 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
onceruns once and then the binder is removed
check:pathcalls the function at that path with (value, path, element); the commands only run when it returns true
delay:mswaits that many milliseconds and renders once, even if the value changed several times meanwhile (100 when no value is given)
empty:textthe text shown instead of an empty value (--- when no text is given)
format:patternformats the value of text, html, value, attr, title, href and src with String.format
class:nameadds that class to the ui-bind element once, after the first render
assign:pathstores the binder instance at that path
helpers:paththe object at that path provides the helpers of the template: with helpers:hh and hh = { shout: fn }, the template can use {{ valueshout() }}

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 the ui-bind
  • parent=".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:value and alt:value as two commands.
public/index.html
<!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>
Try it in your browser

Edit the example and run it. It runs in an isolated frame in your browser; nothing is sent to our server.

Preview