Intermediate

Defining Data Scheme

Data scheme defines schemes for data processing, the default actions for loaded, updated, serialized, grouped, and sorted data items.

The scheme object is defined in the scheme property. Generally, it allows you to set a default scheme for data records of DataStore. So in case you add an empty record to DataStore, the record will be populated with the values set by the scheme.

Any changes you apply through a data scheme are directly applied to the data store items.

var list1 = webix.ui({
    view:"list",
    scheme:{
        name:"Unknown",
        age:16
    }
});
 
list1.add({}); // adds a record { name:"Unknown", age:16 }

add() is the method of the DataStore component. So we use the data property to access it.

In addition, there are special keys you can use within the property:

  • $init - runs in the following cases:
    • when data are initially being loaded to the component;
    • while reloading data for new DataStore items;
    • when the add method is called;
    • while processing the $group object;
  • $update - runs for existing items while reloading data (for new items $init runs) + when the update method is called;
  • $save - runs when saving to a server is triggered in any of the ways;
  • $change - runs each time the data in the table is changed (i.e. loaded, added, updated, deleted). Note that this key runs when either the $init or the $update key runs;
  • $serialize - runs when the serialize method is called;
  • $export - similar to $serialize; runs when data are exported (regardless of export method)
  • $group - the object with grouping parameters. Passed to the group function that automatically runs when data are initially being loaded to the component;
  • $sort - the object with sorting parameters. Passed to the sort method that automatically runs when data are initially being loaded to the component.

Below you can find examples of using each of the keys.

$init Key

Input parameters

The $init function accepts 1 parameter - the data item object.

It is called:

  • for each data item during initial data loading;
  • for newly-added items during data reloading;
  • for the specified item when the add method is called;
  • while processing the $group object.

Usage example

Let's assume that you have a list with data and want to apply different CSS styles for list items depending on the value of the "year" data field. The logic will be the following:

  • for the items the value of the year of which is earlier than 1970 the "oldtime" CSS class will be applied;
  • for the items the value of the year of which is later than 2000 the "newtime" CSS class will be applied.

This is how you can make use of the the $init key within a data scheme:

webix.ui({
    view:"list", 
    layout:"x",
    scheme:{
        $init:function(obj){
            if (obj.year >= 2000) obj.$css = "newtime";
            if (obj.year <= 1970) obj.$css = "oldtime";
        }
    }
});

Related sample:  Horizontal List

$update Key

Input parameters

The $update function accepts 1 parameter - the data item object.

It is called:

  • for updated items during data reloading;
  • for the specified item when the update method is called.

Usage example

Let's assume that in your database table you have a field named "update_date" where the date of the last item update is stored. To have the field values up to date, you can use the $update key and specify it as in:

webix.ui({
    view:"list",
    scheme:{
        $update:function(obj){ 
            var today = new Date();
            // "update_date" is the name of a data property
            obj.update_date = today.getDate();
        }
    }
});

$save Key

Input parameters

The $save function accepts 1 parameter - the data item object.

It is called:

  • each time new or changed data are sent to a server.

Usage example

In combination with the $init key, $save gives you an ability to set loading and saving pattern for the server-side data.

For instance, you can work with dates as DateTime objects on the client side, while storing them as strings on the server. To avoid formatting after each operation, do it only on data loading and saving.

webix.ui({
    view:"datatable",
    url:"data.php", // loading data
    save:"data.php", // saving data
    scheme:{
        // turning strings into objects on loading
        $init:function(obj){
            if (obj.birthday)
                obj.birthday = webix.i18n.parseFormatDate(obj.birthday);
        },
        // turning objects back to strings on saving
        $save:function(obj){
            if (obj.birthday)
                obj.birthday = webix.i18n.parseFormatStr(obj.birthday)
        }
    },
    columns:[...]
});

$change Key

Input parameters

The $change function accepts 1 parameter - the data item object.

It is called:

  • each time data are changed in the table.

Usage example

Let's assume that you have a datatable with a list of films and want to color rows with films that were shot after 1980 year in red. Here you can use the $change key that will run each time data are changed and check whether the changed item(s) should be colored in red.

webix.ui({
    view:"datatable",
    scheme:{
        $change:function(item){
            if (item.year > 1980)
                item.$css = { "color":"red" };
        }
    }
});

