EspoCRM framework provides abilities to define custom views for certain entity types. They must be defined in clientDefs
category of metadata.
custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json
{
"views": {
"list": "custom:views/your-entity-type/list",
"detail": "custom:views/your-entity-type/detail",
"edit": "custom:views/your-entity-type/edit"
},
"recordViews": {
"list": "custom:views/your-entity-type/record/list",
"detail": "custom:views/your-entity-type/record/detail",
"edit": "custom:views/your-entity-type/record/edit"
}
}
client/custom/src/views/your-entity-type/record/detail.js
The view 'views/record/detail' contains all panels with fields, relations and other data you can see on detail view. It doesn't contain header and buttons in the top-right corner.
define('custom:views/your-entity-type/record/detail', ['views/record/detail'], (DetailRecordView) => {
return class extends DetailRecordView {
// custom template, omit if you don't need it
// template = 'custom:your-entity-type/record/detail'
// custom central view, omit if you don't need it
// middleView = 'custom:views/your-entity-type/record/detail-middle'
// custom side column view, omit if you don't need it
// sideView = 'custom:views/your-entity-type/record/detail-side'
// custom bottom view, omit if you don't need it
// bottomView = 'custom:views/your-entity-type/record/detail-bottom'
setup() {
super.setup();
this.hideField('someField');
this.showField('someField');
// custom initialization logic, like binding listening to model changes
this.listenTo(this.model, 'change:myField', () => {
this.model.set('anotherField', this.model.get('myField') + ' Hello');
this.hideField('someField');
this.showField('someField');
this.setFieldRequired('someField');
this.setFieldNotRequired('someField');
this.setFieldReadOnly('someField');
this.setFieldNotReadOnly('someField');
this.hidePanel('activities');
this.showPanel('history');
});
}
afterRender() {
super.afterRender();
}
}
});
You are able to create a custom template with the following path: client/custom/res/templates/your-entity-type/record/detail.tpl
client/custom/src/views/your-entity-type/detail.js
Detail view contains a record view and header view.
client/custom/src/views/your-entity-type/edit.js
client/custom/src/views/your-entity-type/record/edit.js
The same as detail but it is used when record is being created or edited not in inline-edit mode.
client/custom/src/views/your-entity-type/list.js
List view contains Record/List view, Header and Search Form View.
client/custom/src/views/your-entity-type/record/list.js
The views 'views/list/record' contains rows of records.
It's worth to mention that you need to inherit your view class from specific class for your entity if one already exists.
define('custom:views/email/record/detail', ['views/email/record/detail'], (EmailDetailRecordView) => {
return class extends EmailDetailRecordView {}
});
Custom views for specific fields should be specified in entityDefs section of metadata.
Example for Address field of Account entity type.
custom/Espo/Custom/Resources/metadata/entityDefs/Account.json
{
"fields": {
"address": {
"view": "custom:views/account/fields/address"
}
}
}
client/custom/src/views/account/fields/address.js
define('custom:views/fields/address', ['views/fields/address'], (AddressFieldView) => {
return class extends AddressFieldView {
setup() {
super.setup();
// some initialization
}
afterRender() {
super.afterRender();
// your customizations executed after the field is rendered
}
}
});