jComponent / 05. Component
Updated: 17. September 2020
Author: Peter Širka

05. Component

Professional Support Chat with contributors

This page describes the whole implementation of reusable component. Learn from existing components.

Quick navigation:

Component workbench

Definition

The code below describes a simple component definition with default configuration:

COMPONENT('datetime', 'interval:1000;format:dd.MM.yyyy', function(self, config, cls) {

    // This is the component scope
    // self == this
    // config == this.config
    // cls {String} auto-generated class name in the form: "ui-COMPONENTNAME" (+v17)

    var interval;
    
    self.readonly();
    self.blind();

    self.configure = function(name, value, init) {
        switch (name) {
            case 'interval':
                interval && clearInterval(interval);
                interval = setInterval(self.tick, value);
                break;
            case 'format':
                !init && self.tick();
                break;
        }
    };
    
    self.tick = function() {
        self.html(new Date().format(config.format));
    };
    
});

+v14.0.0 Declaration with a specific version:

// v1
COMPONENT('datetime@1', 'interval:1500;format:dd.MM.yyyy', function(self, config) {
    // ...
});

// v2
COMPONENT('datetime@2', 'interval:500;format:dd.MM.yyyy', function(self, config) {
    // ...
});

+v14.0.0 Declaration with multiple versions:

// v1
COMPONENT('datetime, datetime@1, datetime@2', 'interval:1000;format:dd.MM.yyyy', function(self, config) {
    // ...
});

Properties

Property: self._id

The property contains an internal identificator for this component.

  • readonly
  • returns String

Property: self.caller

The property contains a reference to caller/parent of some method executed via .exec()

  • readonly
  • returns Component
  • default undefined

Property: self.config

The property contains the whole configuration.

  • readonly
  • returns Object

Property: self.element

  • readonly
  • returns jQuery Element

Property: self.global

The property contains shared temporary object for all instances of this component.

  • returns Object

Property: self.id

The property contains an identifactor for this component. jComponent binds data-jc-id="ID" attribute to this property automatically. Otherwise self.id is same as self._id.

  • readonly
  • returns String

Property: self.name

The property contains a name of this component.

  • readonly
  • returns String

Property: self.path

The property contains the absolute path for data-binding. This value can be changed via self.setPath().

  • readonly
  • returns String

Property: self.pathscope

The property contains a path from parent e.g<div data-jc-scope="" element (if exists).

  • readonly
  • returns String

Property: self.removed

The property indicates whether the component has been removed.

  • readonly
  • returns Boolean

Property: self.scope

The property returns a scope data object. Read more in Scopes section.

  • readonly
  • returns Object

Property: self.siblings

The property indicates whether the element contains multiple declaration of components in the one element, e.g. <div data-jc="binder,exec">

  • readonly
  • returns Boolean

Property: self.template

The property can contain url address to a template or jQuery selector which it starts with ., # or [. Template will be stored in this property before is executed self.make(). Default value is binded according to data-jc-template="DEFAULT_VALUE" attribute.

Examples:

  • URL address: self.template = '/templates/products.html'
  • selector: self.template = '#mytemplate'
  • or <div data-jc="YOUR_COMPONENT" data-jc-template="/templates/products.html">

Property: self.trim

The property can disable auto trim string values. It works only with inputs with data-jc-bind="" attribute.

  • returns Boolean
  • default true

Property: self.type

The property contains a value from data-jc-type="" attribute. This type describes a data-type for parser or formatter.

  • returns String

Delegates

Delegates are executed on some jComponent actions. Some delegates have to return a value.

Delegate self.configure()

optional The delegate handles a configuration of the component. It's executed after is component initialized and after self.make(), or if self.reconfigure() is executed manually. Each key is processed independently.

self.configure = function(key, value, init, prev) {

    // @key {String}
    // @value {String/Number/Boolean/Object}
    // @init {Boolean} Is initialization?
    // @prev {String/Number/Boolean/Object} A previous value

    switch (key) {
        case 'required':
            self.tclass('required', value);
            break;
        case 'icon':
            self.find('.fa').rclass2('fa-').aclass('fa fa-' + value);
            break;
    }
};

