Здравствуйте,

Всплывает ошибка при загрузке мастера редактирования карточки:

file: undefined
line: undefined
column: undefined
message: Элемент с ключом 33e46153-d870-42af-a250-8d8a9ecae940 Не существует 
 date: Thu Nov 15 2018 16:02:43 GMT+0500 (Екатеринбург, стандартное время)
moduleId: undefined
moduleName: undefined





Пишет что id не найден, смотрел в БД, таблицу SysSchema там реально этого UId нету, но зато есть эта карточка но с другим Id

Почему так могло произойти ? И как это можно исправить ?



Изображение удалено.





Изображение удалено.

Нравится

2 комментария

Уточните, возникают ли какие-то ошибки в консоли просто при открытии этой карточки редактирования?

Возможно, что-то не перенеслось, если эти карточки переносили на основной сайт с базы разработки. 

Попробуйте сравнивать наполнение системных таблиц, связанных с разделами (вроде SysModule, SysModuleEdit и т.д.) для этого и для нормально работающего разделов. Либо произведите автоматический поиск по всем полям всех таблиц базы, чтобы найти, где именно записан этот ID 33e46153-d870-42af-a250-8d8a9ecae940.

Показать все комментарии

Коллеги, всем доброго времени суток, нужна помощь.

Необходимо добавить маску загрузки на страницу редактирования.

Пробовал разными способами.

this.showBodyMask();

также пробовал в зависимости карточки добавлять MaskHelper, и далее в коде вызывать MaskHelper.ShowBodyMask() - не срабатывает

 

так же пробовал следующим образом  - var maskId = this.Terrasoft.controls.Mask.show(this);

 так же не работает.

 страница наследуется от Базовая схема карточки ( NUI ).

Ниже приведен код карточки:

