Symptoms

When I set up the mobile app, all objects work fine, except for "Activity". When I try to access an activity, the following error is displayed - Uncaught TypeError:Cannot read property “modelName” of undefined.

I tried to delete all columns to add them again (thought maybe the "Type" column is causing this issue) - it didn't work. 

Once I changed the settings, I re-distributed access rights, cleared the cache and re-synchronized with the database. 

Solution

Some of the fields were removed on the activity card, and, most importantly, the “Participants” detail was removed. This detailed is required for correct operation of the "Activities" section.

By default, bpm'online only syncs the activities with the current user specified on the “Participants” detail.

If this detail is removed, the activities may not sync correctly.

A workaround for deleted objects used in parent packages:

- Create a custom schema (e.g., "MobileUtilitiesCustom").

Ext.define("Terrasoft.sdk.RecordPageMetadataApplier.Override", {
 
                override: "Terrasoft.sdk.RecordPageMetadataApplier",
 
 
 
                addEmbeddedDetail: function(modelName, operation) {
 
                               this.embeddedDetails[operation.name] = operation.values;
 
                               var values = operation.values;
 
                               var filter = values.filter;
 
                               var detailName = operation.name;
 
                               Terrasoft.sdk.RecordPage.addEmbeddedDetail(modelName, {
 
                                               name: detailName,
 
                                               title: values.caption,
 
                                               position: values.position,
 
                                               modelName: values.entitySchemaName,
 
                                               primaryKey: filter.masterColumn,
 
                                               foreignKey: filter.detailColumn,
 
                                               hidden: values.hidden
 
                               });
 
                },
 
 
 
                applyMetadata: function() {
 
                               this.callParent(arguments);
 
                               for (var itemName in this.removedMetadataItems) {
 
                                               if (!Terrasoft.util.isGuid(itemName) && Terrasoft.util.String.contains(itemName, "EmbeddedDetail")) {
 
                                                               this.addEmbeddedDetail(this.modelName, {
 
                                                                              name: itemName,
 
                                                                              values: {
 
                                                                                              entitySchemaName: itemName.substring(0, itemName.indexOf("Detail")),
 
                                                                                              filter: {
 
                                                                                                              masterColumn: "Id",
 
                                                                                                              detailColumn: "Id"
 
                                                                                              },
 
                                                                                              hidden: true
 
                                                                              }
 
                                                               });
 
                                               }
 
                               }
 
                }
 
});
 
 
 
Terrasoft.sdk.RecordPage.configureColumn = function(model, columnSetName, columnName, columnConfig) {
 
                var modelConfig = Terrasoft.ApplicationConfig.getModelConfig(model);
 
                var columnSetConfig = modelConfig.columnSets.get(columnSetName);
 
                if (!columnSetConfig) {
 
                               return;
 
                }
 
                var columnSetColumns = Terrasoft.sdk.RecordPage.getColumns(model, columnSetName);
 
                if (!columnSetColumns) {
 
                               return;
 
                }
 
                var columnSetColumn = columnSetColumns.get(columnName);
 
                var columnOriginalConfig;
 
                if (columnSetColumn) {
 
                               columnOriginalConfig = columnSetColumn.columnOriginalConfig;
 
                } else {
 
                               columnOriginalConfig = {};
 
                               columnConfig.hidden = true;
 
                               var modelInstance = Ext.ClassManager.get(columnSetConfig.modelName || model);
 
                               var realModelColumnConfig = modelInstance.ColumnConfigs.get(columnName);
 
                               columnConfig.columnType = realModelColumnConfig.columnType;
 
                               columnConfig.name = columnName;
 
                }
 
                Ext.merge(columnOriginalConfig, columnConfig);
 
                var contextModel = columnSetConfig.modelName || model;
 
                if (columnConfig.hidden) {
 
                               var columns = this.getColumnSetColumns(model, columnSetName);
 
                               columns.remove(columnName);
 
                } else {
 
                               var resolvedColumnConfig = this.resolveColumnConfig(contextModel, columnOriginalConfig,
 
                                                               !!columnSetConfig.modelName);
 
                               columnSetConfig.columns.configure(columnName, resolvedColumnConfig);
 
                }
 
};
 
 
 
