Skip to content

Client controller & routing

Custom controller

Define a custom controller for the needed entity type (Account in our example).

Create a file custom/Espo/Custom/Resources/metadata/clientDefs/Account.json:

{
    "controller": "custom:controllers/account"
}

Create a file client/custom/src/controllers/account.js:

define('custom:controllers/account', ['controllers/record'], function (Dep) {

    return Dep.extend({

        actionHello: function (options) {
            console.log('action: hello');
            console.log(options);
        },

        actionTest: function (options) {
            if (!options.id) {
                throw new Espo.Exceptions.NotFound();
            }

            console.log('action: test');
            console.log(options);
        },
    });
});

Clear cache.

If you open in the browser URL your-espo-url#Account/hello it will execute actionHello method.

#Account/hellooptions variable value is an empty object #Account/hello/p1=one&p2=twooptions variable value is an object {p1: 'one', p2: 'two'}

Custom route

Create a file custom/Espo/Custom/Resources/metadata/app/clientRoutes.json:

{
    "Account/test/:id": {
        "params": {
            "controller": "Account",
            "action": "test"
        },
        "order": 1
    }
}

Clear cache.

If you open in the browser URL your-espo-url#Account/test/myId it will execute actionTest method. Argument options will be the object {id: 'myId'}.

Note that it's also possible to specify a specific controller class in controller instead of a scope name. As of v8.2.

Rendering view

In controller:

    actionTest(options) {
        if (!options.id) {
            throw new Espo.Exceptions.NotFound();
        }

        const id = options.id;

        // we need to define the view in client/custom/src/views/account/test.js
        const viewName = 'custom:views/account/test'; 

        // this will render view in the main container element #main
        // id will be passed to the view
        this.main(viewName, {id: id});
    }

Create a view client/custom/src/views/account/test.js:

define('custom:views/account/test', ['view'], (Dep) => {

    return class extends Dep {

        templateContent = 'Id: {{id}}, name: {{name}}'

        data() {
            return {
                id: this.options.id,
                name: this.model.get('name'),
            }
        }

        setup() {
            this.wait(
                this.getModelFactory().create('Account')
                    .then(model => {
                        this.model = model;
                        model.id = this.options.id;

                        return model.fetch();
                    })
            );
        }       
    }
});