define("AbReportSettingsPageV2", ["AbReportSettingsPageV2Resources", "BaseFiltersGenerateModule", "ServiceHelper"], 
	function(Resources, BaseFiltersGenerateModule, ServiceHelper) {
	return {
		entitySchemaName: "AbCustomReport",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		attributes: {
			"AbDateFrom":{
				"dataValueType": Terrasoft.DataValueType.DATE,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isRequired": true
			},
			"AbDateBy":{
				"dataValueType": Terrasoft.DataValueType.DATE,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isRequired": true
			},
			"AbCustomReport": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isLookup": true,
				"referenceSchemaName":"AbCustomReport",
				"isRequired": true
			},
			"City": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isLookup": true,
				"referenceSchemaName":"City",
			},
			"Country": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isLookup": true,
				"referenceSchemaName":"Country",
			},
			"Service": {
				"dataValueType": Terrasoft.DataValueType.LOOKUP,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"isLookup": true,
				"referenceSchemaName":"Product",
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "merge",
				"name": "SaveButton",
				"values": {
					"caption": "$Resources.Strings.AbLoadReportCaption",
					"visible": true
				}
			},
			{
				"operation": "merge",
				"name": "BackButton",
				"values": {
					"visible": true
				}
			},
			{
				"operation": "remove",
				"name": "actions"
			},
			{
				"operation": "remove",
				"name": "Tabs"
			},
			{
				"operation": "remove",
				"name": "PrintButton"
			},
			{
				"operation": "remove",
				"name": "OptionsButtonButton"
			},
			{
				"operation": "insert",
				"name": "AbReportSettingsContainer",
				"parentName": "CardContentContainer",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"items": [],
					"markerValue": "AbReportSettingsContainer"
				}
			},
			{
				"operation": "insert",
				"name": "AbReportSettingsGridLayoutContainer",
				"parentName": "AbReportSettingsContainer",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
					"items": []
				}
			},
			{
				"operation": "insert",
				"name": "AbDateFrom",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 0,
						"row": 0,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbDateFromCaption",
					"bindTo": "AbDateFrom",
					"enabled": true
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "AbDateBy",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 0,
						"row": 2,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbDateByCaption",
					"bindTo": "AbDateBy",
					"enabled": true
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 1
			},
			{
				"operation": "insert",
				"name": "AbCustomReport",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 0,
						"row": 4,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbReportCaption",
					"bindTo": "AbCustomReport",
					"enabled": true,
					"contentType": 3
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 2
			},
			{
				"operation": "insert",
				"name": "City",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 8,
						"row": 0,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbCityCaption",
					"bindTo": "City",
					"enabled": true,
					"contentType": 5
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 3
			},
			{
				"operation": "insert",
				"name": "Country",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 8,
						"row": 2,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbCountryCaption",
					"bindTo": "Country",
					"enabled": true,
					"contentType": 5
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 4
			},
			{
				"operation": "insert",
				"name": "Service",
				"values": {
					"layout": {
						"colSpan": 8,
						"rowSpan": 1,
						"column": 8,
						"row": 4,
						"layoutName": "AbReportSettingsGridLayoutContainer"
					},
					"caption": "$Resources.Strings.AbServiceCaption",
					"bindTo": "Service",
					"enabled": false,
					"contentType": 5
				},
				"parentName": "AbReportSettingsGridLayoutContainer",
				"propertyName": "items",
				"index": 5
			}
		]/**SCHEMA_DIFF*/,
		methods: {
			onEntityInitialized: function () {
				this.callParent(arguments);
				this.set("Name", this.getHeader());
				this.getCurrentContactCountry();
 
			},
			save: function() {
				this.runReportForming();
			},
			getCurrentContactCountry: function () {
				var currentContactId = Terrasoft.SysValue.CURRENT_USER_CONTACT.value;
				var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
					rootSchemaName: "Contact"
				});
				esq.addColumn("Country", "CountryId");
				esq.getEntity(currentContactId, function(result) {
					if (!result.success) {
						this.showInformationDialog(Resources.localizableStrings.AbCurrentUserCountryError);
						return;
					}
					var country = result.entity.get("CountryId");
					if(country!== null || country!== undefined) {
						this.set("Country", country);
					}
				},this)
			},
			runReportForming: function () {
				var startDate = this.get("AbDateFrom");
				var stopDate = this.get("AbDateBy");
				var report = this.get("AbCustomReport");
				var country = this.get("Country");
				var city = this.get("City");
				var service = this.get("Service");
				if(startDate === null || startDate === undefined) {
					this.showInformationDialog(Resources.localizableStrings.AbFillDateStartCaption);
					return;
				}
				if(stopDate === null || stopDate === undefined) {
					this.showInformationDialog(Resources.localizableStrings.AbFillDateStartCaption);
					return;
				}
				if(startDate > stopDate){
					this.showInformationDialog(Resources.localizableStrings.AbIntervalDateWarningCaption);
					return;
				}
				if(report === null || report === undefined) {
					this.showInformationDialog(Resources.localizableStrings.AbFillReportCaption);
					return;
				}
				if(report.value == "c77af1b5-7118-40c7-8636-870edb85d45f" && (city === null || city === undefined)) {
					this.showInformationDialog(Resources.localizableStrings.AbFiillCityWarningCaption);
					return;
				}
				var reportId = report.value;
				countryId = (country === null || country === undefined) ? null : country.value;
				cityId = (city === null || city === undefined) ? null : city.value;
				serviceId = (service === null || service === undefined) ? null : service.value;
 
				var dateStart = Ext.Date.format(startDate, 'Y-m-d');
				var dateStop = Ext.Date.format(stopDate, 'Y-m-d');
				var dataSend = {
					startDate: dateStart,
					stopDate: dateStop,
					reportId: reportId,
					countryId: countryId,
					cityId: cityId,
					serviceId: serviceId
				};
				this.getReportServices(dataSend);
			},
			getReportServices: function(dataSend) {
				var reportId = dataSend.reportId;
				var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
					rootSchemaName: "AbCustomReport"
				});
				esq.addColumn("Name", "ReportName");
				esq.addColumn("AbSourceCodeServiceName", "SourceCodeServiceName");
				esq.getEntity(reportId, function(result) {
					if (!result.success) {
						this.showInformationDialog("Ошибка запроса данных");
						return;
					}
					var reportName =  result.entity.get("ReportName");
					var sourceCodeName =  result.entity.get("SourceCodeServiceName");
					this.downloadReport(sourceCodeName, reportName, dataSend);
				}, this);
			},
			downloadReport: function(sourceCodeName, reportName, dataSend) {
				debugger;
				this.showBodyMask();
				Terrasoft.AjaxProvider.request({
					url: "../rest/" + sourceCodeName + "/GetReportUrl",
					headers: {
						"Accept": "application/json",
						"Content-Type": "application/json"
					},
					method: "POST",
					jsonData: dataSend,
					callback: function (request, success, response) {
						var responseObject = {};
						if (success) {
							responseObject = Terrasoft.decode(response.responseText);
							var key = "/" + responseObject.GetReportUrlResult;
							var reportCaption = reportName + ".xlsx";
							var report = document.createElement("a");
							report.href = "../rest/" + sourceCodeName + "/GenerateSalaryReport" + key;
							report.download = reportCaption;
							document.body.appendChild(report);
							report.click();
							document.body.removeChild(report);
						}
						this.hideBodyMask();
					}, scope: this
				});
			},
			getHeader: function() {
				return Resources.localizableStrings.AbPageSettingsCaption;
			}
		},
		rules: {},
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/
	};
});

 

