Data-Binding is a special feature in jComponent. It can affect DOM element dynamically.
Topics:
Declaration:
<div data-bind="path.to.property__command1:exp__command2:exp__commandN:exp"></div>
attrchangescheckedclassclickconfigcurrencydefdelaydisabledemptyenabledexecfocusformathidehrefhtmlinitimportinvisiblerefreshresizerequiredsetsettershowsrcstricttemplatetexttitletracktracktypevalvbindarrayvisible.class_nameattr+v18 command sets a value into the custom attribute:
<div data-bind="some.path__attr data-id"></div>
<div data-bind="some.path__attr data-id:value"></div>
<!-- With nested selector: -->
<div data-bind="some.path__attr data-id b:value"></div>
changes+v18 command performs all other commands only if the value will be changed. It works with object types too.
<div data-bind="some.path__changes__html"></div>
checkedSets the checked attribute. Targeted for HTML controls only input. Expression must return Boolean.
<input data-bind="some.path__checked:value" />
classToggles specified class when the data-bind is processed. Epression must be String only. Supports multiple classes seperated by empty space.
<div data-bind="some.path__class:hidden" class="hidden">READY</div>
<!-- Or multiple classes: -->
<div data-bind="some.path__class:hidden ready" class="hidden">READY</div>
click+v17 Executes method when the user clicks on the element.
<div data-bind="some.path__click:link_to_method"></div>
<!-- OR WITHOUT PATH -->
<div data-bind="null__click:link_to_method"></div>
<!-- Replaces ? for a SCOPE PATH -->
<div data-bind="null__click:?/link_to_method"></div>
<script>
function link_to_method(element, event, value, path) {
// do something
}
</script>
configPerforms reconfiguration for the current jComponent. Expression must return String with jComponent configuration or can return Object.
<div data-bind="some.path__config:'required:' + (value === true)" data---="textbox">My textbox</div>
<!-- Sets "required" for all nested jComponents -->
<div data-bind="some.path__config [data-jc]:'required:' + (value === true)">
<div data---="textbox"></div>
<div data---="dropdown"></div>
etc..
</div>
currency+v18 Renders formatted currency. A value in currency command is a currency, it's not evaluated and can be used [value_from_ENV].
<div data-bind="some.path.to.number__currency:eur__html"></div>
Additional example with a dynamic currency:
<div data-bind="some.path__html:value.price.currency(value.currency)__track:price,currency"></div>
defSets the def attribute. It's targeted for HTML controls only input, textarea, select and button.
String:
<div data-bind="some.path__def:'String'__html:JSON.strignify(value)"></div>
Number:
<div data-bind="some.path__def:100__html:JSON.strignify(value)"></div>
Boolean:
<div data-bind="some.path__def:true__html:JSON.strignify(value)"></div>
Object:
<div data-bind="some.path__def:{}__html:JSON.strignify(value)"></div>
Array:
<div data-bind="some.path__def:[]__html:JSON.strignify(value)"></div>
delayDelays a binding for 2 seconds. Must be a number which represents milliseconds.
<input data-bind="some.path__val:value__delay:2000" />
disabledSets the disabled attribute. It's targeted for HTML controls only input, textarea, select and button. Expression must return Boolean.
+v17 extends disabled command for components. Now the library can perform reconfigure with disabled:true/false command.
<input data-bind="some.path__disabled:value" />
empty+v17 Sets an empty HTML to the current element when is the value null or undefined or empty string.
<div data-bind="some.path__empty:---"></div>
enabled+v16 Sets the enabled attribute. It's targeted for HTML controls only input, textarea, select and button. Expression must return Boolean.
+v17 extends enabled command for components. Now the library can perform reconfigure with disabled:true/false command.
<input data-bind="some.path__enabled:value" />
execExpression must be a link to a function. This function will be executed if the data-bind path will be changed.
<div data-bind="some.path__exec:myfunction"></div>
<script>
function myfunction(value, path, element) {
console.log('VALUE HAS BEEN CHANGED:', value);
}
</script>
focus+v18 supports focus command which can contain a jQuery selector which will perform .focus(). Example:
<div data-bind="some.path__focus:input">
<input type="text" value="Focused!" />
</div>
format+v17 enables a specific format for Date or Number types.
<div data-bind="some.path.date__html__format:dd.MM.yyyy"></div>
// Or link to environment variable
<div data-bind="some.path.date__html__format:[date]"></div>
// +v17 supports path to value in the form of environment variables
<div data-bind="some.path.date__html__format:[.path.to.property]"></div>
hideToggles hidden class. Expression must return Boolean.
<div data-bind="some.path__hide:value"></div>
<div data-bind="some.path__hide:value !== 'users'"></div>
hrefSets href attribute. It's targeted for links <a> only. Expression must return String.
<div data-bind="some.path__href:value"></div>
htmlSets the value as the HTML content. Expression must return String.
<div data-bind="some.path__html:value"></div>
<div data-bind="some.path__html:value.toUpperCase()"></div>
init+v17 Executes method when the binder is initialized. This command is performed only one time.
<div data-bind="some.path__init:link_to_method"></div>
<script>
function link_to_method(value, path, element) {
// do something
}
</script>
importPerforms IMPORT(). Expression must be URL address String or (+v16) value must return a valid URL adress.
This command imports each resource only one time.
<div data-bind="some.path__import:https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></div>
<div data-bind="some.path__import:value"></div>
+v18 adds a support for <script type="text/html">:
<div data-bind="some.path__show__import:true">
<script type="text/html">
The content will be evaluated when the element will be visible.
</script>
</div>
+v18 supports ENV
<script>
ENV('mycdn', 'https://totaljs.com');
</script>
<div data-bind="some.path__import:[mycdn]/js/app.js"></div>
invisible+v16 sets invisible class to this element if the condition is valid. invisible class is a part of spa.min.css and it's declaration is .invisible { visibility: hidden; }. Usage:
<div data-bind="some.path__invisible:value == true"></div>
refresh+v18 Expression must be a link to a function. This function will be executed if the element is visible and the data-bind path will be changed.
<div data-bind="some.path__refresh:myfunction"></div>
<script>
function myfunction(value, path, element) {
console.log('VALUE OF VISIBLE ELEMENT HAS BEEN CHANGED:', value);
}
</script>
resize+v18 executes resize method in all nested components. IMPORTANT: the element must visible.
required+v18 performs required reconfiguration for the current element component. It expects boolean value type.
<div data---="input__?.company" data-bind="?.iscompany__required">Company name</div>
set+v18 can set a value to a component. It will works with vbindarray too, but only in readonly mode.
. dot in component's path allows to bind a value from data-bindset command is very important for binding<div data-bind="some.path__set" data---="textbox__.__required:1"></div>
OR
<div data-bind="some.path__set:value.toUpperCase()" data---="textbox__.__required:1"></div>
setter+v16 performs element.SETTER() for nested components.
<div data-bind="some.path__setter:'datagrid','resize'"></div>
<!-- performs: element.SETTER('datagrid', 'resize') -->
<div data-bind="some.path__setter:true,'datagrid','resize'"></div>
<!-- performs: element.SETTER(true, 'datagrid', 'resize') -->
showToggles hidden class. Expression must return Boolean.
<div data-bind="some.path__show:value"></div>
<div data-bind="some.path__show:value === 'users'"></div>
srcSets src attribute, targeted for <img. Expression must return String.
<div data-bind="some.path__src:value"></div>
strictThis command performs a strict comparing of path. Must be without expression.
<div data-bind="myobj.address__strict__html:JSON.stringify(value)"></div>
myobj or myobj.addressmyobj.customer or something else doesn't affect this bindertemplateCompiles HTML content as a Tangular template. Can be defined without expression. +v17 expression can contain a jQuery selector which enables Virtual DOM comparing for content.
<div data-bind="some.path__template">
<script type="text/html">
<div>{{ value.name }}</div>
<div>{{ value.price | format(2) }}</div>
</script>
</div>
<!-- +v17 With Virtual DOM differ -->
<div data-bind="some.path__template:.product">
<script type="text/html">
<div class="product">
<div>{{ value.name }}</div>
<div>{{ value.price | format(2) }}</div>
</div>
</script>
</div>
<!-- +v18 With custom template -->
<div data-bind="some.path__template:{jQuery selector}"></div>
<!-- +v18 With custom template and virutal dom -->
<div data-bind="some.path__template:.product {jQuery selector}"></div>
value represents Tangular modelVirtual DOM: Template is compiled to Virtual DOM and then it's compared with current DOM. This feature can improve rendering (blinking) when the content is re-rendering.
textSets a value as the TEXT content (HTML markup will be escaped). Expression must return String.
<div data-bind="some.path__text:value"></div>
<div data-bind="some.path__text:value.toUpperCase()"></div>
titleSets title attribute.
<div data-bind="some.path__title:value"></div>
trackEnables a strict path comparison for defined paths separated by comma (use a field name without parent path). Binder will render the content below if the main path object will be changed or specific field (name or price) will be changed.
<div data-bind="some.path__template__track:name,price">
<script type="text/html">
<h1>{{ value.name }}</h1>
<div>Price: {{ value.price | format(2) }} EUR</div>
</script>
</div>
tracktypeTracks only changes according to defined SET() types. A value can contain multiple values separated by comma.
<div data-bind="some.path__html__tracktype:2"></div>
<script>
// Will be binded
SET('some.path', 'Value', 2);
// Won't be binded
SET('some.path', 'Value', 1);
</script>
Internal types:
0 init value1 manually via e.g. SET()2 by input3 default valuevalSets value for the input/textarea/select. Expression must return String.
<input data-bind="some.path__val:value" />
vbindarray+v17 This is very special command. It has same functionality like template but the <script type="text/html" must contain VBINDARRAY template. Read more about VBINDARRAY here.
<div data-bind="some.path.to.array__vbindarray">
<script type="text/html">
<div data-bind=".name__html b">Name: <b></b></div>
<p data-bind=".description__html"></p>
</script>
</div>
visible+v16 sets invisible class to this element if the condition is not valid. invisible class is a part of spa.min.css and it's declaration is .invisible { visibility: hidden; }. Usage:
<div data-bind="some.path__visible:value !== false"></div>
.class_nameToggles .class_name if the expression returns true. You can use multiple .class_name commands.
<div data-bind="some.path__.animate:value > 100"></div>
Multiple:
<div data-bind="some.path__.animate1:value > 100__.animate2:value > 1000"></div>
You can use multiple types of command expressions. You need to choose what suits is for you. In most cases value argument contains the real value from a model according to the data-bind path. IMPORTANT: click command uses other order of arguments.
Arrow function in the form:
COMMAND:(value,path,jQueryElement)=>value.toUpperCase()
<or>
COMMAND:n=>n.toUpperCase()
Direct value:
COMMAND:value.toUpperCase()
<or>
COMMAND:value
<or>
COMMAND:value > 10
Link to method:
COMMAND:upper_value
function upper_value(value, path, element) must be defined in the window scope+v16 Most of commands are performend when the element is visible --> in other words: the command show must return true or hide must return false.
If you want to evaluate a command for hidden element then you can extend command by adding ~ before the name of command, for example:
<div data-bind="some.path__~setter:'datagrid','resize'">
...
</div>
You can link commands to same expression with help of + char with spaces on both sides.
<div data-bind="path.to.property__COMMAND + COMMAND + COMMAND:VALUE"></div>
<div data-bind="user.age__visible + .selected:age => age > 18__html:value"></div>
You can extend most of commands by adding a custom jQuery selector.
Declaration:
<div data-bind="some.path__html JQUERY_SELECTOR:value"></div>
Usage:
<div data-bind="some.path__html h1:value__show:value">
<h1></h1>
</div>
Nullable / Undefined values can be handled easily. Just use !COMMAND and evaluating will be performed if the value won't be null or undefined.
<div data-bind="user.name__!html:value.toUpperCase()"></div>
You can define multiple data-bind paths in the same HTML element. Paths must be divided by this | phrase. For example:
<div data-bind="path.to.property1__command:expression__|__path.to.property2__command:expression__|__path.to.property3__command:expression"></div>
You can use data-bind in jComponent scopes, but you need to defined ? (question mark) on the start of data-bind path. Question mark ? will be replaced for a scope path.
<div data-bind="?.property__html:value"></div>
+v17 supports scope in command values:
<div data-bind="?.property__html:?/render"></div>
<!-- WILL BE COMPILED TO -->
<div data-bind="SCOPEPATH.property__html:SCOPEPATH/render"></div>
Good to know:
Data-Binding supports inline helpers:
1. Direct assignment
<div data-bind="form.name --> (value || '').toUpperCase()__html:value"></div>
2. With arrow function
<div data-bind="form.name --> n => (n || '').toUpperCase()__html:value"></div>
3. Plugins
<div data-bind="form.name --> plugin/method(value)__html:value"></div>
The example below will work in component's scope only.
Binds a value according to the data-jc-path attribute.
It works in the component scope only.
<div data-bind="@__COMMAND + COMMAND + COMMAND:VALUE"></div>
Binds a component config.
It works in component scope only.
<div data-bind="@config__COMMAND + COMMAND + COMMAND:VALUE"></div>
Binds a value defined via component.data('property', value).
It works in the component scope only.
<div data-bind="@property__COMMAND + COMMAND + COMMAND:VALUE"></div>
+v17 supports private binding methods:
<div data-bind="@__html:@method_in_component"></div>
+v17 supports shorter commands:
<div data-bind="property__show"></div>
<!-- IS SAME AS -->
<div data-bind="property__show:value"></div>
<div data-bind="property__html"></div>
<!-- IS SAME AS -->
<div data-bind="property__html:value"></div>
<div data-bind="property__html__show"></div>
<!-- IS SAME AS -->
<div data-bind="property__html:value__show:value"></div>
+v17 supports disabling of data binding:
<div id="myelement" data-bind="property__html:value"></div>
<script>
$('#myelement').binder().disabled = true;
</script>
+v17 supports refreshing of data-bind. It can be helpful for specific components and behaviours.
<div id="myelement" data-bind="property__html:value"></div>
<script>
$('#myelement').binder().refresh();
</script>
+v16 supports this method. Virtual binder VBIND is a special thing and it can bind data from a custom model which doesn't need to be defined in the window scop. Compiled element doesn't need to be a part of DOM.
.path// VBIND(template);
var obj = VBIND('<div data-bind=".name__html:value"></div>');
// Sets a model
obj.set({ name: 'Peter' });
// Sets a specific value with path
obj.set('name', 'Peter');
// +v18 Updates a specific path
obj.upd(path);
// +v18 Updates entire object
obj.upd();
// Removes the binder
obj.remove();
// jQuery element
obj.element.html(); // <div>PETER</div>
// Attachs element into the DOM
$(document.body).append(obj.element);
+v17 supports private binding methods:
var obj = VBIND('<div data-bind=".name__html:.mymethod"></div>');
obj.mymethod = function(value, path, el) {
// this === jQuery element
return 'VALUE_FOR_COMMAND';
};
// Sets a model
obj.set({ name: 'Peter' });
VBIND instance from elementvar vbind = element.vbind();
vbind.set(YOUR_OBJECT);
+v16 supports this method. VBINDARRAY prepares a template as VBIND object and it renders items/templates very effective according to the array. It's someting similiar like Virtual DOM.
.path in the templateVBIND element will contain data-index attribute with the item array index// VBINDARRAY(template, target_element);
var obj = VBINDARRAY('<div data-bind=".name__html:value"></div>', document.body);
obj.set([{ name: 'Peter' }, { name: 'Anna' }, { name: 'Lucia' }]);
+v17 supports private binding methods:
var obj = VBINDARRAY('<div data-bind=".name__html:.mymethod"></div>', document.body);
obj.mymethod = function(value, path, el) {
// this === jQuery element
return 'VALUE_FOR_COMMAND';
};
// Possibilities:
// obj.set(index, item);
// obj.set(array);
// Sets a model
obj.set([{ name: 'Peter' }, { name: 'Anna' }, { name: 'Lucia' }]);
// v18 additional methods:
// obj.upd(index);
// obj.upd();
VBINDARRAY instance from elementvar vbindarray = element.vbindarray();
vbindarray.set([YOUR_ARRAY]);