Delegate self.destroy()

optional The delegate is executed when the component is removing.

self.destroy = function() {
    // Clean up
};

Delegate self.getter()

optional + internal The delegate has an internal implementation and it receives a value from HTML controls like input, select and textarea automatically. It's binded with data-jc-bind attribute on the target control. Its implementation is a bit complicated.

self.getter = function(value) {
    // @value {String} A value from HTML control
};

Delegate self.getter2()

optional This delegate has a similar functionality as self.getter() but you can use it for your own needs without changing self.getter().

self.getter2 = function(value) {
    // @value {Object} A processed value
};

Delegate self.init()

optional This delegate is executed the only onetime for all same components and jComponent evaluates it if the component is used. If you want to share some data between all instances then you can use self.global property.

self.init = function() {
    // It's executed the only one time for all instances of same components
};

Delegate self.knockknock()

optional This delegate is executed each 60 seconds by jComponent automatically.

self.knockknock = function(counter) {
    // @counter {Number}
};

Delegate self.make()

optional This delegate is executed when the component is creating. If you fill self.template property then the template argument will contain obtained data.

self.make = function(template) {
    // @template {String} Optional, it contains processed template data
};

Delegate self.prerender()

optional This delegate can update processed template before is executed self.make(). It works with filled self.template property only.

self.prerender = function(template) {
    // @template {String}
    // IMPORTANT: it needs to return a modified value
    return template.replace(/\n/g, '<br />');
};

Delegate self.released()

  1. For example: j-Form component - when the form is closed the component executes released(true) for all nested components and when the form is going to visible the component executes released(false) for all nested components.
self.released = function(is) {

    // @is {Boolean} true = the component is released by parent component, false = isn't released

    if (is) {
        // here you can clean-up DOM because e.g. component is hidden
    } else {
        // here you can restore previous state because control is visible
    }
    
};

Delegate self.setter()

optional The delegate observes changes in the model according to the defined path. It's executed everytime when data changes. Default implementation contains auto-mechanism for HTML inputs like <input data-jc-bind />, <textarea data-jc-bind> and <select data-jc-bind>.

// Custom implementation:
self.setter = function(value, path, type) {

    // @value {Object}
    // @path {String}
    // @type {Number} 0: init, 1: manually, 2: by input, 3: default 

    // Apply formatters
    value = self.formatter(value);

    // Render the value:
    self.html(value == null ? 'NULL' : value.toString());
};

Delegate self.setter2()

optional This delegate has a similar functionality as self.setter() but you can use it for your own needs without changing self.setter().

self.setter2 = function(value, path, type) {

    // @value {Object}
    // @path {String}
    // @type {Number} 0: init, 1: manually, 2: by input, 3: default 
    
};

Delegate self.state()

optional This delegate can change CSS when the value is invalid or something else.

self.state = function(type, what) {

    // type === 0 : init
    // type === 1 : manually
    // type === 2 : by input
    // type === 3 : by default

    // what  === 1 : valid
    // what  === 2 : dirty
    // what  === 3 : reset
    // what  === 4 : update
    // what  === 5 : set
    // what  === 6 : notify

    self.tclass('error', type === 0 ? false : self.isInvalid());
};

Delegate self.validate()

optional This delegate validates a value. It's executed by jComponent automatically when the value is modified. This delegate has to return a Boolean value.

self.validate = function(value, isInitialValue) {

    if (isInitialValue)
        return true;

    return value.length > 0;
};

Methods

Method: self.aclass()

This method is alias for self.element.addClass() and it adds CSS class into the element classes.

self.aclass(cls, [delay]);
// @cls {String}
// @delay {Number} Optional, in milliseconds
// returns {Component}

Method: self.append()

This method is alias for self.element.append() and it appends a new content into the element. A value can be HTML.

self.append(value);
// @value {String} or {Array String}
// returns {Component}

Method: self.attr()

This method is alias for self.element.attr(name, [value]) and it can get/set a value into the element attribute.

