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 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'], function (Dep) {
return Dep.extend({
// called on initialization
init: function () {
this.controlFields();
// Invoke controlFields method every time assignedUserId gets changed.
this.recordView.listenTo(
this.model,
'change:assignedUserId',
() => this.controlFields()
);
// 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);
}
}
);
},
controlFields: function () {
// 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 for enum/array/multi-enum/checklist fields
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');
},
});
});
Clear cache after all.
!!! 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.
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"
]
}