Terrasoft.sdk.RecordPage.addColumn = function(model, columnConfig, columnSetName) {
 
                var modelConfig = Terrasoft.ApplicationConfig.getModelConfig(model);
 
                if (!columnSetName) {
 
                               columnSetName = modelConfig.primaryColumnSetName;
 
                }
 
                var columnSetConfig = modelConfig.columnSets.get(columnSetName);
 
                if (!columnSetConfig) {
 
                               return;
 
                }
 
                var contextModel = columnSetConfig.modelName || model;
 
                var isEmbeddedDetail = !!columnSetConfig.modelName;
 
                if (!columnConfig.hidden) {
 
                               columnSetConfig.columns.add(this.resolveColumnConfig(contextModel, columnConfig, isEmbeddedDetail));
 
                }
 
                this.addColumnToQueryConfig(model, columnConfig.name, columnSetName, isEmbeddedDetail);
 
                if (columnConfig.displayColumn) {
 
                               this.addColumnToQueryConfig(model, columnConfig.displayColumn, columnSetName, isEmbeddedDetail);
 
                }
 
};

- In the mobile application manifest (e.g., "UsrMobileApplicationManifestCustomMobile") specify the custom schema.

Like 0

Like

Share

0 comments
Show all comments

Symptoms

An error occurs while adding the "Feed" section to the new workplace in the mobile application wizard.

Solution

1. Add the following code in the schema settings of the "Feed" section grid (UsrMobileSocialMessageGridPageSettingsSupervisorworkplace):

{
    "operation": "insert",
    "name": "e0de54d7-b417-42b1-8081-36337aa344a1",
    "values": {
        "row": 0,
        "content": "Created by",
        "columnName": "CreatedBy",
        "dataValueType": 1,
        "operation": "insert"
    },
    "parentName": "settings",
    "propertyName": "items",
    "index": 1
}

2. Change the Message column proprety ("row") to "1" in the settings above. 

"row": 1,

 

Like 0

Like

Share

0 comments
Show all comments

Question

How do I configure the frequency of automatic data synchronization in a mobile application?

Answer

The mobile application supports three types of synchronization:



Offline - to perform synchronization, you must click the sync button.

Offline synchronization in the background - starts when the bpm’online mobile application is minimized and only if the “Automatic synchronization” setting corresponds to the current status of the Internet connection.

Online - synchronization occurs during every interaction with a record in the mobile appication.

About filters that apply to displayed activities:

  • Activity must not be closed
  • Non-email activity
  • The user of the mobile application is in the activities.

Also, the filters of the mobile application interface are applied:

Activity date - depending on the filter set by date

"Display in schedule" checkbox

Like 0

Like

Share

0 comments
Show all comments

Question

How to implement a search for multiple columns in a section?

For example, in the Contacts section, search by full name and zip code (the column in the Contact object).

Answer

- Launch the mobile app wizard

- Open default workplace (“Main workplace”)

- Go to section settings

- Click "Save"

- Create ClientUnit schema

- Add the following code to it:

Terrasoft.sdk.GridPage.setSearchColumns("Contact", [“Name”, “Zip”]);

- Open MobileApplicationManifestDefaultWorkplace in the Custom package

- Register your schema for the “Contacts” section:

{
    “Models”: {
        “Contact”: {
            "PagesExtensions": [
                "Name_of_the_schema"
            ]
        }
    }
}

 

Like 0

Like

Share

0 comments
Show all comments

Question

How to add a standard detail to a mobile application and display a specific column in it?

Answer