Нравится

11 комментариев

Добрый день.

Для вызова маски из this необходимо проверить, не потерялся ли контекст где-то по стэку вызова.  При правильном this метод showBodyMask(); должен работать.

Для вызова из MaskHelper необходимо модуль подключить в define.

define("AbReportSettingsPageV2", ["AbReportSettingsPageV2Resources", "BaseFiltersGenerateModule", "ServiceHelper", "MaskHelper"], 
	function(Resources, BaseFiltersGenerateModule, ServiceHelper, MaskHelper) 

В консоли ошибки есть?

Пащенко Александр Сергеевич,

В зависимости MaskHelper добавлял. Во всех трех случаях которые я описал ошибок в консоли нет.

Нигрескул Алексей,

попробуйте так:

 

var maskId = Terrasoft.MaskHelper.showBodyMask();

Terrasoft.MaskHelper.hideBodyMask(maskId);

 

Нигрескул Алексей,

Страница настроек случайно не в SystemDesigner вставлена?

Варфоломеев Данила,

Да, туда.

Есть какие то особенности в данной реализации?

Нигрескул Алексей,

Ну как сказать. Я уперся в те же самые проблемы, перепробовал все способы, маска так и не заработала. Убил часа 3, потом просто плюнул на это дело. Только в дизайнере такой бред происходит.

Принял, благодарю. А ТП ничего не говорит по данному поводу?

Cм. пример использования showBodyMask и hideBodyMask. 

Зверев Александр,

Все перепробовал - не работает.

Может, на самом деле маска показывается, но сразу скрывается другим процессом.

Показать все комментарии

День добрый всем, может кто либо сталкивался или знает, суть задачи такова:

Нужно отфильтровать стандартный фильтр, а именно оставить лишь пару колонок из множества в section, что бы в глаза не бросались остальные. Ковырялся в сторону QuickFilterModuleV2, но что-то не разобрался с ним.

Изображение удалено.

Нравится

3 комментария

Надо было искать не в QuickFilterModuleV2, а в CustomFilterViewModelV2.

Список колонок получает функция:

function getSimpleFilterColumnList(filters, list) {
	list.clear();
	var columnList = {};
	var columnNames = [];
	var columns = this.entitySchema.columns;
	Terrasoft.each(columns, function(column) {
if (column.dataValueType !== Terrasoft.DataValueType.GUID &&
	column.dataValueType !== Terrasoft.DataValueType.TIME &&
	column.dataValueType !== Terrasoft.DataValueType.BLOB &&
	column.dataValueType !== Terrasoft.DataValueType.IMAGELOOKUP &&
	column.usageType !== ConfigurationEnums.EntitySchemaColumnUsageType.None) {
	if (this.isColumnDeprecated(column)) {
return;
	}
	columnNames.push({
name: column.name,
caption: column.caption
	});
}
	}, this);
	var sortedColumnNames = columnNames.sort(function(a, b) {
if (a.caption === b.caption) {
	return 0;
} else {
	return a.caption > b.caption ? 1 : -1;
}
	});
	Terrasoft.each(sortedColumnNames, function(item) {
var column = columns[item.name];
columnList[column.name] = {
	value: column.name,
	displayValue: column.caption,
	dataValueType: column.dataValueType,
	referenceSchemaName: column.referenceSchemaName
};
	});
	list.loadAll(columnList);
}

 

Я попробовал переопределить этот модуль, просто сделать пустым выпадающий список. Этот модуль в версии 7.13 нельзя заместить обычным способом, я использовал материал . Раскройте пожалуйста подробнее как удалось переопределить эту функцию?

Так это тема 2018 года, тогда в 7.11 ещё было можно.

Показать все комментарии

Как отловить событие выбора справочника ?

т.е пользователь нажимает на лупу из списка выбирает значение которое ему нужно и после этого должно генерироваться событие

Нравится

4 комментария
Лучший ответ

Чем onchange плох?

this.on("change:UsrAuto", function() {
	this.UpdateFinanceTab();
}, this);

 

Чем onchange плох?

this.on("change:UsrAuto", function() {
	this.UpdateFinanceTab();
}, this);

 

Алексей-Карягин,

Да в принципе ни чем, просто я не знал о нём ..

спасибо огромное, это отлично работает

Подскажите, пожалуйста, куда вставить этот код. Если в methods, то как его связать с полем справочника? Если непосредственно в код объявления справочника, то в какое свойство? Спасибо.

Руслан Хасанов, 

этот код нужно вставлять тогда когда нужно прослушивание события, например после загрузки карточки в метод onEntityInitialized

 

methods: {
    onEntityInitialized: function(){
        this.callParent();
        this.on("change:Amount", function(){
            window.alert("lalala");
        }, this);
    }
}

 

Показать все комментарии

Коллеги. всем доброго времени суток! Нужна Ваша помощь.

В преднастроенной странице реализовал метод подсчета вводимых символов - http://prntscr.com/jr6ki0

срабатывает функция - http://prntscr.com/jr6ky6

Результат - http://prntscr.com/jr6lss, http://prntscr.com/jr6m3d

Делаю так же в карточке редактирования раздела SMS:

http://prntscr.com/jr6mwu - не срабатывает

http://prntscr.com/jr6nx7

Подскажите в чем может быть проблема?

Заранее благодарю!

Нравится

1 комментарий

Проверить имена атрибута в методе this.set

Показать все комментарии

Подскажите пожалуйста каким образом можно внедрить сторонние библиотеки JS в мобильную версию bpm online

Нравится

3 комментария

Здравствуйте, Андрей!

Подскажите, какую функциональность Вы хотите добавить сторонними библиотеками?

Pavel Bashtovoy, мне необходимо распрарсить xlsx файл, без отправки на сервер.

Андрей, добрый день!

Как вариант Вы можете создать отделньую схему и полностью скопировать код из этой библиотеки (т.е. метод "copy-paste"). А затем подключить как обычно в манифест CustomSchemas.

Пример подключения таких скриптов:

CustomSchemas: ['MobileActionCheckIn', 'MobileUtilities']

Показать все комментарии

Добрый день, коллеги!

Такая ситуация, есть обычная страница редактирования (PortalKnowledgeBasePage), а на ней обычная деталь (FileDetail), я хочу сделать так что бы при открытии страницы, сразу скачивался первый попавшийся файл на детали. На рендере страницы я вызываю этот метод:

renderDownloadFile: function () {
        var esqKnowledgeBaseFile = Ext.create("Terrasoft.EntitySchemaQuery", {
                "rootSchemaName": "KnowledgeBaseFile"
        });
        esqKnowledgeBaseFile.addColumn("Id");
        esqKnowledgeBaseFile.addColumn("KnowledgeBase");
        esqKnowledgeBaseFile.addColumn("Name");
        esqKnowledgeBaseFile.addColumn("Data");
        esqKnowledgeBaseFile.filters.addItem(Terrasoft.createColumnFilterWithParameter(
                Terrasoft.ComparisonType.EQUAL, "KnowledgeBase", this.get("PrimaryColumnValue")));
        esqKnowledgeBaseFile.getEntityCollection(function(resultKnowledgeBaseFile) {
                if (resultKnowledgeBaseFile.success) {
                        var textFileAsBlob = new Blob([resultKnowledgeBaseFile.collection.getByIndex(0).get("Data")], {type:'application/pdf'});
                        var fileNameToSaveAs = resultKnowledgeBaseFile.collection.getByIndex(0).get("Name");

                        var downloadLink = document.createElement("a");
                        downloadLink.download = fileNameToSaveAs;
                        downloadLink.innerHTML = "Download File";
                        if (window.webkitURL != null) {
                                downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
                        } else {
                                downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
                                downloadLink.onclick = destroyClickedElement;
                                downloadLink.style.display = "none";
                                document.body.appendChild(downloadLink);
                        }
                        downloadLink.click();
                }
        }, this);
},

Запись берет правильно, в общем он все делает правильно, кроме одного, скачивается файл, с правильным названием, с правильным количеством страниц, а вот содержимого нет. Видимо я не правильно передаю бинарные данные в конструтор Blob, но я уже все варианты перепробовал, подскажите пожалуйста!
Спасибо.

Нравится

4 комментария

Роман, проблема заключается в том что вы передаете в Blob стринг, вследствие чего файл получает нужный размер и тип, но абсолютно неправильное содержание. Работать массивами байтов в JavaScript не самая лучшая идея. Рекомендую Вам написать свой WCF сервис, который будет принимать Id записи, обращаться к базе данных и получать byte[]. Данный массив необходимо обвернуть в Stream и вернуть из сервиса добавив необходимый mime type.

Данное решение будет более простым, надежным и применимым не только на одной странице редактирования.

"Мотков Илья" написал:Роман, проблема заключается в том что вы передаете в Blob стринг, вследствие чего файл получает нужный размер и тип, но абсолютно неправильное содержание. Работать массивами байтов в JavaScript не самая лучшая идея. Рекомендую Вам написать свой WCF сервис, который будет принимать Id записи, обращаться к базе данных и получать byte[]. Данный массив необходимо обвернуть в Stream и вернуть из сервиса добавив необходимый mime type.

Данное решение будет более простым, надежным и применимым не только на одной странице редактирования.


Сделал как вы сказали, и все ровно не получается. Теперь клиентская сторона выглядит вот так:

onGetServiceInfoClick: function(idKnowledgeBase) {
				var serviceData = {
					KnowledgeBaseID: this.get("PrimaryColumnValue")
				};
				ServiceHelper.callService("CustomConfigurationService", "GetTransformValue",
				function(response) {
					var result = response.GetTransformValueResult;
					this.renderDownloadFile(result);
				}, serviceData, this);
			},
 
			renderDownloadFile: function (data) {
				var esqKnowledgeBaseFile = Ext.create("Terrasoft.EntitySchemaQuery", {
					"rootSchemaName": "KnowledgeBaseFile"
				});
				esqKnowledgeBaseFile.addColumn("Id");
				esqKnowledgeBaseFile.addColumn("KnowledgeBase");
				esqKnowledgeBaseFile.addColumn("Name");
				esqKnowledgeBaseFile.filters.addItem(Terrasoft.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "KnowledgeBase", this.get("PrimaryColumnValue")));
				esqKnowledgeBaseFile.getEntityCollection(function(resultKnowledgeBaseFile) { 
					if (resultKnowledgeBaseFile.success) {
						var textFileAsBlob = new Blob([data], {type:'application/pdf'});
						var fileNameToSaveAs = resultKnowledgeBaseFile.collection.getByIndex(0).get("Name");
 
						var downloadLink = document.createElement("a");
						downloadLink.download = fileNameToSaveAs;
						downloadLink.innerHTML = "Download File";
						if (window.webkitURL != null) {
							downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
						} else {
							downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
							downloadLink.onclick = destroyClickedElement;
							downloadLink.style.display = "none";
							document.body.appendChild(downloadLink);
						}
						downloadLink.click();
					}
				}, this);
			},

