Client schema (Classic UI)
A client view model schema is a visual module schema that implements the front-end part of Creatio. A client view model schema is a configuration object for generating views and view models by ViewGenerator
and ViewModelGenerator
. Learn more about module types and their specificities in a separate article: Client module types.
Develop a client schema
Ways to develop client view model schemas:
- The Configuration section. Learn more about development in the Configuration section in a separate article: View model schema.
- Section Wizard. Learn more about section development in the Section Wizard in user documentation: Create a new section
- Detail Wizard. Learn more about detail development in the Detail Wizard in user documentation: Create a detail.
Structure elements of the client schema:
- Auto-generated code. Contains the description of the schema, its dependencies, localized resources, and messages.
- Rendering styles. Only available in some types of client schemas.
- The schema source code. A syntactically correct JavaScript code that defines the module.
Use marker comments in the schema source code for the diff
, modules
, details
, and businessRules
properties.
The purpose of marker comments is to uniquely identify the client schema properties. When you open the Wizard, Creatio validates the presence of marker comments as shown in the table below.
Validation rules for marker comments in client schemas
Schema type | Required marker comments |
---|---|
|
|
|
|
| |
| |
|
Client schema properties
The source code of client schemas has a generic structure available below.
define("ExampleSchema", [], function() {
return {
entitySchemaName: "ExampleEntity",
mixins: {},
attributes: {},
messages: {},
methods: {},
rules: {},
businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
};
});
After the module is loaded, Creatio calls the anonymous factory function, which returns the schema configuration object. Properties of the configuration object schema:
-
entitySchemaName
. The name of the entity schema used by the current client schema. -
mixins
. A configuration object that contains a mixin declaration. -
attributes
. A configuration object that contains schema attributes. -
messages
. A configuration object that contains schema messages. -
methods
. A configuration object that contains schema methods. -
rules
. A configuration object that contains schema business rules. -
businessRules
. A configuration object that contains schema business rules created or modified by the Section Wizard or Detail Wizard. The/**SCHEMA_BUSINESS_RULES*/
marker comments are required since they are necessary for the operation of the Wizards. -
modules
. A configuration object that contains schema modules. The/ ** SCHEMA_MODULES * /
marker comments are required since they are necessary for the operation of the Wizards.noteThe
details
property loads a detail to a page. Since a detail is also a module, we recommend using themodules
property instead. -
diff
. A configuration object array that contains the schema view description. The/**SCHEMA_DIFF*/
marker comments are required since they are necessary for the operation of the Wizards. -
properties
. A configuration object that contains view model properties. -
$-properties
. Automatically generated properties for the attributes of the view model schema.
Schema name (entitySchemaName)
To implement the entity schema name, use the required entitySchemaName
property. Simply specify it in one of the inheritance hierarchy schemas.
define("ClientSchemaName", [], function () {
return {
/* Object schema (model). */
entitySchemaName: "EntityName",
/* ... */
};
});
Mixins (mixins)
A mixin is a class that extends the functions of other classes. JavaScript does not support multiple inheritances. However, mixins let you extend the schema functionality without duplicating the logic used in the schema methods. You can use the same set of actions in different client schemas of Creatio. Create a mixin to avoid duplicating the code in each schema. Mixins are different from other modules added to the dependency list in the way of calling their methods from the module schema. You can call to their methods directly, much like those of a schema. Use the mixins
property to implement mixins.
Mixin management procedure:
- Create a mixin.
- Assign a name to the mixin.
- Connect the corresponding name array.
- Implement the mixin functionality.
- Use the mixin in the client schema.
Create a mixin
Create a mixin similarly to an object schema.
Assign a name to the mixin
When naming mixins, use an -able suffix in the schema name. For example, name a mixin that enables serializing in the components Serializable
. If a mixin name cannot end "-able," end the schema name in Mixin.
Do not use words like Utilities
, Extension
, Tools
, or similar in the names. They make the purpose of the mixin impossible to discern based on the mixin name.
Connect the namespace
Enable a corresponding name array in the mixin (Terrasoft.configuration.mixins
for the configuration, Terrasoft.core.mixins
for the core).
Implement the mixin functionality
Mixins cannot depend on the internal implementation of the schema to which to apply them. Mixins must be independent mechanisms that receive a set of parameters, process them, and, if needed, return a result. Design mixins as modules that must be connected to the schema dependency list when the define()
function declares the schema.
View the mixin structure below.
define("MixinName", [], function() {
Ext.define("Terrasoft.configuration.mixins.MixinName", {
alternateClassName: "Terrasoft.MixinName",
/* Mixin functionality. */
});
return Ext.create(Terrasoft.MixinName);
})
Use the mixin
The mixin implements the functionality needed in the client schema. To receive the set of mixin actions, specify the mixin in the mixins
block of the client schema.
/* MixinName is a module where the mixin class is implemented. */
define("ClientSchemaName", ["MixinName"], function () {
return {
/* SchemaName is the name of the entity. */
entitySchemaName: "SchemaName",
mixins: {
/* Connect the mixin. */
MixinName: "Terrasoft.NameSpace.Mixin"
},
attributes: {},
messages: {},
methods: {},
rules: {},
modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
};
});
Once you connect the mixin, you can use its methods, attributes, and fields in the client schema as if they were part of the client schema. That way, method calls are more concise than when using a separate schema. For example, getDefaultImageResource
is a mixin function. To call the getDefaultImageResource
mixin function in the custom schema to which the mixin is connected, use this.getDefaultImageResource();
.
To overload a mixin function, create a function with the same name in the client schema. As a result, Creatio will use the function of the schema, and not that of the mixin, when calling.
Attributes (attributes)
Use the attributes
property to implement attributes.
Messages (messages)
The purpose of messages is to organize data exchange between modules. Use the messages
property to implement messages. Use the Terrasoft.MessageMode
enumeration to set the message mode.
Message mode types
Message mode | Description | Connection |
---|---|---|
Address | Address messages are only received by the last subscriber. | To switch to address mode, set the |
Broadcasting | Broadcasting messages are received by all subscribers. | To switch to broadcasting |
Aside from modes, you can also specify the message direction.
Message direction types
Message direction | Description | Connection |
---|---|---|
Publishing | The message can only be published, i. e., it is an outbound message. | To set the message direction to publishing, set the |
Subscription | The message can only be subscribed to, i. e., it is an inbound message. | To set the message direction to subscription, set the |
Bidirectional | The bidirectional mode enables publishing of and subscription to the same message in different instances of a single class or within a single schema inheritance hierarchy. The same message cannot be announced with different directions in a single schema inheritance hierarchy. Learn more about using bidirectional messages in cases where that is a requirement in a separate article: Sandbox. | Corresponds to |
Message publication
Declare a message with the "publishing" direction in the schema where you want to publish the message.
messages: {
/* Message name. */
"GetColumnsValues": {
/* Set the message mode to address. */
mode: this.Terrasoft.MessageMode.PTP,
/* Set the message direction to "publishing." */
direction: this.Terrasoft.MessageDirectionType.PUBLISH
}
}
Publishing is done by calling the publish
method from the sandbox
class instance.
// GetColumnsValues method that gets the message publishing result.
getColumnsValues: function(argument) {
/* Message publishing.
GetColumnsValues is the message name.
argument is the argument passed to the handler function of the subscriber. An argument is an object with the message parameters.
key is an array of message filtering tags. */
return this.sandbox.publish("GetColumnsValues", argument, ["key"]);
}
Message publishing can return the handler function results only in the address mode.
Message subscription
Declare a message with the "subscription" direction in the subscription schema.
messages: {
/* Message name. */
"GetColumnsValues": {
/* Set the message mode to address. */
mode: this.Terrasoft.MessageMode.PTP,
/* Set the message direction to "subscription." */
direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
}
}
The subscription is made by calling the subscribe
method in the sandbox
class instance.
/* GetColumnsValues is the message name.
messageHandler is the message handler function.
context is the execution scope of the handler function.
key is an array of message filtering tags. */
this.sandbox.subscribe("GetColumnsValues", messageHandler, context, ["key"]);
In the address mode, the messageHandler
method returns the object, which is processed as the result of message publishing. In broadcasting mode, the messageHandler
method does not return a value.
- messageHandler method (address mode)
- messageHandler method (broadcast mode)
methods: {
messageHandler: function(args) {
/* Return an object to process as a message publishing result. */
return { };
}
}
methods: {
messageHandler: function(args) {
}
}
Methods (methods)
To implement a method, use the methods
property.The property contains a collection of methods that form the schema business logic and affect the view model. By default, the scope of methods is the scope of view model.
The purpose of the methods
property.
- Create new methods.
- Extend the basic methods of parent schemas.
Business rules (rules and businessRules)
Business rules are Creatio mechanisms that let you customize the behavior of fields on a page or detail. To implement business rules, use the rules
and businessRules
properties. Use the businessRules
property for business rules created or modified in the Section Wizard or the Detail Wizard.
The purposes of business rules:
- Hide or show fields.
- Lock or unlock fields for editing.
- Make fields required or optional.
- Filter lookup fields based on values in other fields.
Creatio implements the business rule functionality in the BusinessRuleModule
client module. To use the business rule functionality, add BusinessRuleModule
to the list of schema dependencies.
define("CustomPageModule", ["BusinessRuleModule"], function(BusinessRuleModule) {
return {
/* Implement the client module. */
};
});
The RuleType
enumeration of the BusinessRuleModule
module defines business rule types.
Specifics of business rules
Specifics of business rule declaration:
- Describe business rules in the
rules
schema property. - Apply business rules to view model columns and not to controls.
- Name each business rule.
- Set business rule parameters in the configuration object.
Business rules defined in the businessRules
property have the following features:
- They are generated by the Section or Detail Wizards.
- When you create a new business rule, the corresponding Wizard generates the name and adds the rule to the client schema of the record page view model.
- Creatio does not use the
BusinessRuleModule
enumerations when describing generated business rules. - The
/**SCHEMA_BUSINESS_RULES*/
marker comments are required since they are necessary for the operation of the Wizards. - They have a higher priority during runtime.
- When a business rule is disabled, Creatio sets the
enabled
property of the configuration object tofalse
. - When a business rule is removed, the configuration object remains in the client schema of the record page view model, but Creatio sets the
removed
property totrue
.
We do not recommend editing the businessRules
property of the client schema.
Edit an existing business rule
After a Wizard edits a manually created business rule, the business rule‘s configuration object in the rules
property of the record page view model remains unchanged. At the same time, a new version of the business rule configuration object with the same name is created in the businessRules
property.
When Creatio processes a business rule during runtime, the business rule defined in the businessRules
property takes precedence. Subsequent changes to this business rule in the rules
property will not affect Creatio in any way.
Changes made to the configuration object of the businessRules
property take precedence when you delete or disable a business rule.
Modules (modules)
To implement modules, use the modules
property. Its configuration object declares and configures modules and details loaded on the page. The / ** SCHEMA_MODULES * /
marker comments are required since they are necessary for the operation of the Wizards.
The details
property loads a detail to a page. Since a detail is also a module, we recommend using the modules
property instead.
modules: /**SCHEMA_MODULES*/{
/* Load the module.
Module title. Must be the same as the name property in the diff array. */
"TestModule": {
/* Optional. The ID of the module to load. If not specified, Creatio will generate it automatically.*/
"moduleId": "myModuleId",.
/* If no parameter is specified, Creatio will use BaseSchemaModuleV2 for loading. */
"moduleName": "MyTestModule",
/* Configuration object. When the module is loaded, the object is passed as instanceConfig. The object stores a set of initial parameter values for the module. */
"config": {
"isSchemaConfigInitialized": true,
"schemaName": "MyTestSchema",
"useHistoryState": false,
/* Additional module parameters. */
"parameters": {
/* Parameters passed to the schema during the initialization. */
"viewModelConfig": {
masterColumnName: "PrimaryContact"
}
}
}
},
/* Load the detail.
Detail name. */
"Project": {
/* Detail schema name. */
"schemaName": "ProjectDetailV2",
"filter": {
/* The column of the section object schema. */
"masterColumn": "Id",
/* The column of a detail object schema. */
"detailColumn": "Opportunity"
}
}
}/**SCHEMA_MODULES*/
Array of modifications (diff)
To implement an array of modifications, use the diff
property, which contains an array of configuration objects. The purpose of the array of modifications is to build a representation of the module in the Creatio interface. Each element in the array represents properties from which Creatio generates various interface controls. The /**SCHEMA_DIFF*/
marker comments are required since they are necessary for the operation of the Wizards.
Alias mechanism
When developing new versions, you sometimes need to move page elements to new zones. In situations where users have customized the record page, such changes can have unpredictable consequences. The alias
mechanism interacts with the diff
builder to provide partial backward compatibility when changing the UI in new product versions. The builder is the json-applier
class that merges base schema and client extension schema parameters.
The alias
property contains data about the previous name of the element. Creatio creates the diff
array of modifications based on that data, considering not only elements with a new name but also with the name specified in alias
. In essence, alias
is a configuration object that links the new and old elements. When creating a diff
array of modifications, the alias
configuration object can disallow application of some properties and operations to the element where it is declared. You can add the alias
object to any element in the diff
array of modifications.
Relationship between a view and model
The purpose of the bindTo
property is to indicate the relationship between a view model attribute and a view object property.
Declare the property in the values
property of the configuration objects in the diff
array of modfications.
View an example that uses the bindTo
property below.
diff: [
{
"operation": "insert",
"parentName": "CombinedModeActionButtonsCardLeftContainer",
"propertyName": "items",
"name": "MainContactButton",
/* Properties passed to the component’s constructor. */
"values": {
/* Set the type of the added element to button. */
"itemType": Terrasoft.ViewItemType.BUTTON,
/* Bind the button title to the localizable schema string. */
"caption": {bindTo: "Resources.Strings.OpenPrimaryContactButtonCaption"},
/* Bind the button click handler method. */
"click": {bindTo: "onOpenPrimaryContactClick"},
/* The display style of the button. */
"style": Terrasoft.controls.ButtonEnums.style.GREEN,
/* Bind the button availability property. */
"enabled": {bindTo: "ButtonEnabled"}
}
}
]
Tabs are objects that contain the tabs
value in their propertyName
property.
Creatio implements an alternative way to use the bindTo
property for tab titles.
...
{
"operation": "insert",
"name": "GeneralInfoTab",
"parentName": "Tabs",
/* Imply that the object is a tab. */
"propertyName": "tabs",
"index": 0,
"values": {
/* $ replaces usage of bindTo: {...}. */
"caption": "$Resources.Strings.GeneralInfoTabCaption",
"items": []
}
},
...
diff
property declaration rules
-
Best use of converters.
A converter is a function executed in the
viewModel
environment. A converter accepts the values of theviewModel
property and returns a result of the corresponding type. To ensure that Wizards operate correctly, format thediff
property value in JSON. Therefore, the value of the converter must be the name of the view model method rather than an inline function.- Correct use of the converter
- Incorrect use of the converter
methods: {
messageHandler: function(args) {
/* Return an object to process as a message publishing result. */
return { };
}
}diff: /**SCHEMA_DIFF*/[
{
/* ... */
"bindConfig": {
"converter": function(val) {
/* ... */
}
}
}
]/**SCHEMA_DIFF*/- Correct use of the generator
- Incorrect use of the generator
methods: {
someFunction: function(val) {
/* ... */
}
},
diff: /**SCHEMA_DIFF*/[
{
/* ... */
"values": {
"generator": "someFunction"
}
/* ... */
}
]/**SCHEMA_DIFF*/diff: /**SCHEMA_DIFF*/[
{
/* ... */
"values": {
"generator": function(val) {
/* ... */
}
}
}
]/**SCHEMA_DIFF*/ -
Parent element.
The parent element (container) is the DOM element where the module renders its view. To ensure that the Wizards operate as intended, place a single child element in the parent container.
- Example of the correct placement of a view in the parent element
- Example of the incorrect placement of a view in the parent element
<div id="OpportunityPageV2Container" class="schema-wrap one-el" data-item-marker="OpportunityPageV2Container">
<div id="CardContentWrapper" class="card-content-container page-with-left-el" data-item-marker="EntityLoaded"></div>
</div><div id="OpportunityPageV2Container" class="schema-wrap one-el" data-item-marker="OpportunityPageV2Container">
<div id="CardContentWrapper" class="card-content-container page-with-left-el" data-item-marker="EntityLoaded"></div>
<div id="DuplicateContainer" class="DuplicateContainer"></div>
</div>When you add, change, move an element (
insert
,merge
,move
operations), specify theparentName
property (the parent element’s name) in thediff
property.- Example of the correct definition of the view element in the diff property
- Example of the incorrect definition of the view element in the diff property
{
"operation": "insert",
"name": "SomeName",
"propertyName": "items",
"parentName": "SomeContainer",
"values": {}
}{
"operation": "insert",
"name": "SomeName",
"propertyName": "items",
"values": {}
}If the
parentName
property is missing, the Wizard will be unable to configure the page. Creatio will display a corresponding error message.The value of the
parentName
property must match the name of the parent element in the corresponding base page schema. For example, this isCardContentContainer
for record pages.If you specify the name of a non-existent container element as the parent element in the
parentName
property, a "Schema cannot have more than one root object" error will occur, since the added element will be placed in the root container. -
Unique names.
Each element in the
diff
array must have a unique name.- Example of the correct addition of elements to a diff array
- Example of the incorrect addition of elements to a diff array
{
"operation": "insert",
"name": "SomeName",
"values": { }
},
{
"operation": "insert",
"name": "SomeSecondName",
"values": { }
}{
"operation": "insert",
"name": "SomeName",
"values": { }
},
{
"operation": "insert",
"name": "SomeName",
"values": { }
} -
Placement of view elements.
To ensure the view elements are customizable and changeable, place them on the layout grid. In Creatio, each row of the layout grid has 24 cells (columns). Use the
layout
property to place elements on the grid.Grid element properties:
column
. The index of the left column.row
. The index of the top row.colSpan
. The number of spanned columns.rowSpan
. The number of spanned rows.
Example that places elements{
"operation": "insert",
"parentName": "ParentContainerName",
"propertyName": "items",
"name": "ItemName",
"values": {
/* Element placement. */
"layout": {
/* Start at column zero. */
"column": 0,
/* Place in the fifth row of the grid. */
"row": 5,
/* Span 12 columns wide. */
"colSpan": 12,
/* Occupy one row. */
"rowSpan": 1
},
"contentType": Terrasoft.ContentType.ENUM
}
} -
Number of operations.
If you change the client schema without a Wizard, we recommend adding no more than one operation per schema element to ensure that the Wizard operates as intended.
Properties (properties)
To implement properties, use the properties
property, which contains a JavaScript object.
View an example that uses the properties
property in the SectionTabsSchema
schema of the NUI
package below.
define("SectionTabsSchema", [], function() {
return {
...
/* Declare the properties property. */
properties: {
/* The parameters property. Array. */
parameters: [],
/* modulesContainer property. Entity. */
modulesContainer: {}
},
methods: {
...
/* Initialization method. Always executed first. */
init: function(callback, scope) {
...
/* Call the method uses the view model properties. */
this.initContainers();
...
},
...
/* The method where to use the properties. */
initContainers: function() {
/* Use the modulesContainer property. */
this.modulesContainer.items = [];
...
/* Use the parameters property. */
this.Terrasoft.each(this.parameters, function(config) {
config = this.applyConfigs(config);
var moduleConfig = this.getModuleContainerConfig(config);
var initConfig = this.getInitConfig();
var container = viewGenerator.generatePartial(moduleConfig, initConfig)[0];
this.modulesContainer.items.push(container);
}, this);
},
...
},
...
}
});
See also
Create a new section (user documentation)
Create a detail (user documentation)