Data Binding and Syncing with Non-UI Objects

The webix library contains view-less yet meaningful elements. They have no graphic representation and are used to store data in them.

These collections can store data and have the same API as their "visible" siblings. Such methods as bind() and sync() can be used with them as well.

How can you benefit from them?

DataCollection and TreeCollection Usage

Non-ui components store some info you'd like to use later in visible components. For instance, in the DataCollection you can specify the needed dataset and later on, sync all the data-presenting components with it so that they all are fed with the same data.

var data = new webix.DataCollection({ 
    template:"#rank#. #title# - #year#",
    data:big_film_set // the data source
});

Now let's initialize the list and synchronize it with our invisible DataCollection:

webix.ui({
    view:"list",
    id:"list",
    template:"#rank#. #title# - #year#",
    data:"" // we needn't specify anything here
});
 
$$('list').data.sync(data);

Now, if we bind a form to the DataCollection, it will be a slave view in relation to the synced list as well! And any data from the form will be added to dataCollection, and then to list.

However, data will not fill the form unless we refer to cursor concept.

Cursor Concept

Cursor position is the ID of an item that the cursor is set on. Cursor should be set in case several components are bound to/synced with one and the same source, e.g. one and the same DataCollection, in order to avoid conflicts between different component referring to one and the same data source and making changes upon it.

The invisible dataCollection is a master component for both the form and data-containing components synced with it. But since it's invisible, data cannot be operated on. The issue is solved by using any component to set cursor to an item from dataCollection each time this item is selected in the chosen component.

For instance, you'd like a list to be "volunteer" to get to dataCollection during form filling.

$$('list').attachEvent("onAfterSelect", function(id){  data.setCursor(id); });

As a result, data is saved to dataCollection after editing as well as to all the synced components without any additional manipulations.

Related sample:  DataCollection Syncing

Server-Side Integration with non-UI Components

Server-side work is enabled with dataConnector to load data and dataProcessor to save changes back to the database. It can be used for both "visible" and "invisible" (non-ui) components.

To use dataProcessor with dataCollection synced with some component on the page, you should go through a three-stage process.

1 . Define a dataCollection and populate it with data from the database:

store = new webix.DataCollection({
    url:"../common/connector.php",
    datatype: "xml"
});

2 . Declare a dataProcessor for the dataCollection:

var dp = new webix.DataProcessor({
    master: store,
    url: "../common/connector.php"
});

3 . Sync a data-presenting component with the dataCollection:

list.sync(store);

Related sample:  Data Syncing with DataCollection

DataCollection and Datatable Syncing

DataProcessor and server-side integration work the same way with all components yet in case of datatable extra functionality appears.

DataConnector allows rendering data from one table into a component (render_table method) or displaying data from several tables using custom SQL-query (render_sql method). More info about this in the Server-side Integration article.

Working with Database Tables: ID-to-Text Transformation

Tables in the database are often connected by ID while on client-side, within the component, we require that text values should be shown. The solution hides in loading data from the needed tables into different dataCollections and refer to datatable column configuration to render the database data.

First, create several dataCollections and load data from connected database tables.

Table Rendering

var employee = new webix.DataCollection({
    url:"data/employees.php",
    save:"connector->data/employees.php" // dataprocessor, short init form
});
 
var customers = new webix.DataCollection({
    url:"data/customers.php"
});
 
var orders = new webix.DataCollection({
    url:"data/orders.php",
    save:"connector->data/orders.php"
});

What is there in these collections?

While database connect parameters are the same for two collection, they differ in tables they render:

--library connectors for working with server side
require_once("./config.php");
$data = NEW JSONDataConnector($db,"SQLite3"); 
 
--for employee collection
$data->render_table("employees","id","email, fullname, login"); 
 
--for customers collection
$data->render_table("customers","id","lastname, firstname, job, address, city, zip, country"); 
 
--for orders collection
$data->render_table("orders","id","date, employee, customer, status [,other fields]);

Then create a datatable and sync it with either fo these collections.

$$("dash-ord-active").sync(orders);

This will be the main data source for the component. As far as in the "orders" table contains just IDs of dedicated customers and orders, they should be transformed into text while rendering to datatable .

For these needs there's a collection property in datatable column API to point to a data source different from that of the whole component.

{ view:"datatable", id:"dash-ord-active", 
 columns:[
        { id:"date", header:"Order Date" },
        { id:"employee", header:"Employee", collection:employee},
                { id:"customer", header:"Customer", collection:customers},
                { id:"status", header:"Status" },
                { id:"fee", ...},
                { id:"taxes", ...},
                { id:"total", ...} //other columns
        ]
}

Two columns for the datatable are fed directly from employee and customers collection where they get text values instead of ID-s.

Datatable column configuration is described in related datatable documentation.

Back to top