А сам веб сервис вот так:

public class CustomConfigurationService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
        public MemoryStream GetTransformValue(string KnowledgeBaseID)
        {
            var UserConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
            var KnowledgeBaseFileESQ = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "KnowledgeBaseFile");
            KnowledgeBaseFileESQ.AddAllSchemaColumns();
            var KnowledgeBaseIDFilter = KnowledgeBaseFileESQ.CreateFilterWithParameters(FilterComparisonType.Equal, "KnowledgeBase", new Guid(KnowledgeBaseID));
            KnowledgeBaseFileESQ.Filters.Add(KnowledgeBaseIDFilter);
            var KnowledgeBaseFileEnteties = KnowledgeBaseFileESQ.GetEntityCollection(UserConnection);
 
            var data = KnowledgeBaseFileEnteties[0].GetColumnValue("Data") as byte[];
            var result = new MemoryStream(data);
 
            return result;
        }
    }

Ну и в последнем методе "renderDownloadFile", параметр data вот такой

И ещё пробовал с веб сервиса передать массив байтов, и принимать его вот так:

var textFileAsBlob = new Blob(data, {type:'application/pdf'});

Все ровно ничего хорошего не получилось

Роман, данный функционал уже реализован в системе. Посмотрите в сервис FileService. К примеру для файла с страницы редактирования контактов достаточно сформировать тэг

