Adding a detail with a lookup
Glossary Item Box
General provisions
Details are special elements of section edit pages, which display additional data that is not stored in the fields of the section primary object. The details are displayed on the edit page tabs in the tab container.
There are four basic types of details:
- details with a record edit page;
- details with edit fields;
- details with an editable list;
- details with a lookup.
For more information on details, please see the "Details" article in the "Application interface and structure" section.
A detail with a lookup not a standard bpm'online detail and can not be added to sections using the Detail Wizard. Below is a step-by-step procedure for adding a detail with editable list to an edit page.
General procedure for adding a detail with a lookup to an existing section
To add a detail with a lookup:
- Create a detail object schema.
- Create and configure the detail schema.
- Set up the detail in a replacing section edit page schema.
- Set up the detail fields.
Case description
Create a custom detail [Acceptance certificates] on the [Delivery] tab of the [Orders] section record page. The detail must display a list of documents (Acceptance certificates) for the current order.
Case implementation algorithm
1. Create detail object schema
In the settings mode, go to the [Configuration] section, open the [Schemas] tab and execute the [Add] > [Object] menu command (Fig. 1).
Fig. 1. Adding a detail object schema
Select the base BaseEntity object (located in the Base package) as the parent for the created schema (Fig 2). The rest of the properties must be set up as shown in Fig. 2. In the [Package] property, the system will specify the current package name. For more information on setting schema properties in the Object Designer, please see "Workspace of the Object Designer" article.
Fig. 2. Setup of detail object schema properties
Add an [Order] lookup column which will connect the detail object with the section object, and a [Document] lookup column where the acceptance certificate document will be stored. Both columns must be made to be required. Column properties setup is shown in Fig. 3 and Fig. 4.
Fig. 3. Specifying the properties of the [Order] column
Fig. 4. Specifying the properties of the [Document] column
Object schema must be saved and published.
2. Create detail schema
In the settings mode, go to the [Configuration] section, open the [Schemas] tab and execute the [Add] > [Module] menu command (Fig. 1).
The new module must inherit the functionality of the BaseGridDetailV2 base schema for details with lists, which is available in the NUI package. To do this, specify this schema as the parent for the created detail schema (Fig. 5). The rest of the properties must be set up as shown in Fig. 5. In the [Package] property, the system will specify the current package name.
Fig. 5. Detail schema properties
Set the Acceptance certificates value for the [Caption] localizable string of the detail schema (Fig. 6). The [Caption] string contains the detail title, shown on the edit page.
Fig. 6. Setting the value of the [Caption] string
To make the detail be filled in from a lookup, make the following changes to the detail schema:
- Add dependencies from the ConfigurationЕnums module.
- Add the onDocumentInsert and onCardSaved event handler methods, openDocumentLookup lookup window method and auxiliary data management methods.
- Add required configuration objects to the array of modifications.
Below is the detail schema source code (with comments), which must be added to the [Source code] section of the client module designer. The example below uses the Terrasoft.EntitySchemaQuery class to perform queries to the database. For more information on how to use EntitySchemaQuery, please see the "The use of EntitySchemaQuery for creation of queries in database" article in the "Working with data" section. Detail menu items for editing and copying records were disabled to simplify the case.
// Define schema and set its dependencies from other modules. define("CourierCertDetail", ["ConfigurationEnums"], function(configurationEnums) { return { // Detail object schema name. entitySchemaName: "CourierCertInOrder", // Detail schema methods. methods: { //Returns columns, which were selected by query. getGridDataColumns: function() { return { "Id": {path: "Id"}, "Document": {path: "Document"}, "Document.Number": {path: "Document.Number"} }; }, //Configures and displays lookup modal window. openDocumentLookup: function() { //Configuration object var config = { // Object schema name, whose records are displayed in lookup. entitySchemaName: "Document", // Indicates whether multiple selection is available. multiSelect: true, // Columns that will be used in lookup (e.g., for sorting). columns: ["Number", "Date", "Type"] }; var OrderId = this.get("MasterRecordId"); if (this.Ext.isEmpty(OrderId)) { return; } // Instance of the [EntitySchemaQuery] class. var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { // Root schema setup. rootSchemaName: this.entitySchemaName }); // Adding the [Id] coluln. esq.addColumn("Id"); // Adding the [Id] column of the [Document] schema. esq.addColumn("Document.Id", "DocumentId"); // Creating and adding filters to the query collection. esq.filters.add("filterOrder", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "Order", OrderId)); // Getting the whole collection of records and displaying it in the lookup modal window. esq.getEntityCollection(function(result) { var existsDocumentsCollection = []; if (result.success) { result.collection.each(function(item) { existsDocumentsCollection.push(item.get("DocumentId")); }); } // Ading filter to configuration object. if (existsDocumentsCollection.length > 0) { var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id", existsDocumentsCollection); existsFilter.comparisonType = this.Terrasoft.ComparisonType.NOT_EQUAL; existsFilter.Name = "existsFilter"; config.filters = existsFilter; } // Call lookup modal window this.openLookup(config, this.addCallBack, this); }, this); }, // Event handler for saving edit page. onCardSaved: function() { this.openDocumentLookup(); }, // Opens document lookup if the order edit page was saved earlier. addRecord: function() { var masterCardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]); var isNewRecord = (masterCardState.state === configurationEnums.CardStateV2.ADD || masterCardState.state === configurationEnums.CardStateV2.COPY); if (isNewRecord === true) { var args = { isSilent: true, messageTags: [this.sandbox.id] }; this.sandbox.publish("SaveRecord", args, [this.sandbox.id]); return; } this.openDocumentLookup(); }, // Adding selected documents. addCallBack: function(args) { // Instance of the BatchQuery batch request class. var bq = this.Ext.create("Terrasoft.BatchQuery"); var OrderId = this.get("MasterRecordId"); // Collection of documents selected in the lookup. this.selectedRows = args.selectedRows.getItems(); // Collection passed to query. this.selectedItems = []; // Copying necessary data. this.selectedRows.forEach(function(item) { item.OrderId = OrderId; item.DocumentId = item.value; bq.add(this.getDocumentInsertQuery(item)); this.selectedItems.push(item.value); }, this); // Executing batch request if it is not empty. if (bq.queries.length) { this.showBodyMask.call(this); bq.execute(this.onDocumentInsert, this); } }, //Returns query for adding current object. getDocumentInsertQuery: function(item) { var insert = Ext.create("Terrasoft.InsertQuery", { rootSchemaName: this.entitySchemaName }); insert.setParameterValue("Order", item.OrderId, this.Terrasoft.DataValueType.GUID); insert.setParameterValue("Document", item.DocumentId, this.Terrasoft.DataValueType.GUID); return insert; }, //Method called when adding records to the detail list. onDocumentInsert: function(response) { this.hideBodyMask.call(this); this.beforeLoadGridData(); var filterCollection = []; response.queryResults.forEach(function(item) { filterCollection.push(item.id); }); var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: this.entitySchemaName }); this.initQueryColumns(esq); esq.filters.add("recordId", Terrasoft.createColumnInFilterWithParameters("Id", filterCollection)); esq.getEntityCollection(function(response) { this.afterLoadGridData(); if (response.success) { var responseCollection = response.collection; this.prepareResponseCollection(responseCollection); this.getGridData().loadAll(responseCollection); } }, this); }, // Method called when deleting selected detail records. deleteRecords: function() { var selectedRows = this.getSelectedItems(); if (selectedRows.length > 0) { this.set("SelectedRows", selectedRows); this.callParent(arguments); } }, // Hide the [Copy] menu item. getCopyRecordMenuItem: Terrasoft.emptyFn, // Hide the [Edit] menu item. getEditRecordMenuItem: Terrasoft.emptyFn, // Returns default column name for filter. getFilterDefaultColumnName: function() { return "Document"; } }, // Array of modifications. diff: /**SCHEMA_DIFF*/[ { // Operation type — merge. "operation": "merge", // НName of the schema element, with which the action is performed. "name": "DataGrid", // Object, whose properties will be combined wuth the shema element properties. "values": { "rowDataItemMarkerColumnName": "Document" } }, { // Operation type — merge. "operation": "merge", // Name of the schema element, with which the action is performed. "name": "AddRecordButton", // Object, whose properties will be combined wuth the shema element properties.. "values": { "visible": {"bindTo": "getToolsVisible"} } } ]/**SCHEMA_DIFF*/ }; } );
Save the detail schema to apply the changes.
3. Set up the detail in the replacing section edit page schema
To display the detail on the order edit page, first create a replacing client module, and specify the order edit page OrderPageV2 (located in the Order package) as the parent (Fig. 7). For more information on creating replacing schemas, please see the "Creating a custom client module schema" article.
Fig. 7. Order edit page replacing schema properties
To display the [Acceptance certificates] detail on the [Delivery] tab of the order edit page, add the following source code. In the details section, a new CourierCertDetail model will be defined, and its location on the edit page will be specified in the modification section of the diff array.
define("OrderPageV2", [], function() { return { // Name of the edit page object schema. entitySchemaName: "Order", // List of added details of the edit page. details: /**SCHEMA_DETAILS*/{ // Setup of the [Acceptance certificates] detail. "CourierCertDetail": { // Detail schema name. "schemaName": "CourierCertDetail", // Detail object schema name. "entitySchemaName": "CourierCertInOrder", // Filtering contacts displayed for current order only. "filter": { // Detail object schema column. "detailColumn": "Order", // Section object schema column. "masterColumn": "Id" } } }/**SCHEMA_DETAILS*/, // Array of modifications. diff: /**SCHEMA_DIFF*/[ // Metadata for adding [Acceptance certificates] detail. { "operation": "insert", // Detaail name. "name": "CourierCertDetail", "values": { "itemType": 2, "markerValue": "added-detail" }, // Containers where detail is places. "parentName": "OrderDeliveryTab", "propertyName": "items", // Index in the list of added elements. "index": 3 } ]/**SCHEMA_DIFF*/, methods: {}, rules: {} }; });
To apply the changes, the replacing page schema must be saved.
4. Set up detail list columns
At this stage, the detail is completely operational, however contacts are not displayed on the detail, because the detail list does not have displayed columns specified for it. Go to the detail menu and set up the columns to be displayed (Fig. 8).
Fig. 8. Detail actions menu