Intermediate

Customizing Loading Pattern with Ajax

By default Webix loads data to its component by an asynchronous Ajax GET request. However, various modifications are possible.

Loading Data via POST Request

You can change the request type to POST.

{
    view:"datatable",
    ..config..
    url: "post->load.php"
}

Loading Data via Synchronous Ajax Request

You can change the request to a synchronous one (sometimes it may be useful).

{
    view:"datatable",
    ..config..
    url: "sync->load.php"
}

Modifying Background Ajax Requests

You cannot modify background Ajax requests sent by the above pattern.

However, you can catch Webix onBeforeAjax event to modify ANY Ajax request on the page (so be attentive):

Sending Headers

webix.attachEvent("onBeforeAjax", 
    function(mode, url, data, request, headers, files, promise){
        headers["Content-type"] = "application/json";
    }
);

Note that Webix Ajax module (described below) features a built-in functionality for sending headers with server-side requests.

Loading with Webix Ajax Helper

To load data on demand without breaking application flow, you can resort to Webix Ajax interface.

You can load data in two ways:

  • a traditional callback approach
  • implementation with promises

Loading with a callback function

To access the raw text and load it into a UI component, you can add a callback as the second parameter for webix.ajax() to load the data into the component.

//get request (default)
webix.ajax("data/load.php", function(text,data){
    $$("list").parse(text);
});

Ajax loading allows passing parameters to a server-side script as a GET request:

webix.ajax("server/load.php?id="+id, function(text,data){
    //callback
});

Loading through a promise

Using a callback is not the only possible way. Any asynchronous Ajax request performed by Webix immediately returns a promise object. A promise is an object that serves as a placeholder for a value. When the promise arrives, you can parse it directly into the component.

var data = webix.ajax("data/load.php"); //promise
$$("list").parse(data);

Promises are useful when you plan to load the same data to some other component as well or load the data later. Thus an Ajax request and data loading are not bound together.

Pre-processing data before loading

A server-side script must return data in one of the supported data formats so that the responce can be parsed into the necessary component. In case the received data is presented in a non-supported format, you can modify the format and then parse the data.

Suppose this is the data we receive:

{
    "x1":{ name:"Alex" },
    "x2":{ name:"Dan" }
}

and for a Webix component it must be like the following

[
    { id:"x1", name:"Alex"},
    { id:"x2", name:"Dan" }
]
  • There is a way to change it inside a callback function.
webix.ajax("data/load.php", function(text,data){
 
    var js = data.json();
    var new_js = [];
 
    for (key in js){
        new_js.push({
            id:key, 
            name:js[key].name
        });
    };
 
    $$("list").parse(new_js);
});

In the snippet above JSON data is received from the response, then the data object is remapped and loaded into the component.

  • The same can be done using a promise. Promises have a then method for registering a callback to use when the operation succeeds.
var data = webix.ajax("data/load.php").then(function(data){
    var js = data.json();
    var new_js = [];
 
    for (key in js){
        new_js.push({
            id:key, 
            name:js[key].name
        });
    };
 
    return new_js;
});
 
$$("list").parse(data);

Both techniques shown above allow configuring the UI and processing the data separately. You can combine these two processes. In the snippet below the url property gets its value dynamically and the data is loaded into the datatable during the initialization of the UI.

var userId = 123;
 
webix.ui({
    view:"datatable",
    autoConfig:true,
    url:function(details){
        return webix.ajax("data.php?filterByUser="+userId).then(function(res){
            var js = data.json();
            var new_js = [];
 
            for (key in js){
                new_js.push({
                    id:key, 
                    name:js[key].name
                });
            };
 
            return new_js;
        })
    }
});

Dynamic loading

For big amounts of data dynamic loading is used. Customization of dynamic loading calls is different, because it is not possible to control it directly. There are 2 ways to customize dynamic loading.

onDataRequest event

While loading new data into a component, you can cancel the default behaviour and define a custom data request with the help of the onDataRequest event.

// onDataRequest
grid.attachEvent("onDataRequest", function(start, count, callback){     //count
    var view = this;
    webix.ajax().post("api/data?page="+start/10).then(function(data){
        this.parse(data.json());
    })
    return false;
})

The callback function varies among components. For the Datatable a callback receives three parameters:

  • start - the position from which the new data is loaded;
  • count - the number of records that will be loaded;
  • callback - (optional) the function to be executed after the data is loaded.

In the snippet above instead of sending default start and pos parameters, the code sends the page number (which is the starting position divided by the page size).

For the Tree and Treetable the parameters are:

  • id - the ID of a parent branch
  • callback - the function to be executed after the data is loaded.

Using a proxy object

It's possible to create a custom proxy object, which will work as an intermediate level between a component and a server-side script.

For details, please check the proxy documentation for details.

Related articles

Here you should consult:

Back to top