<a target='_self' href='http://localhost:8087/0/rest/FileService/GetFile/e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4/564a97fc-7290-4343-b45e-8f466e5fad5b"'></a>

Где e9eafee9-c4e4-4793-ad0a-003bd2c6a9b4 - UId объекта ContactFile, а 564a97fc-7290-4343-b45e-8f466e5fad5b - Id файла из таблицы ContactFile. UId будет проще всего скопировать напрямую с уже созданных линков на детали "Файлы и ссылки".

Показать все комментарии

На форуме не нашел, решил написать.
Проблема такая:
-В расширенном модуле AccountSectionV2 нужно по нажатию кнопки еще проставлять true на галку.
При создание нового account(а именно на page) все без проблем "завелось", проблема встала именно на section, при редактирование из клиентской части уже имеющегося юр.лица.

Как я понял нужно использовать esq, т.к. this.set("bool",true); не работает, но не нашел как устанавливать значения через esq. Быть может надо по другому. Помогите пожалуйста.

define("AccountSectionV2", [],
        function() {
        return {
                entitySchemaName: "Account",
            // Коллекция методов модели представления страницы редактирования.
            methods: {
                                getChainCardModuleSandboxId: function(typeColumnValue) {
                                        return this.getCardModuleSandboxId() + "_chain" + typeColumnValue;
                                },
                                showExistingRecordSaveButton: function() {
                                        this.set("IsSendToFlextera", true);
                                        return this.get("IsCardInEditMode") && this.get("ShowSaveButton");
                                       
                                },
                                onClickSaveToFlex: function() {
                                   this.set("IsSendToFlextera", true);
                                        var tag = arguments[0] || arguments[3];
                                        this.sandbox.publish("OnCardAction", tag, [this.getCardModuleSandboxId()]);
                                       
                                }
                        },
                               
                        diff: [
                {
                                        "operation": "insert",
                                        "name": "FlexsaveRecordButton",
                                        "parentName": "CombinedModeActionButtonsCardLeftContainer",
                                        "propertyName": "items",
                                        "values": {
                                                "itemType": Terrasoft.ViewItemType.BUTTON,
                                                "caption": {"bindTo": "Resources.Strings.SaveToFlexteraCaption"},
                                                "click": {"bindTo": "IsSendToFlextera"},//"onClickSaveToFlex"},
                                                "visible": {"bindTo": "showExistingRecordSaveButton"},
                                                "classes": {"textClass": ["actions-button-margin-right"]},
                                                "tag": "save"
                                        }
                                }
            ]
                 
         };
        });