Related sample:  Rows Styling

$serialize Key

Input parameters

The $serialize function accepts 1 parameter - the data item object.

It is called:

  • for each data item, when the serialize method is called.

The $serialize key must return data item object that will go to the resulting serialized JSON object. You should not modify the original data.

Usage example

Let's assume that you store date values as Date() objects in the database. But on the client side you want to operate with these data as with strings. In this case, you can specify the $serialize key and call the serialize method to get the data in the required format:

webix.ui({
    view:"list",
    id:"mylist",
    data:list_data,
    template:"#date#",
    scheme:{
        $init:function(obj){
            obj.date = new Date();
        },
        $serialize: function(obj){
            return { value:obj.value, date: webix.i18n.dateFormatStr(obj.date) };
        }
    }
});
 
var items = $$("mylist").serialize();

Related sample:  Getting Data in the Required Format

Note that $serialize accepts a data item, and the changes made upon it will modify the widget data. The example above shows how to preserve the initial data unchanged.

$export Key

Input parameters

The $export function receives one parameter - the data item object.

It is called:

The $export key must return data item object that will go to the resulting exported data set. You should not modify the original data.

Usage example

Suppose you want to export the dates in your data as strings. Add the $export key that will transform the dates and return them to the export method:

webix.ui({
    view:"list",
    id:"mylist",
    data:list_data,
    template:"#date#",
    scheme:{
        $export:function(obj){
            return { value:obj.value, date:webix.i18n.parseFormatStr(obj.date) };
        }
    }
});
 
webix.toExcel($$("mylist"));

Related sample:  Changing Item Data in Export

$group Key

Input parameters

The $group function accepts 1 parameter - a so-called group object that has 2 properties:

  • by – a data property according to which items will be united in groups;
  • map – an object that defines properties of the items in the group.

Properties are specified by an array. The first element of this array is a template with a property from the original data, the second one – the functor that will be applied to all the values of the property (set by the first element) in the group. Grouping provides the following functors:

  • sum – gets the sum of the values;
  • max – gets the maximum value in the group;
  • min - gets the minimum value in the group.

It's possible to define a custom functor. For further reading go to the related article on Custom Functor for Data Grouping in Charts.

The $group function is called:

  • for each data item during initial data loading

The function doesn't run when you programmatically call the group method.

Usage example

Let's take the following example: you've got the sales information over the last years in several companies and want to show total sales per companies in a chart. So, you need to get objects of the same companies and sum up their sales. Grouping helps to resolve this problem.

webix.ui({
    view:"chart",
    scheme:{
        $group:{
            by:"#company#", // 'company' is the name of data property
            map:{
                sales:["#sales#","sum"]
            }   
        }
    }
});

Related sample:  Grouping

$sort Key

Input parameters

The $sort function accepts 1 parameter - a so-called sorting object that has 3 properties:

  • by - the name of the data property by which items will be sorted;
  • dir - the sorting direction: "asc" or "desc";
  • as - the sorting mode. The following modes can be applied:
    • "int"
    • "date"
    • "string"
    • "string_strict" (case-sensitive "string")
    • "text"
    • "server"
    • "raw"
    • or custom.

A custom sorting method is defined by a function. This function is called for each pair of adjacent values and returns 1,-1 or 0:

  • 1 - the object with the first value in pair must go before the second one
  • -1 - the second object goes before the first
  • 0 - the objects are equal

The $sort function is called:

  • for each data item during initial data loading.

The function doesn't run when you programmatically call the sort method.

Usage example

Let's assume, you need to sort data by the "time" property that consists of minutes and seconds divided by ":". This example shows both the usage of the $sort key and the way to define a custom sorting method:

webix.ui({
    view:"chart",
    scheme:{
        $sort:{
            by:"time",
            dir:"asc",
            as:sortTime
        }
    }
});
 
function sortTime(a,b){
    a = a.split(":");
    b = b.split(":");
    if (a[0] > b[0]) return 1;
    else if (a[0] < b[0]) return -1;
    else{
        if (a[1] > b[1]) return 1;
        else if (a[1] < b[1]) return -1;
        return 0;
    }
}
Back to top