1. Go to the "Mobile application wizard" (/0/Nui/ViewModule.aspx#SectionModuleV2/SysMobileWorkplaceSection)

2.  Open the required workplace ("DefaultWorkplace" by default) and click the "Set up sections" button.

3. Select the desired section, for example, "Contacts", and press the "Details setup" button

4. Add a detail:

5. Go to the "Configuration" section (/0/WorkspaceExplorerModule.aspx)

6. Add a new "Module" schema type with the name "UsrContactCareerModuleConfig"

7. Write a similar code:

Terrasoft.sdk.GridPage.setPrimaryColumn("ContactCareer", "JobTitle");
Terrasoft.sdk.RecordPage.addColumn("ContactCareer", {
        name: "JobTitle",
        position: 1
    }, "primaryColumnSet");
Terrasoft.sdk.RecordPage.removeColumn("ContactCareer", "Contact", "primaryColumnSet");

Where ContactCareer is the name of the table that corresponds to our detail;

JobTitle - the name of the column you want to display

8. Connect this schema in the "MobileApplicationManifestDefaultWorkplace" mobile application manifest: Find the block of the ContactCareer model and add our UsrContactCareerModuleConfig module to PagesExtensions.

Like that:

 

 

Like 0

Like

Share

0 comments
Show all comments

Symptoms

Bpm'online mobile bug report:

Type: Terrasoft.ServerException

Message: Request for server returned error

Additional info:

{"request":{"id":4,"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie","X-Requested-With":"XMLHttpRequest"},"options":{"url":"http://xxxxx.xxxxxxx.xxxxx/0/Services/ProfileService.asmx/Logout","method":"POST","jsonData":{"customData":"","doLogout":"true"},"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"disableCaching":false,"scope":{"initialConfig":{"url":"http://xxxxx.xxxxxxx.xxxxx/0/Services/ProfileService.asmx/Logout","method":"POST","jsonData":{"customData":"","doLogout":"true"},"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"disableCaching":false},"performanceCounterKey":"86e101ce-533b-4802-941b-56bf73c7b609"}},"async":true},"requestId":4,"status":500,"statusText":"Internal Server Error","responseText":"{\r\n  \"Code\": -1,\r\n  \"Exception\": \"Terrasoft.Core.LicException: The license has expired or inactive\\r\\n  at Terrasoft.Core.UserConnection.CheckLicense()\\r\\n  at Terrasoft.Core.UserConnection.InitializeCurrentUser(String userName, TimeZoneInfo timeZone, String clientIP, String agent, Boolean logSessionStart)\\r\\n  at Terrasoft.Core.UserConnectionFactory.CreateUserConnection(AppConnection appConnection, AuthData authData, String sessionId, String clientIP, String agent, Boolean checkPasswordExpiry)\\r\\n  at Terrasoft.Web.Common.SessionHelper.RecreateUserConnection(AuthData authData)\"\r\n}","responseXML":null,"responseBytes":null}

Cause

The user does not have an active license.

Solution

For correct authorization in the mobile application, it is necessary to distribute the license to the user.

Like 0

Like

Share

0 comments
Show all comments

Question

How do views work in a mobile application? When importing data in offline mode, views are saved to the database as regular tables. It is necessary to filter the field for which the lookup is a view. The view uses records from two sections (Accounts and a custom Construction Objects section). It turns out that when a new account is added in the desktop version, it shows up in the view and can be filtered by it. When creating a new account in the offline mode of the mobile application in the view, it shows up only after synchronization, which complicates the user's experience. As far as I understand, SQL-Lite has the ability to work with views. Is it possible to implement the functionality of views?

Bpm'online application version 7.9.2 2410. Mobile application version 7.11.7.

Answer

SQLite has the ability to create a view. To do this, you need to run the script to create a view in the configuration module. Create the module itself and add it to the manifest in the CustomSchemas block.

Code example:

var sqls = [“CREATE VIEW IF NOT EXISTS AccountView (Id, Name) AS  SELECT Id, Name FROM Account”];
Terrasoft.Sql.DBExecutor.executeSql({
   isCancelable: false,
   sqls: sqls,
   success: function() {},
   failure: function() {}
});

It will be quite difficult to implement filtering by view in the card, so you will still have to write a custom business rule that will make a request for the view.

By default, we do not work with SQLite views. It makes no sense, because the representation in MSSQL or Oracle may not be the same as the SQLite implementation. A view in a mobile application is a regular table, therefore you need to work with it accordingly.

This means that if you want a value to appear there, you should add it. To do this, you can implement business rules for the “Account” and “Construction Objects” objects, so that when adding or updating a record, a copy of this record will be made in the desired view.

Like 0

Like

Share

0 comments
Show all comments

Question

By default, the mobile application wizard allows you to add only two fields to the section list.

Is it possible to increase the number of displayed fields?

Answer

The list can show not only the displayed columns but also display values generated based on the values of several columns. If complex formatting is used, or if it required to display different values depending on certain conditions, column values can be specified as functions (using the Terrasoft.sdk.GridPage.setPrimaryColumn() and Terrasoft.sdk.GridPage.setSecondaryColumn() methods):

Terrasoft.sdk.GridPage.setPrimaryColumn('Account', {
	columns: ['Name', 'PrimaryContact'],
	convertFunction: function(values) {
		if (!Ext.isEmpty(values.PrimaryContact)) {
			return values.Name + ' (' + values.PrimaryContact + ')';
		} else {
			return values.Name;
		}
	}
});

You can also specify additional columns when selecting the value of the lookup field. This is done similarly to a grid, but only the Terrasoft.sdk.LookupGridPage class is used:

Terrasoft.sdk.LookupGridPage.setSecondaryColumn ("Account", "PrimaryContact");

The alternative option for expanding the capabilities of the grid is to change the template of the grid elements:

Terrasoft.util.writeStyles(
	".div-table {",
		"display:table;",
		"width:100%;",
	"}",
	".div-table-row {",
		"display:table-row;",
		"width:100%;",
		"clear:both;",
	"}",
	".div-table-col {",
		"float:left;",
		"display:table-column;",
		"min-width:50%;",
	"}",
	".div-table-col-button {",
		"float:right;",
		"display:table-column;",
	"}"
);
Ext.define("MyCustomList", {
	override: "Ext.Terrasoft.List",
 
	initializeItemTpl: function() {
		this.callParent(arguments);
		var store = this.getStore();
		var model = store.getModel();
		var modelName = model.getName();
		if (modelName === "Account") {
			var tpl = this.getItemTpl();
			tpl.html =
			"<div class=\"x-list-item-tpl div-table\">" +
				"<div class=\"div-table-row\">" +
					"<div class=\"div-table-col\">{[this.applyPrimaryColumn(values)]}</div>" +
					"<div class=\"div-table-col-button\">{Phone}</div>" +
				"</div>" +
				"<div class=\"div-table-row\">" +
					"<div class=\"div-table-col\">{[this.applySecondaryColumn(values)]}</div>" +
					"<div class=\"div-table-col-button\">{Web}</div>" +
				"</div>" +
			"</div>";
		}
	}
 
});

 

Like 0

Like

Share

0 comments
Show all comments

Symptoms

Bpm'online mobile bug report

Type: Terrasoft.SourceCodeException

Message: TypeError: undefined is not an object (evaluating 'columnConfig.columnType')

Cause

The error occurs due to the fact that you have not configured the parameters of the embedded details correctly, e.g., in the "Leads" section.

Solution

You have to correctly configure all the details. For example, to set up the “Files and Attachments” detail in the “Leads” section:

- To display the details in the mobile application, you must select the “Lead attachments” detail

- Select "Lead" in the "Detail column" field

- In the “Object column” field specify “Id”

Like 0

Like

Share

0 comments
Show all comments

Question

I need to place a button under or next to one of the fields on the edit page, clicking on which will display the lookup list.

I need to open a lookup that is not related to the page, and I may need additional operations before that. This cannot be done by just adding a lookup field.

Is it possible to place a button somewhere in the middle of the page? The manual action will be quite inconvenient for the user.

Answer

In the config view, define the required control + a method to display it, and in the controller, assign a handler:

Ext.define("...view...", {
    config: {
       refreshButton: {
            id: 'usr_order_refresh_btn',
            cls: "x-button-primary-blue",
            text: 'Update'
        }
    },
    showRefreshButton: function (isShow) {
        var navigationPanel = this.getNavigationPanel(); /*a component in which the controll will be displayed*/
        var refreshButton = this.getRefreshButton();
        if (isShow) {
            this._refreshButton = navigationPanel.addButton(refreshButton);
        } else {
            navigationPanel.removeButton(refreshButton);
        }
        return this._refreshButton;
    }
});
Ext.define("...controller...", {
    initializeView: function (view) {
        this.callParent(arguments);
        var btn = view.showRefreshButton(true);
        btn.on("tap", this.onRefreshButtonTap, this);
    },
    onRefreshButtonTap: function() {
        /* subject */
    }
});

If you need to open a picker to select a value, then look in the MobileActivityGridPageControllerV2.  For example, there are pickers that enable you to select the "Responsible" employee (the "getEmployeePicker()" method) or select the schedule mode (the "getGridModePicker()" method).

Like 0

Like

Share

5 comments

Hi,

I am given with the requirement to create a button in Account Edit page section in Mobile application. The above code seems difficult to understand. Can you please explain How create/add a button in mobile application.

Please help/guide me to acheive this.

Sriraksha KS,

Hello, to add the button to the edit page you can follow the instructions from the article: 

https://community.bpmonline.com/articles/adding-custom-user-action-mobi…



Best regards,

Alex

Alex_Tim,

The link you gave displays

"You are not authorized to access this page."

 

Please help !!

Sriraksha KS,

It looks fine from my side. I recommend opening this link in another browser or incognito mode.

Seems like when you are logged into community, the link is not working; i was not logged in and it opened for me; but once i logged into my community profile, the link didn't open.

Show all comments