Нравится

1 комментарий

Максим, добрый день!

Если колонка, для которой необходимо установить значение, есть среди колонок активной строки, можно попробовать сохранять активную строку:

var activeRow = this.getActiveRow();
activeRow.set("YourColumnName", columnValue);
activeRow.saveEntity();

Для работы этого кода необходимо, чтобы в коллекции activeRow.columns была колонка с названием YourColumnName и типом Terrasoft.ViewModelColumnType.ENTITY_COLUMN (данная константа равняется 0).

Также обновление значения можно выполнить через запрос примерно так:

var updateQuery = this.Ext.create("Terrasoft.UpdateQuery", {
	rootSchemaName: "EntitySchemaName"
});
var filters = updateQuery.filters;
filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
	this.Terrasoft.ComparisonType.EQUAL, "Id", currentRecordId));
updateQuery.setParameterValue("YourColumnName", columnValue);
updateQuery.execute(callbackFunction, this);
Показать все комментарии

Добрый день! Хочу поделиться опытом работы с JS в проектах на bpm’online 5. Статья будет полезна тем, кто не знает с какой стороны подойти к этому вопросу и с чего начать. Умение работать с JS применительно к bpm’online открывает богатые возможности настройки функциональности. В статье будет рассмотрено:

  • как добавлять js-скрипты на страницы bpm’online
  • как подписываться на события "onclick", "onkeydown" и пр.
  • как генерировать сигналы для страницы
  • показан пример использования jQuery
  • использование js-библиотек

