Client-Side Data Processing
.. in Webix Apps

EditAbility: Grid Data
webix.ui({
view:"datatable",
columns:[
{ id:"rank", editor:"text", header:""},
{ id:"title", editor:"text", header:"Film title"},
{ id:"year", editor:"text", header:"Released"},
{ id:"votes", editor:"text", header:"Votes"}
],
editable:true
});- datatable/treetable is editable
- columns have editor
Text
*There are > 10 types of editors

Editability: Column Options
view:"datatable",
columns:[
{ id:"title", editor:"text" },
{ id:"cat_id", editor:"select", options:["Crime", "Thriller"] },
],
editable:true,
data: [
{ id:1, title:"The Shawshank Redemption", cat_id:"Thriller" },
{ id:2, title:"The Godfather", cat_id:"Crime" }
]- select
- richselect
- combo
Editability: Column Options
view:"datatable", id:"grid", data:data,
columns:[
{ id:"title", fillspace:true},
{ id:"categoryId", editor:"select", collection:options}
]
var data = [
{ id:1, title:"...", categoryId:1 },
{ id:2, title:"...", categoryId:2 },
{ id:3, title:"...", categoryId:3 }
];var options = [
{ id:1, value:"Crime"},
{ id:2, value:"Thriller"},
{ id:3, value:"Drama" }
];Data
Options
Text
- plain array
- array of 'id-value' pairs
- path to external storage
EditAbility: List and Tree Data
webix.protoUI({
name:"editlist"
}, webix.EditAbility, webix.ui.list);
webix.ui({
view:"editlist",
template:"#rank#. #title#",
editable:true,
editor:"text",
editValue:"title"
});
- the component is 'upgraded' with webix.EditAbility
- the component is editable
- the component has editor and editValue

Wow, I can create Webix components myself!..

On-Edit Validation
view:"datatable", //any data component
rules:{
"title":webix.rules.isNotEmpty,
"year":webix.rules.isNumber
}How did we validate form values?
Validation starts after data change (e.g. editor closes)
Rules!

Datatable Filtering
datatable.filterByAll();
- title
- year
- votes
- rating
- rank
Value changes in any filter
filter.compare || default compare
And

Datatable Filtering
compare function
{ content:"textFilter", compare:function(value, filter, item){
var year = value.getFullYear().toString();
return year.toString().indexOf(filter.toLowerCase()) !==-1;
}}
...
data:[
{ text:"Joint 2", start:new Date(2011,1,14) }
]change .filterByAll()
$$("grid").filterByAll=function(){
this.filter(function(obj){
if (...) return true;
return false;
});
};Datatable Filtering
Add an extra field
rows:[
{ view:"segmented", id:"selector", options:[
{ id:1, value: ">2000" },
{ id:2, value: "<2000" }
]},
{ view:"datatable", id:"grid" }
]$$("grid").registerFilter(
$$("selector"),
{
columnId:"start",
compare:function(value, filter, item){
var year = value.getFullYear();
if(filter == 1) return year > 2000;
else return year <=2000;
}
},
{
getValue:function(node){ return node.getValue(); },
setValue:function(node, value){ node.setValue(value); }
}
);
Grouping Data
Grouping criterion
Aggregating data
view.group({
by:"year"
});{ id:1, title:"The Shawshank Redemption", year:1994, votes:678790},
{ id:2, title:"The Godfather", year:1972, votes:511495},
{ id:3, title:"The Godfather: Part II", year:1994, votes:319352},
{ id:4, title:"The Good, the Bad and the Ugly", year:1972, votes:213030} view.group({
by:"year",
map:{
votes:[ "votes", "sum" ],
title:[ "year", "any" ]
}
});Visualizing the result
columns:[
{ id:"title", template:function(obj, common){
if(obj.$group) return common.treetable(obj, common) + obj.title;
else return obj.title;
}}
]Grouping Data: Chart
Grouping criterion - X axis
Aggregating data - Y Axis
view.group({
by:"year"
});{ id:1, title:"The Shawshank Redemption", year:1994, votes:678790},
{ id:2, title:"The Godfather", year:1972, votes:511495},
{ id:3, title:"The Godfather: Part II", year:1994, votes:319352},
{ id:4, title:"The Good, the Bad and the Ugly", year:1972, votes:213030}view.group({
by:"year",
map:{
votes:[ "votes", "sum" ]
}
});Visualizing the result
view:"chart",
value:"#votes#",
xAxis:{
template:"#year#"
},
yAxis:{}Data Pre Processing
Scheme functions
- $init
- $group
- $sort
- $change
- $update
- $save
- $serialize
{
view:"datatable",
scheme:{
$init:function(obj){
obj.date = new Date(2018, 23, obj.id);
if(obj.year > 1998)
obj.$css = "highlight";
},
$sort:{
by:"votes",
dir:"desc"
}
}
}Connect you Data:Binding
$$("mydata").attachEvent("onAfterSelect", function(id){
var item = this.getItem(id);
$$("myform").setValues(item);
});
$$("myform").attachEvent("onChange", function(){
var values = this.getValues();
$$("mydata").updateItem(values.id, values);
});$$("myform").bind($$("mydata"));
$$("myform").save();- in: form is filled when data item is selected
- out: form pushes data into master upon .save() call
$$("myform").attachEvent("onChange", function(){
this.save();
});* don't forget about form elements names
Connect you Data:Syncing
Same data with different presentation?
No need to load twice -
Sync them!
webix.ui({
cols:[
{ view:"list", id:"list", select:true, data:[...]},
{ view:"datatable", id:"mydata", autoConfig:true }
]
});
$$("mydata").sync($$("list"));- master list contains data loaded in either of the ways
- slave datatable has no data of its own
- slave datatable takes its data from master list
Connect you Data:Syncing
$$("mydata").sync($$("list"), function(){
this.filter(function(obj){
obj.year > 1998;
})
});Edit: master
Add: master
Remove: master
slave
slave
slave
$$("mydata").sync($$("list"));Sync callback:
Useful Links
Webix Topics:
Practice task: click here

Follow-up text: click here
1-4. Webix Basics. Client-Side Data Processing
By ihelga
1-4. Webix Basics. Client-Side Data Processing
How to edit, filter, sort, group data in Webix widgets. Binding and syncing of widget data.
- 680