Advanced

Webix Proxy Objects

Both the component's url property and its load function can be used not only for passing the loading script. They can include additional loading logic in proxy objects.

The samples given in this chapter assume that all requests to the server side are performed with the webix.ajax module. For more information, check the Ajax Operations article and webix.ajax API.

Built-in Proxy Objects

There's a list of ready-to-use Webix proxy objects that can be used by adding prefixes to a loading script.

Active

  • rest - for working with a server in the REST mode;
  • post - for loading data in a POST request (GET by default);
  • binary - for loading and reading files as arraybuffer;
  • json - for sending JSON data to a server via RESTful "save" requests with the "application/json" content type;
  • GraphQL - for working with a server with the help of the GraphQL API query language.

Deprecated

  • indexdb - for working with indexedDB in-browser database storage;
  • faye - for enabling live data update on all clients currently using the application. Look here for details;
  • offline and cache - for offline support of applications that use server-side data;
  • local - for saving component data into a browser local storage and working with it. Described as part of the offline support article;
  • connector - for saving data via Server Side Connector;

Built-In Proxy Usage

To use a proxy, define it in one of these ways:

1. implicitly, insert the name of the proxy as a prefix to the path to your server-side script:

// proxy for loading
webix.ui({
    view:"datatable", id:"grid",
    url:"binary->file.pdf" 
});
$$("grid").load("binary->file.pdf");
 
// proxy for saving
webix.ui({
    view:"list"
    url:"load.php",
    save:"rest->load.php" 
});

2. explicitly, use the webix.proxy() method:

var myProxy = webix.proxy("binary", "load.php");
 
webix.ui({
    view:"list"
    url: myProxy
});

Using Methods of Built-in Proxy Objects

Proxies may have several methods that are called automatically:

  • init()
  • load()
  • save()
  • saveAll()
  • result()

For more details about these methods, go to this reference.

All built-in proxies have at least one of them: load() or save() depending on the purpose of the proxy. They are called by Webix during loading and saving respectively, but you can also call them by API in either of the two ways:

1. via the url of the component:

$$("grid").config.url.load(view, params);

2. via the instance of the proxy created explicitly:

var binary = webix.proxy("binary", "server/datatable.php");
 
webix.ui({
    view:"datatable",
    autoConfig:true,
    url:binary
});
 
binary.load(view, params);

Customizing Built-in Proxy Objects

In custom proxies you can define any parameters or methods, as well as override the methods of native proxies. These are the ways how you can customize proxies:

1. Initialize any existing proxy with an additional logic. Use the webix.proxy() method with three parameters:

  • the name of the built-in proxy;
  • the path to the script;
  • the object with the additional logic.
var dataProxy = webix.proxy("rest", "data.php", { 
    meta: "some text", //some param
    save:function(view, params){
        params.data.meta = this.meta;
        webix.proxy.rest.save.call(this, view, params); 
    }
});

And use this proxy as:

webix.ui({
    view:"datatable", autoConfig:true,
    save:dataProxy
});

2. Create a new proxy based on an existing one. Use webix.extend() to provide extra functionality.

You can extend it in the init() method of the new proxy object:

webix.proxy.custom = { 
    init:function(){
        webix.extend(this, webix.proxy.rest);
    }, 
    meta:"text", //some param
    save:function(view, params){
        params.data.meta = this.meta;
        webix.proxy.rest.save.call(this, view, params); 
    }
}

Or with a slightly different syntax:

webix.proxy.custom = webix.extend({
    meta: "text", //some param
    save:function(view, params){
        params.data.meta = this.meta;
        webix.proxy.rest.save.call(this, view, params); 
    }
}, webix.proxy.rest);

To use the new proxy, add it as a prefix to the path to the server-side script:

webix.ui({
    view:"datatable", save:"custom->my_script"
});

Creating Custom Proxy Objects

A proxy object is a plain JSON object that contains:

  • a compulsory $proxy property set to true;
  • functions to fire on loading and saving;
  • custom properties and methods.

So, first you need to define a proxy object with the desired configuration. It can be done in two ways:

1. dynamically, in the url property of the data component:

{
    view:"datatable",
    url:{
        $proxy:true,
        load:function(view, params){
            return webix.ajax().get("load.php", params); 
        }
    }
}

2. as a separate proxy. Please note that the server script can be accessed as this.source within the methods of such proxy:

webix.proxy.myCustomName = {
    $proxy:true,
    load:function(view, params){
        return webix.ajax().get(this.source, params); 
    }
};

Then append the name of the proxy object as a prefix to the corresponding script for the related widget:

{
    view:"datatable",
    url:"myCustomName->load.php"
}
//or, after component initialization
$$("datatable1").load("myCustomName->load.php");

This way has an advantage, as such separate proxy can be used for several components.

Providing Loading Logic

If you want to provide the loading logic, define the load() method for your proxy that should return either a promise of data or static data:

Promise of data

webix.proxy.load = {
    $proxy:true,
    load:function(view, params){
        return webix.ajax("/samples/server/packages");
    }
};

Check Ajax Operations article for more details on return data.

Static data

webix.proxy.load = {
    $proxy:true,
    load:function(view, params){
        var data = [ /* array or records */];
        return data;
    }
}

Related sample:  Loading: Proxy and Url

Providing Saving Logic

For defining custom logic for saving data to the server, you should provide the save() method:

webix.proxy.save = {
    $proxy:true,
    save:function(view, params, dp){
        var id = params.data.id;
        if (params.operation == "insert")
            return webix.ajax().post("/samples/server/films", params.data);
        // ... other operations
    }
};

Related sample:  Saving: Proxy and Url

Saving All Changes on Demand

Normally, DataProcessor of a component tracks all changes made on the client side and sends save requests immediately after any insert/update/remove operation.

If you want to cancel this behavior and instead, save all changes made by user on demand (e.g. once they click a "Save" button), you should tune both saving pattern and DataProcessor in the following way:

First, create a proxy with the saveAll() method that will receive the updates tracked by DataProcessor till the moment it is called:

webix.proxy.saveall = {  
    $proxy:true, 
    saveAll:function(view, updates, dp){
        //updates - the array of changed records
        return webix.ajax().post(this.source, { data:updates });
    }
};

Next, you need to prohibit the automatic sending of changes by defining the autoupdate setting for the DataProcessor. Also, don't forget to use the above proxy as a saving url:

{
    view:"datatable", id:"datatable1",
    autoConfig:true, editable:true,
    url:"/samples/server/films",
    save:{
        autoupdate:false,
        url:"saveall->/samples/server/films_all"
    }
}

After that, call send() method of component DataProcessor to push all the saved updates to the saveAll() method of the above proxy:

// e.g. in a button click handler
webix.dp($$("datatable1")).send();

Related sample:  Save: All at once

Proxy API Reference

init()

Used for providing the initial logic of a proxy object. It does not have any parameters or a return value.

load()

Used for data loading.

Parameters:

Return value:

a promise of the data or a plain data array/object.

save()

Used for saving single records and is triggered when some changes occur on the client side.

Parameters:

  • view - object - the component you work with;
  • params - object - an object with the following properties:
    • data - a data object of the changed record,
    • id - the ID of the record;
    • operation - the name of the operation, "insert", "update" or "delete";
  • dp - object - DataProcessor object.

Return value:

A promise with response data, or a plain data object.

saveAll()

Is used for saving all changes made on the client side at once. Is triggered when DataProcessor saveAll method is called.

Parameters:

  • view - object - the component you work with;
  • update - array - an array of changed records, each of which contains a data object, the ID of the record and the name of the operation;
  • dp - object - DataProcessor object;

Return value:

A promise with response data, or a plain data array.

result()

Called after data are saved and a server-side response is received.

Parameters:

  • state - object - the operation state;
  • view - object - the component you work with;
  • dp - object - DataProcessor object;
  • text - string - the text of a server-side response;
  • data - object - raw data of a server-side response;
  • loader - object - an XHR loader object.

Return value:

void

Back to top