Основы

Добавление JS скрипта на страницу выполняется с помощью метода:

Page.AddScript(string script)

Добавим на «страницу карточки задачи» кнопку и напишем код обработки:


Page.AddScript("alert('Hello!')");

В результате нажатия на кнопку произойдёт следующее:

Чтобы упростить себе жизнь и не мучиться с экранированием символов, текст JS-скрипта в исходном виде можно записать в параметр бизнес-процесса.

А затем добавить скрипт, передавая в качестве текста скрипта параметр JS_FirstScript:

Page.AddScript(JS_FirstScript);

Немного модифицируем этот способ: в параметр JS_FirstScript запишем:

alert('%message%');

Добавим в Usings пространство имен System.Text.RegularExpressions
В коде пишем:

string script;

script = Regex.Replace(JS_FirstScript, "%message%", "Привет");
Page.AddScript(script);

script = Regex.Replace(JS_FirstScript, "%message%", "Пока");
Page.AddScript(script);


Подписка на события

Пример №1
Добавим возможность ловить нажатие клавиш и выполнять определённые действия:

string scriptLeft = Regex.Replace(JS_FirstScript, "%message%", "Left");
string scriptRight = Regex.Replace(JS_FirstScript, "%message%", "Right");
string KeyboardScript = "document.onkeydown = function(event) {var key_code = event.keyCode; if(key_code == 37){" + scriptLeft + "}if(key_code == 39){" + scriptRight + "}}";
Page.AddScript(KeyboardScript);

После нажатия на нашу красную кнопку, на страницу добавятся обработчики нажатия кнопок «Стрелка влево» и «Стрелка вправо». Нажимая на стрелки, получаем:

Само собой, если добавить этот скрипт в "Init", то обработчики появятся уже после открытия страницы.

Пример №2
Добавим обработку клика по изображению. Дизайнер bpm'online не позволяет добавить обработчик события «click» на элемент «Область изображения», но мы можем сделать это с помощью JS. Добавим картинку на страницу:


Мы будем искать html-элемент этой картинки по id, поэтому посмотрим на него:

id = PageContainer_MyGreatImageBox

Добавим обработку клика на картинку:

string script = Regex.Replace(JS_FirstScript, "%message%", "Image Click!");
string imageBoxScript = "document.getElementById('PageContainer_MyGreatImageBox').onclick = function() {" + script + "}";
Page.AddScript(imageBoxScript);

Генерирование сигнала

Добавим ещё один событийный подпроцесс:

с сигналом «JSMessage»:

В скрипте «JMessage» напишем:

