Creating a detail with selection from lookup
Glossary Item Box
Introduction
Details are elements of section edit pages. Details display records bound to the current section record by a lookup field. These can be, for example, records from other sections, whose primary objects contain lookup columns linked to the primary object of the current section. Details are displayed on tabs of section edit pages.
More information about details is available in the “Details” article of the “Application interface and structure” section.
Since a detail with selection from lookup is not a standard bpm’online detail, it is not enough to use section wizard to add it to the section. Below we will describe a way of adding such a detail to a section edit page.
To add a custom detail with selection from lookup to an existing section:
- Create a detail object schema.
- Create a detail via detail wizard and add it to the section.
- Configure the detail schema.
- Set up detail fields.
Case description
Create the [Acceptance certificates] custom detail on the [Delivery] tab of the [Orders] section. The detail should display the list of documents – acceptance certificates for the current order.
Source code
You can download the package with case implementation using the following link.
Case implementation algorithm
1. Creating a detail object schema
Run the [Add] – [Object] menu command on the [Schemas] tab of the [Configuration] section (Fig. 1).
Fig. 1. Adding a detail object schema
Select the “Base object” as the parent object (Fig. 2).
Object properties:
- [Name] – “UsrCourierCertInOrder”
- [Title] – “Acceptance certificates for deliveries of orders”
Find more information about object schema property setup in object designer in the “Workspace of the Object Designer” article.
Fig. 2. Setup of detail object schema properties
Add the [Order] lookup column to the object schema establishing connection with the [Orders] section and the [Document] lookup column containing the acceptance certificate. Mark both columns as “required” to avoid adding empty records. Column setup is shown in fig. 3 and fig. 4.
Fig. 3. The [Order] column property setup
Fig. 4. The [Document] column property setup
Save and publish the object schema.
2. Creating a detail and adding it to the section
Via detail wizard create the [Acceptance certificates] detail (Fig. 5). Add the detail to the [Delivery] tab of the [Orders] section page via section wizard (Fig. 6).
Fig. 5. Creating the detail
Fig. 6. Adding the detail to the section
As a result, the UsrSchema1Detail detail schema and the OrderPageV2 section replacing schema will be created in the development package.
ATTENTION
We recommend changing the name of the detail schema to a more unique name, since the auto generated name can be duplicated in a different development package. We replaced the name for UsrCourierCertDetail in the current case.
Change the detail schema name for a new one in the OrderPageV2 section replacing schema.
3. Configuring the detail
Change the source code of the created detail schema:
- Add dependency from the ConfigurationEnums module.
- Add the onDocumentInsert(), onCardSaved() event handler-methods, the openDocumentLookup() method of calling the modal lookup window and additional data control methods.
- Add the necessary configuration objects to the diff modification array.
The Terrasoft.EntitySchemaQuery class is used for executing database queries in the current case. You can learn more about using EntitySchemaQuery in the “The use of EntitySchemaQuery for creation of queries in database” article. To simplify the case, we blocked the detail menu options that enable editing and copying detail list records.
Source code of the detail schema:
// Defining the shcema and setting up its dependencies from other modules. define("UsrCourierCertDetail", ["ConfigurationEnums"], function(configurationEnums) { return { // Name of the detail object schema. entitySchemaName: "UsrCourierCertInOrder", // Detail schema methods. methods: { //Returns columns selected by query. getGridDataColumns: function() { return { "Id": {path: "Id"}, "Document": {path: "UsrDocument"}, "Document.Number": {path: "UsrDocument.Number"} }; }, //Configures and displays modal lookup window. openDocumentLookup: function() { //Configuration object var config = { // Name of the object schema whose records will be displayed in the lookup. entitySchemaName: "Document", // Multiple selection option. multiSelect: true, // Columns used in the lookup, e.g., for sorting. columns: ["Number", "Date", "Type"] }; var OrderId = this.get("MasterRecordId"); if (this.Ext.isEmpty(OrderId)) { return; } // The [EntitySchemaQuery] class instance. var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { // Setting up the root schema. rootSchemaName: this.entitySchemaName }); // Adding the [Id] column. esq.addColumn("Id"); // Adding the [Id] column for the [Document] schema. esq.addColumn("Document.Id", "DocumentId"); // Creating and adding filters to query collection. esq.filters.add("filterOrder", this.Terrasoft.createColumnFilterWithParameter( this.Terrasoft.ComparisonType.EQUAL, "UsrOrder", OrderId)); // Receiving the whole record collection and its display in the modal lookup window. esq.getEntityCollection(function(result) { var existsDocumentsCollection = []; if (result.success) { result.collection.each(function(item) { existsDocumentsCollection.push(item.get("DocumentId")); }); } // Adding filter to the 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 of the modal lookup window this.openLookup(config, this.addCallBack, this); }, this); }, // Event handler of saving the edit page. onCardSaved: function() { this.openDocumentLookup(); }, //Opens the document lookup if the order edit page has been saved. 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 the selected products. addCallBack: function(args) { // Class instance of the BatchQuery package query. var bq = this.Ext.create("Terrasoft.BatchQuery"); var OrderId = this.get("MasterRecordId"); // Collection of the selected documents from the lookup. this.selectedRows = args.selectedRows.getItems(); // Collection passed over to query. this.selectedItems = []; // Copying the 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 the package query if it is not empty. if (bq.queries.length) { this.showBodyMask.call(this); bq.execute(this.onDocumentInsert, this); } }, //Returns query for adding the current object. getDocumentInsertQuery: function(item) { var insert = Ext.create("Terrasoft.InsertQuery", { rootSchemaName: this.entitySchemaName }); insert.setParameterValue("UsrOrder", item.OrderId, this.Terrasoft.DataValueType.GUID); insert.setParameterValue("UsrDocument", item.DocumentId, this.Terrasoft.DataValueType.GUID); return insert; }, //Method called when adding records to the detail record 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 records from the detail record list. deleteRecords: function() { var selectedRows = this.getSelectedItems(); if (selectedRows.length > 0) { this.set("SelectedRows", selectedRows); this.callParent(arguments); } }, // Hide the [Copy] menu option. getCopyRecordMenuItem: Terrasoft.emptyFn, // Hide the [Edit] menu option. getEditRecordMenuItem: Terrasoft.emptyFn, // Returns the default filter column name. getFilterDefaultColumnName: function() { return "UsrDocument"; } }, // Modification array. diff: /**SCHEMA_DIFF*/[ { // Operation type - merging. "operation": "merge", // Name of the schema element under operation. "name": "DataGrid", // The object, whose properties will be combined with the schema element properties. "values": { "rowDataItemMarkerColumnName": "UsrDocument" } }, { // Operation type - merging. "operation": "merge", // Name of the schema element under operation. "name": "AddRecordButton", // The object, whose properties will be combined with the schema element properties. "values": { "visible": {"bindTo": "getToolsVisible"} } } ]/**SCHEMA_DIFF*/ }; } );
4. Setting up detail list columns
At this stage the detail is completely operable but contact records are not displayed on the detail as the display columns are not specified. Call the detail action menu and set up the column display (fig. 7).
Fig. 7. Detail action menu
As a result, the new detail will enable adding records from the document lookup via the modal window (Fig. 8).
Fig. 8. Case result
See also
- Creating a detail in wizards
- Adding a detail with an editable list
- Adding an edit page detail
- Creating a custom detail with fields