self.attr(name, [value]);
// @name {String}
// @value {String} Optional
// returns {Component}

Method: self.attrd()

This method is alias for self.element.attr(name, [value]) and it can get/set a value into the element attribute with data- prefix for name of attribute.

self.attrd(name, [value]);
// @name {String}
// @value {String} Optional
// returns {Component}

self.attrd('name', 'value');
// sets a value to the "data-name" attribute

Method: self.bindchanges()

+v14.2.0 This method binds changes only. If setter will get the same value as a previous value then skips binding.

self.bindchanges();
// returns {Component}

Method: self.bindexact()

+v14.1.2 This method sets binding of values when the the modification path is same as the component path or the path is part of parent path.

self.bindexact();
// returns {Component}

Method: self.bindvisible()

+v13.0.0 This method sets binding of values only when the component is not released, it depends on releasing of the parent component.

self.bindvisible([delay]);
// @delay {Number} A delay for binding value, default: DEF.delaybinder (200)
// returns {Component}

Method: self.blind()

This method sets the component as blind. Component will be skipped when jComponent performs data-binding. If your component won't work with data-binding then this option can increase a performance of your web app.

self.blind();
// returns {Component}

Method: self.data()

+v15 This method can set or get data from internal component repository. Data can be used for data-bind="" attribute and nested j-Components.

self.data(path, [value]);
// returns {Object}

// Sets:
self.data('some.path', 'Test');
// It depends all:
// <element data-bind="@some.path"
// <element data-jc="somecomponent__@some.path"

// Gets:
self.data('some.path');

Method: self.canisue()

+v17 This method checks a component whether exists or no.

self.caniuse(name);
// @name {String} A component name
// returns {Number}

// 0: component doesn't exist
// 1: component is initialized
// 2: component is not initialized but it's declared (lazy load)

console.log(self.caniuse('calendar'));
// Output: 1

console.log(self.caniuse('datepicker'));
// Output: 2

console.log(self.caniuse('newcomponent'));
// Output: undefined

Method: self.change()

This method can perform a change state. It changes dirty state and contacts all components which listen on path.

self.change([is]);
// @is {Boolean} Optional
// returns {Component}

// Is a change?
console.log(self.change());
// Output: false

// Perform a change
self.change(true);

console.log(self.change());
// Output: true

Method: self.classes()

REMOVED IN v18 This method can add or remove CSS classes.

self.classes(value);
// @value {String}
// returns {Component}

self.classes('+selected +hover -disabled -fa-home +fa-check-circle');
// +class -> is for adding
// -class -> is for removing

Method: self.closest()

This method is alias for self.element.closest(selector), it searchs selector in all parent elements.

self.closest(selector);
// @selector {String}
// returns {jQuery}

Method: self.command()

+v17 This method registers a new component command.

self.command(name, fn);
// @name {String}
// @fn {Function} a processor


self.command('refresh', function() {
    // DO SOMETHING
});

// EXECUTION
CMD('refresh');

Method: self.compile()

This method compiles new and uncompiled jComponents.

self.compile([container]);
// @container {jQuery Element} Optional, default: current element
// returns {jQuery}

Method: self.css()

This method is alias for self.element.css(name, [value]), it can set CSS or get.

self.css(name, [value]);
// @name {String}
// @value {String} Optional
// returns {Component} or {String}

// Writing:
self.css('margin', '5px');
self.css('width', '100%');

// Reading:
console.log(self.css('height'));

Method: self.datasource()

This method can watch some additional data-source. Each next declaration of self.datasource() cancels previous declaration.

self.datasource(path, callback, [init]);
// @name {String}
// @callback {Function(path, value, type)}
// @init {Boolean} Optional, invokes the callback with a value (default: true)
// returns {Component}
// +v12.0.0

self.datasource('products.manufacturers', function(path, value, type) {
    // @path {String}
    // @value {Object}
    // @type {Number} 0: init, 1: manually, 2: by input, 3: default 
});

Method: self.default()

This method can set a default value for the current component path.