Page.AddScript("alert('Привет')");

Чтобы сгенерировать сигнал с помощью JS, можно использовать следующую конструкцию:

string message = "JSMessage";
string signalMessage = string.Format("Terrasoft.AjaxMethods.ThrowClientEvent(\'{0}\', '{1}');", InstanceUId, message);
Page.AddScript(signalMessage);

Теперь, по нажатию на нашу красную кнопку:

JQuery

Для того, чтобы не изобретать велосипеды, у нас есть возможность использовать JQuery в своем коде. Причём, JQuery уже добавлен в ресурсы страницы. На момент написания статьи, обычно это jQuery v1.7.1

Приведу пример анимации с помощью jQuery.
Добавим в процесс параметр «scriptAnimation». Пишем его значение:

$("#PageContainer_MyGreatImageBox").animate({
        opacity: 0,
        marginLeft: "-50"
        }, 300 );
$("#PageContainer_MyGreatImageBox").animate({
        opacity: 1,
        marginLeft: "50"
        }, 300 );

Добавим скрипт на страницу:

string imageBoxScript = "document.getElementById('PageContainer_MyGreatImageBox').onclick = function() {" + scriptAnimation + "}";
Page.AddScript(imageBoxScript);

В результате, при нажатии на изображение, оно будет сдвигаться влево на 100 пикселей и постепенно исчезать. После чего начнётся обратная анимация.

Изменив id элемента в параметре «scriptAnimation», можно подвигать, например, поле ввода автора активности:

Добавление библиотек JS на страницу

Что делать, если нам нужно подключить какой-то js-код, который просто неприлично в нормальном обществе засовывать в параметр процесса? Рассмотрим на примере добавления маски ввода к текстовому полю.
Добавим на страницу текстовое поле, назовём его MaskedTextEdit

В \inetpub\wwwroot\sitename\Terrasoft.WebApp\Resources положим файл jquery.maskedinput-1.3.js

в PageLoadComplete (иначе не сработает) пишем:

var appPath = (Page.Request.ApplicationPath == "/") ?
        string.Empty :
        Page.Request.ApplicationPath;
var csnameJQm = "JQMask";
var csurlJQm = "/Resources/jquery.maskedinput-1.3.js";
var scriptManager = ScriptManager.GetCurrent(Page.AspPage);
scriptManager.RegisterClientScriptIncludeInternal(csnameJQm, appPath + csurlJQm);
string CommunicationMask = "+7(999)999-99-99";
Page.AddScript("$('#" + Page.MaskedTextEdit.ClientID + "').mask('" + CommunicationMask + "');");

В результате получим текстовое поле с маской ввода:

Спасибо за внимание! Надеюсь, что эта статья поможет вам в решении ваших задач!

Нравится

Поделиться

6 комментариев

...ушел делать убегающую кнопку для клиента к 1 апреля :smile:

Добро :smile:

Все круто, только не понял, почему для обращения к TextEdit'у с клиента Вы используете свойтсво "ClientID", а для картинки смотрите ее Id в HTML-коде.
Думаю, что оптимальнее везде использовать ClientID.

Добрый день, Андрей!
На то это и примеры, чтобы показать все способы получения идентификатора. Например, понадобилось вдруг нам подвигать какое-нибудь поле, то тут ClientID нам не поможет:

Получив ClientID = PageContainer_HouseCategoryEdit мы будем двигать только текст контрола, в то время как "прямоугольник" контрола будет стоять на месте. Чтобы двигать прямоугольник, нам нужно посмотреть его Id в html:
т.е. нам нужен id div'а, а именно "ext-gen1052", или вообще "ext-gen1070", чтобы подвигать поле вместе с меткой.

Евгений, в таком случае это будет довольно небезопасно, так как после внесения изменений в дизайн страницы автогенерируемый Id уже может быть не тот_) Думаю, если нужно двигать весь контрол, то его можно поместить в контейнер и двигать контейнер. Хотя, я не пробовал, могу ошибаться.

Да, это запросто. Честно говоря, этот момент я не проверял :)

Показать все комментарии