Skip to content

Dynamic Handler (complex dynamic forms)

Dynamic Handler provides the ability to manipulate the form (detail/edit views) appearance.

Note that you can make forms dynamic with Dynamic Logic feature. Dynamic Handler is intended for more complex tasks where Dynamic Logic can be useless.

An example for the Account entity type.

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

{
    "dynamicHandler": "custom:account-dynamic-handler"
}

Create a file client/custom/src/account-dynamic-handler.js:

define('custom:account-dynamic-handler', ['dynamic-handler'], (Dep) => {

    return class extends Dep {

        // Called on initialization.
        init() {
            this.control();

            // Invoke 'control' method every time assignedUserId gets changed.
            this.recordView.listenTo(this.model, 'change:assignedUserId', () => this.control());

            // Changing another attribute on status change.
            this.recordView.listenTo(this.model, 'change:status', (model, value, options) => {
                if (!options.ui) {
                    // Skip if the change was initiated not by a user interaction.
                    // Important.
                    return;
                }

                if (value === 'Some Status') {
                    setTimeout(() => this.model.set('someField', 'someValue'), 1);
                }
            });
        }

        control() {        
            // if assigned user is not empty
            if (this.model.get('assignedUserId')) {                
                this.recordView.showField('sicCode');

                this.recordView.setFieldRequired('type');
                this.recordView.setFieldReadOnly('teams');

                // set options
                // actual for enum/array/multi-enum/checklist/varchar fields types
                this.recordView.setFieldOptionList('type', ['Test', 'Hello']);

                this.recordView.showPanel('activities');

                return;
            }

            this.recordView.hideField('sicCode');
            this.recordView.setFieldNotRequired('type');
            this.recordView.setFieldNotReadOnly('teams');
            this.recordView.setFieldOptionList('type', ['Test']);
            this.recordView.hidePanel('activities');
        }
    }
});

Then, clear cache.

Note

If you set model attributes from a model-change listener callback, you might need to use setTimeout with a zero or a small interval value. It will prevent some side effects.

Multiple dynamic handlers

It's possible to add multiple dynamic handlers to for one entity type. This allows different extensions to have their own dynamic handler.

In metadata > YourEntityType > clientDefs:

{
    "dynamicHandlerList": [
        "__APPEND__",
        "custom:my-dynamic-handler"
    ]
}

Record view methods

The list of record view methods that may be useful in a dynamic handler.

  • hideField
  • showField
  • setFieldReadOnly
  • setFieldNotReadOnly
  • setFieldRequired
  • setFieldNotRequired
  • setFieldOptionList
  • resetFieldOptionList
  • showPanel
  • hidePanel
  • stylePanel
  • unstylePanel

See also