self.default([reset]);
// @reset {Boolean} Optional, it resets "dirty" and "valid" states (default: true)
// returns {Component}

Method: self.emit()

This method emits an event within jComponent. Is alias for EMIT() method.

self.emit(name, [a], [b], [..n]);
// @name {String} Event name
// @a {Object} Optional, additional argument
// @b {Object} Optional, additional argument
// @..n {Object} Optional, additional argument
// returns {Component}

Method: self.empty()

This method is alias for self.element.empty(), it removes the whole content of element and important removes all components which the parent component is this component.

self.empty();
// returns {Component}

Method: self.evaluate()

This method is alias for self.element.empty(), it removes the whole content of element.

self.evaluate([value], expression, [is_value]);
// @value {Object} Optional, can be object if "is_value" is "true"
// @expression {String} A condition.
// @is_value {Boolean} Optional, default: false
// returns {Boolean}

// With reading a value according to the component "data-jc-path"
var isTeenager = self.evaluate('value >= 10 && value <= 20');

// With a real value
var isTeenager = self.evaluate(15, 'value >= 10 && value <= 20', true);

Method: self.event()

This method registers a new event for the element. Is alias for self.element.on() method.

self.event(name, [selector], callback);
// @name {String} Event name
// @selector {String} Optional, custom selector
// @callback {Function}
// returns {Component}

self.event('keydown', 'input', function(e) {
    console.log(e.which);
});

Method: self.exec()

The method executes a method according to the path in all nested components. It wont't throw any exception if the method not exist.

self.exec(name, [a], [b], [..n]);
// @name {String} A method name
// @a {Object} Optional, additional argument
// @b {Object} Optional, additional argument
// @..n {Object} Optional, additional argumentň
// returns {Component}

self.exec('refresh');
// Executes in all nested components --> component.refresh();

Method: self.extend()

The method extends a current value by adding/rewrite new fields with new values.

self.extend(value);
// @value {Object}
// returns {Component}

self.extend({ age: 35, alias: 'Peter' });

Method: self.find()

This method finds elements according to the selector. Is alias for self.element.find() method.

self.find(selector);
// @selector {String}
// returns {jQuery}

self.find('input').prop('disabled', true);

Method: self.formatter()

This method can register a new formatter for this component or can format a value. The method uses all registered global formatters MAIN.formatter() too for formatting values.

// For registering formatter:
self.formatter(fn);
// @fn {Function(path, value, type} Function needs to return a value
// returns {Component}

self.formatter(function(path, value, type) {
    // @path {String}
    // @value {Object}
    // @type {String} According to the "data-jc-type" attribute or "self.type"
    return typeof(value) === 'string' ? value.toUpperCase() : value;
});

// You can register more fomatters in a row
self.formatter(function(path, value, type) {
    return typeof(value) === 'string' ? value.split('').reverse().join('') : value;
});

// For formatting:
self.formatter(value);
// @value {Object}
// returns {Object}

console.log(self.formatter('Peter'));
// Output: RETEP

Method: self.get()

This method can get a value according to the data-jc-path or path.

self.get([path]);
// @path {String} Optional, default current component path
// returns {Object}

console.log(self.get());
// Gets a value: "window[component.path]"

console.log(self.get('users.grid.items'));
// Gets a value: "window.users.grid.items"

Method: self.hclass()

This method is alias for self.element.hasClass(), it determines class in the element.

self.hclass(cls);
// @cls {String}
// returns {Boolean}

Method: self.html()

This method is alias for self.element.html(), it can set/get a content of the element.

self.html(value);
// @value {String} or {String Array}
// returns {String} or {jQuery Element}

Method: self.import()

REMOVED IN v18 This method can import some content from external source to this element. IMPORTANT: Instead of this function use IMPORT().

self.import(url, [callback], [insert], [preparator]);
// @url {String}
// @callback {Function} Optional
// @insert {Boolean} Optional, default: true
// @preparator {Function(content)} Optional, it needs to return modified content
// returns {Component}

self.import('/templates/products.html');

Method: self.inc()

The method increments a Number according to the component.path.

self.inc(value);
// @value {Number}
// returns {Component}

self.inc(5);

Method: self.invalid()

The method sets the state of this component to invalid and it contacts all components listen on the path.

self.invalid();
// returns {Component}

Method: self.isInvalid()

The method checks a state whether the component is invalid or valid.

self.isInvalid();
// returns {Boolean}

Method: self.main()

The method returns a parent component instance if exists (otherwise: null).

self.main();
// returns {Component}

Method: self.nested()

REMOVED IN v18. The method returns all nested components.

self.nested();
// returns {Array Component}

Method: self.nocompile()

+v16 The method disables jComponent compilation for nested elements. This feature can increase the performance in several cases.

self.nocompile();
// returns {Component}

Method: self.nodirty()

The method disables dirty state.

self.nodirty();
// returns {Component}

Method: self.noscope()

The method disables scopes according to the data-jc-scope attribute.

self.noscope();
// returns {Component}

Method: self.notify()

The method notifies a setter in all components according to the component.path.

self.notify();
// returns {Component}

Method: self.novalidate()

The method disables validation.

self.novalidate();
// returns {Component}

Method: self.parent()

The method is alias for self.element.parent(), it gets a parent element.

self.parent([selector]);
// @selector {String} Optional, a jQuery selector
// returns {jQuery}

Method: self.parser()

This method can register a new parser for this component or can parse a value. The method uses all registered global parsers MAIN.parser() too for parsing values.

// For registering parser:
self.parser(fn);
// @fn {Function(path, value, type} Function needs to return a value
// returns {Component}

self.parser(function(path, value, type) {
    return typeof(value) === 'string' ? value.parseDate() : value;
});

// For parsing:
self.parser(value);
// @value {Object}
// returns {Object}

console.log(self.parser('2017-11-06'));
// Output: Mon Nov 06 2017 00:00:00 GMT+0100 (CET)

Method: self.push()

The method pushs a new item into the Array according to the component.path.

self.push([path], value);
// @value {Object}
// returns {Component}

self.push('Node.js');
self.push(['Node.js', 'Total.js']);

Method: self.rclass()

The method is alias for self.element.removeClass(), it removes a class from the current element.

self.rclass(cls, [delay]);
// @cls {String} Class names
// @delay {Number} Optional, default: 0
// returns {jQuery}

Method: self.rclass2()

The method removes classes according to the text to search.

self.rclass2(search);
// @search {String} or {RegExp}
// returns {Component}

self.rclass2('fa-');

Method: self.readonly()

The method enables readonly mode for the component. It disables dirty and valid states, getter, setter, parsers and formatters. This option can improve performance.

self.readonly();
// returns {Component}

Method: self.reconfigure()

The method reconfigures the component. Internally it executes self.configure delegate. Read more about configuration.

self.reconfigure(value);
// @value {String} or {Object}
// returns {Object}

self.reconfigure('maxlength:50;required:false');

// is same as:

self.reconfigure({ maxlength: 50, required: false });

Method: self.refresh()

The method executes the component.setter with a refreshed value according to the component.path.

self.refresh([updatePath]);
// @updatePath {Boolean} Optional, "true" notifies all components on the path (default: false)
// returns {Component}

Method: self.release()

The method performs release state for all nested components.

self.release(is);
// @is {Boolean} "true": release state, "false" restore state
// returns {Component}

// E.g. component is hidden:
self.release(true);

// E.g. component will be visible:
self.release(false);

Method: self.releasemode()

The method performs release state for all nested components.

self.releasemode(type);
// @type {String/Number/Boolean}
// returns {Component}

// "auto" or 0 means (DEFAULT):
// The component releasing dependes on the parent component.

// "true" or true or 1 means:
// The component accepts only released state from the parent component and it applies it to the nested components. So this component can change another state for nested components.

// "false" or false or 2 means:
// The component accepts only not released state from the parent component and it applies to the nested components. So this component can change another state for nested components.

// "manual" or 3 means:
// The component controls nested components manually (so it doesn't matter on the release state of the parent component)

Method: self.remove()

The method removes this component from the DOM and executes destroy delegate.

self.remove();
// returns {Component}

Method: self.replace()

The method replaces the current element for a new.

self.replace(el, [remove]);
// @el {jQuery} a new element
// @remove {Boolean} Optional, removes older element (default: false)
// returns {Component}

Method: self.reset()

The method resets dirty and valid state.

self.reset();
// returns {Component}

Method: self.rewrite()

The method rewrites a value according to the component.path and it won't notify all listeners.

self.rewrite(value);
// @value {Object}
// returns {Component}

Method: self.scopepath()

+v17 The method returns an updated path according to the scope --> if the path will contain ? char which will be replaced.

self.scopepath(path);
// returns {String}

Method: self.set()

The method sets a value according to the component.path.

self.set(value, [type]);
// @value {Object}
// @type {Number/String} Optional
// returns {Component}

Method: self.setPath()

The method rewrites component.path.

self.setPath(path);
// @path {String} New path
// returns {Component}

Method: self.singleton()

The method creates a single instance of the component. So if the component will be declared multiple times then jComponent creates the only one instance and another declarations will be skipped.

self.singleton();
// returns {Component}

Method: self.skip()

The method skips future calling of component.setter. It's incremental.

self.skip([path]);
// @path {String} Optional, absolute path (default: "data-jc-path")
// returns {Component}

// Skips a next calling of setter
self.skip();

// or with multiple paths:
self.skip('users.form.firstname, users.form.lastname');

// returns {Component}

Method: self.tclass()

The method toggles class, it's alias for self.element.toggleClass().

self.tclass(cls, [add]);
// @cls {String} A class name
// @add {Boolean} Optional, true: adds class, false: remove class, undefined: toggles class
// returns {Component}

Method: self.text()

This method is alias for self.element.text(), it can set/get a content of the element.

self.text([value]);
// @value {String}
// returns {String} or {jQuery Element}

Method: self.unwatch()

The method unregisters a monitoring of value according to the path argument.

self.unwatch(path, [handler]);
// @path {String}
// @handler {Function} Optional
// returns {Component}

Method: self.validate2()

+v13.0.4 The method performs validation with refreshing state of component.

self.validate2();
// returns {Boolean}

Method: self.watch()

The method registers a monitoring of value according to the path argument.

self.watch(path, handler, [init]);
// @path {String}
// @handler {Function}
// @init {Boolean} Optional, it evaluates path now (default: false)
// returns {Component}

self.watch('products.items', function(path, value, type) {
    // @path {String}
    // @value {Object}
    // @type {Number} 0: init, 1: manually, 2: by input, 3: default
});

Usage in HTML

Each component needs to be initialized in HTML directly:

Component declaration:

<div data---="COMPONENT_NAME"></div>
<span data---="COMPONENT_NAME"></span>
<whatever data---="COMPONENT_NAME"></whatever>

<!-- OR OLDER DECLARATION -->

<div data-jc="COMPONENT_NAME"></div>
<span data-jc="COMPONENT_NAME"></span>
<whatever data-jc="COMPONENT_NAME"></whatever>

Component declaration with data-binding:

<div data---="COMPONENT_NAME__path.to.model"></div>
  • jComponent converts a component path.to.model to the path in the window scope. It converts it to e.g. window.path.to.model in the background
  • so the component will watch a value on the path.to.model path

Component declaration with data-binding and configuration:

  • separator can be __ or ___ or _____ and can contain spaces between values
  • developer can choose declaration between new and older
<div data-jc="component __ path __ config __ default value"></div>

Examples:

<div data---="textbox___form.name___required:true;maxlength:30">NEW</div>
<div data-jc="textbox" data-jc-path="form.name" data-jc-config="required:true;maxlength:30">OLD</div>

<div data---="textbox___form.name___required:true;maxlength:30___'Peter'">NEW</div>
<div data-jc="textbox" data-jc-path="form.name" data-jc-config="required:true;maxlength:30" data-jc-value="'Peter'">OLD</div>

<div data---="textbox __ form.name __ required:true;maxlength:30 __ 'Peter'">NEW</div>
<div data-jc="textbox" data-jc-path="form.name" data-jc-config="required:true;maxlength:30" data-jc-value="'Peter'">OLD</div>
  • jComponent follows HTML 5 standards

Configuration

The configuration of components is a very important part of reusable components. Configuration is stored in data---="COMPONENT__PATH__key1:value1;key2:value2" attribute.

Good to know:

  • Number is parsed as Number, e.g. key:123 or key:123.45
  • Boolean is parsed as Boolean, e.g. key:false or key:true
  • Environment values are parsed automatically, e.g. key:[key_in_env]
  • if your value contains a : colon you can encode it via backslash \:
  • you don't have to encode absolute URL addresses, e.g. key:https://www.google.sk will work without encoding
  • IMPORTANT: configuration can be binded with path.to.variable like this: data-jc-config="=path.to.variable"

Each component needs to implement the delegate below:

// This delegate is executed for each key from configuration
self.configure = function(key, value, init, prev) {

    // @key {String}
    // @value {String/Number/Boolean/Object}
    // @init {Boolean} Is initialization?
    // @prev {String/Number/Boolean/Object} A previous value

    switch (key) {
        case 'required':
            self.tclass('required', value);
            break;
        case 'icon':
            self.find('.fa').rclass2('fa-').aclass('fa fa-' + value);
            break;
    }
    
};

Processed component can be reconfigured via:

  • self.reconfigure('key3:value3;key4:value') or
  • self.reconfigure({ key3: 'value3', key4: 'value4' })
  • Quick tip: SETTER('#mytextboxid', 'reconfigure', 'required:false')

Reconfiguration doesn't cancel previous configuration, but it extends it.

Special configuration

Special configuration is part of jComponent +v16.

  • $id:string component id
  • $class:string can toggle class when the component is ready
  • $binding:1 enables real-time binding only
  • $binding:2 enables binding after change only
  • $delay:300 binding delay
  • $init:path.to.method executes a method if the component is initialized
  • $setter:path.to.method executes a method if the setter is modified
  • $state:path.to.method executes a method if the component changes the state
  • $reconfigure:path.to.method executes a method if the component is reconfigured
  • $compile:false disables a compilation for nested components
  • $url:/editor.html downloads the declaration of component only one time before is component processed (+v17)

Data Binding

Data Binding performs two way Data Binding between a component and a model.

  • components creates a listener on the path and the component will react on its change
  • delegate component.setter processes data-binding on the component side
  • these global methods perform a change in the model and notify all components SET(), PUSH(), INC(), EXTEND() and UPDATE()
<div data---="textbox__myform.name"></div>
<div data---="json__myform"></div>
<div data---="textbox__user.name"></div>

<script>
    SET('myform.name', 'Peter');
    // This method assigns a value "Peter" according to the path "window.myform.name"
    // "window.myform.name" will contain "Peter"
    // Components: textbox + json will be notified because they listen on the modified path
    // Component textbox with "user.name" won't be notified because it's listening on another path

    SET('user', { name: 'Peter' });
    // This method assigns a value {Object} according to the path "window.user"
    // "window.user" will contain the {Object}
    // Only component textbox with "user.name" will contain a modified value
</script>

+v14.2.0 supports inline helpers:

<div data---="textbox__myform.name --> value.toUpperCase()"></div>

Special binding for nested components

+v16 supports special data-binding for nested jComponents. Path of nested component must start with @ char.

For example:

<div data---="A__path">
    <div data---="B__@path"></div>
</div>
  • component A can set data to B component via component.data('path', 'some data')
  • nested component B is listening on the owner/parent component A

Special binding for data-bind

+v18 supports binding a value via data-bind command set. This binding of value works with VBINDARRAY too, but only in readonly mode.

  • . dot in the component's path is very important, it allows to bind a value from data-bind

For example:

<div data-bind="path.to.value__set" data---="textbox__.__required:1"></div>

or 

<div data-bind="path.to.value__set:value.toUpperCase()" data---="textbox__.__required:1"></div>