Подскажите как динамически делать пункт меню в "Действие" карточки в совмещенном режиме.

В обычном режиме все работает нормально.

attributes: {
	"IsCanVisaStatus": {
		dataValueType: Terrasoft.DataValueType.BOOLEAN,
		value: true,  // Значение по умолчанию которое передаеться при загрузке страницы на нашу кнопку
		dependencies: [{
			columns: ["KtState"], // Отслеживаем изменение поля состояния 
			methodName: "setCanVisaStatusContract" // и запускаем нашу функция если состояние изменчется
		}]
	}
},
methods: {
	onEntityInitialized: function() {
		this.callParent(arguments);
		this.setCanVisaStatusContract(); // Запускаем функцию при входе на страницу когда поля уже заполненны
	},
	getActions: function() {
		var actionMenuItems = this.callParent(arguments);
		actionMenuItems.addItem(this.getButtonMenuItem({
			Type: "Terrasoft.MenuSeparator",
			Caption: ""
		}));
		actionMenuItems.addItem(this.getButtonMenuItem({
			"Caption": VisaHelper.resources.localizableStrings.SendToVisaCaption,
			"Tag": VisaHelper.SendToVisaMenuItem.methodName,
			"Enabled": {"bindTo": "IsCanVisaStatus"} // мониторим через привязку состояние значения атрибута
		}));
		return actionMenuItems;
	},
	setCanVisaStatusContract: function(){
		var stateId = this.get("KtState").value; // Текущая стадия
		var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {  // Запрос к базе данных о том нужна ли кнопка отправки на визирования
			rootSchemaName: "KtContractKarTelState"
		});
		esq.addColumn("KtCanVisa", "KtCanVisa"); // Сама колонка указывающая что нужна кнопка
		esq.getEntity(stateId, function(result) {
			if (result.success) {
				if (result.entity.get("KtCanVisa") && this.canEntityBeOperated()) {   // this.canEntityBeOperated() - стандартный класс отвечает за то что если карточка на в режиме редактирования то false.
					this.set("IsCanVisaStatus", true);
				} else {									// Присваивает атрибуту значение true или false в зависимости от результата запроса
					this.set("IsCanVisaStatus", false);
				}
				
			}
		}, this);
	}
}

В отоге весь код работает хорошо но только в обычном режиме карточки, а совмещенном кнопка не видет атрибут хоть по девагу все запускается так же и значения поля в атрибуте меняется по кнопка просто его не видит. Пробовал атрибут вписать в Section - не помогло, атрибут видит кнопка но изменить его не получается.

Нравится

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

Нужно использовать механизм сообщений. Вот пример. Моем случае бинд был на аттрибут (в странице редакирования) "Enabled": {"bindTo": "enabledPlanPaymentDate"}

В секции пишем

		messages: {
			"GetEnabledPlanPaymentDate": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		attributes: {
			"enabledPlanPaymentDate": {
				"type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"dataValueType": this.Terrasoft.DataValueType.BOOLEAN,
				"value": false
			}
		},
		methods: {
			init:function() {
				this.callParent(arguments);
				this.sandbox.subscribe("GetEnabledPlanPaymentDate",  function(args){this.$enabledPlanPaymentDate = args}, this, ["SectionModuleV2_InvoiceSectionV2"]);
			},
		}

В странице реадактирования:

		messages: {
			"GetEnabledPlanPaymentDate": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			}
		},
 
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.sandbox.publish("GetEnabledPlanPaymentDate", this.checkEnabledChangePlanPaymentDate(), ["SectionModuleV2_InvoiceSectionV2"]);
			},
			checkEnabledChangePlanPaymentDate: function() {
				return this.$enabledPlanPaymentDate;
			}
}

 

Нужно использовать механизм сообщений. Вот пример. Моем случае бинд был на аттрибут (в странице редакирования) "Enabled": {"bindTo": "enabledPlanPaymentDate"}

В секции пишем

		messages: {
			"GetEnabledPlanPaymentDate": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		attributes: {
			"enabledPlanPaymentDate": {
				"type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"dataValueType": this.Terrasoft.DataValueType.BOOLEAN,
				"value": false
			}
		},
		methods: {
			init:function() {
				this.callParent(arguments);
				this.sandbox.subscribe("GetEnabledPlanPaymentDate",  function(args){this.$enabledPlanPaymentDate = args}, this, ["SectionModuleV2_InvoiceSectionV2"]);
			},
		}

В странице реадактирования:

		messages: {
			"GetEnabledPlanPaymentDate": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			}
		},
 
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.sandbox.publish("GetEnabledPlanPaymentDate", this.checkEnabledChangePlanPaymentDate(), ["SectionModuleV2_InvoiceSectionV2"]);
			},
			checkEnabledChangePlanPaymentDate: function() {
				return this.$enabledPlanPaymentDate;
			}
}

 

Трефилов Павел Сергеевич,

Спасибо, отлично работает. Не много изменил на двустороннюю подписку что бы атрибут менять через сообщение и тот что в секции и тот что на странице

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

Добрый день. Есть такая задача:  в совмещённом режиме продублировать кнопку, которая будет устанавливать дату в поле в карточке. Кнопку я добавил, но не могу установить значение в поле карточки. Пытался сделать через sandbox следующим образом:

В Section:

 messages: {
            "MessagePublish": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        },

............

        methods: {

            //обработчик кнопки
            onSetDateTimeForPageClick: function () {
                this.sandbox.publish("MessagePublish");
            }

         }

В Page:

 messages: {
            "MessagePublish": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            },
        },
        init: function () {
            this.callParent(arguments);
            this.sandbox.subscribe("MessagePublish", this.methods.onSetDateTimeClick, this);
        },

Что я упустил или неправильно делаю?

Заранее спасибо)

 

Нравится

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

Добрый день.

Если дату вы передаете, то в publish нужно указать передаваемый аргумент. В subscribe callback-метод нужно записывать без «methods» (this.onSetDateTimeClick) – и соответственно он должен быть задан в methods страницы, и принимать параметр(в который придёт передаваемый аргумент). Больше примеров на академии https://academy.terrasoft.ru/documents/technic-sdk/7-11/sandbox-obmen-s…

VladKapitanchyk,

Добрый день, метод onSetDateTimeClick имеет следующее определение 

        onSetDateTimeClick:function(){
                this.set("UsrDateTime",(new Date).toString());
            }

Где UsrDateTime текстовое поле карточки. То есть, вызов происходит без аргументов, из Section я всего лишь хочу дать сигнал, чтобы на Page вызвался метод. Исправил в subscribe callback-метод на (this.onSetDateTimeClick), но это не помогло. Также попробовал переделать на способ с передачей аргументов, и тоже не помогло(

Полный листинг способа без передачи аргумента:

В Section:

define("UsrClientModule21Section", [], function () {
    return {
        entitySchemaName: "UsrClientModule2",
        details: /**SCHEMA_DETAILS*/ {} /**SCHEMA_DETAILS*/ ,
        messages: {
            "MessagePublish": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        diff: /**SCHEMA_DIFF*/ [{
            "operation": "insert",
            "parentName": "CombinedModeActionButtonsCardLeftContainer",
            "propertyName": "items",
            "name": "SetDateTimeButton",
            "values": {
                "itemType": Terrasoft.ViewItemType.BUTTON,
                "caption": {
                    bindTo: "Resources.Strings.SetDateTime"
                },
                "click": {
                    bindTo: "onSetDateTimeClick"
                },
                "style": Terrasoft.controls.ButtonEnums.style.GREEN,
            }
        }] /**SCHEMA_DIFF*/ ,
        methods: {
            onSetDateTimeClick: function () {

this.sandbox.publish("MessagePublish");

//Способ с передачей аргумента.

//this.sandbox.publish("MessagePublish",(new Date).toString());
            }
        }
    };
});

В Page:

define("UsrClientModule21Page", [], function() {
    return {
        entitySchemaName: "UsrClientModule2",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
        messages: {
            "MessagePublish": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            },
        },
        init: function () {
            this.callParent(arguments);

            this.sandbox.subscribe("MessagePublish", this.onSetDateTimeClick, this);

//При передаче аргумента

// this.sandbox.subscribe("MessagePublish", function(arg)..{this.set("UsrDateTime",arg)}, this);
        },
        diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
        methods: {
            onSetDateTimeClick:function(){
                this.set("UsrDateTime",(new Date).toString());
            }
        },
        rules: {},
        businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/
    };
});

Добрый день.

Метод "init" должен быть в блоке "methods".

Так же рекомендую открывать консоль (F12) и читать ошибку, если будет что то наподобе "Cannot read property 'entitySchemaName'" значит проблема с неправильной структурой схемы.

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

Добрый день.

Посчитали "совмещенный" режим не самым полезным для пользователя. Да и повторять логику отображения и доступности кнопок из Page в Section с помощью месседжей - не самый удобный вариант. В связи с этим решили открывать карточку объекта только в Page режиме, минуя совмещенный с реестром. Т.е. чтобы при нажатии на кнопку открыть в реестре, объект открывался только в режиме редактирования. Каким образом это реализовать? Может кто-то уже сталкивался с подобным кейсом?

Нравится

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

самый простой вариант (как мне кажется) переопределить метод

editRecord: function(primaryColumnValue) {
	var activeRow = this.getActiveRow();
	var typeColumnValue = this.getTypeColumnValue(activeRow);
	var schemaName = this.getEditPageSchemaName(typeColumnValue);
	this.set("ShowCloseButton", true);
	this.openCard(schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue);
},

в BaseSectionV2 и открывать карточку через window.open()

А можете привести пример синтаксиса использования windows.open()?

editRecord: function(primaryColumnValue) {
	var activeRow = this.getActiveRow();
	var typeColumnValue = this.getTypeColumnValue(activeRow);
	var schemaName = this.getEditPageSchemaName(typeColumnValue);
	this.set("ShowCloseButton", true);
	window.open(Terrasoft.combinePath(Terrasoft.workspaceBaseUrl,"Nui/ViewModule.aspx#CardModuleV2",schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue));
	//this.openCard(schemaName, ConfigurationEnums.CardStateV2.EDIT, primaryColumnValue);
}

 

вот еще пример метода как Из карточки детали выполняется открытие счета сразу на редактирование:
 

openInvoicePage: function(invoiceId) {
   var config = {
         schemaName: "InvoicePageV2",
         operation: enums.CardStateV2.EDIT,
         id: invoiceId,
         moduleId: this.getInviocePageSandboxId()
   };
   this.sandbox.publish("OpenCard", config, [this.sandbox.id]);
},

 

Это же можно повторить и для Схем Реестров, Вызов Метода осуществляете предварительно получив Id сущности, что хотите открыть на редактирование из реестра.

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

Добрый день!

Подскажите, пожалуйста, можно ли открывать карточку не совмещенном режиме,а сразу в обычном при открытии из раздела. Просто немного надоело делать кнопочки на двух страницах, и в page и section.

Насколько  я помню, это можно решить какой-то настройкой, но я к сожалению не помню какой.

Так же интересно, чем я жертвую, отключая данную опцию)

 

Нравится

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

Я так думаю ничем, кроме "удобства" для пользователя, хотя я ни разу не видел как кто-то пользовался по итогу этой узенькой полоской. Легче вернуться в секцию и найти нужную запись.

По теме: я просто сделал windows.open, когда пользователь нажимает на кнопку открыть в гриде (onActiveRowAction вроде функция называется. Там ещё case обработчик тэгов кнопок должен быть). Возможно не самый изящный способ, можно было бы и через pushHistoryState, но срабатывает

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

если делать через window.open кнопка "Закрыть" не срабатывает, можно ли как то сделать чтобы она работала? 

window.close ?

Если открывали в _self, тоесть в том же окне, то:
window.history.back();

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

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

var recId = this.get("Id");
var requestUrl = " CardModuleV2/LeadPageV2/edit/" + recId;
this.sandbox.publish("PushHistoryState", {
    hash: requestUrl
});

Нравится

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

Могу предположить что нужно посмотреть в исходных кодах базовой карточки или раздела, и искать в направлении historyStateInfo.workAreaMode === 2 (так выполняется проверка на совмещенный режим).

спасиб, а реально как-то вызвать функцию в схеме карточки из схемы раздела, необходимо запускать функцию кнопки, которая нормально работает в Combined режиме, а в Separated не срабатывает?

Не совсем понятно, что нужно конкретно.
Вы можете объявить в diff раздела и карточке, а сами функции, например, прописать в миксине, который подключите к разделу и карточке.
В этом миксине можете так же написать функцию, на проверку того в каком режиме открыта карточка, а в самой карточке вызывать эти функции.

Спасибо за помощь :smile:
Суть в том, что есть кнопка удаления в разделе карточки, которая прописана в LeadSectionV2, использующая стандартную функцию deleteRecords из GridUtilitiesV2 и работает в совмещенном режим, но если перейти из контакта в лид или просто перезагрузить страницу, то карточка открывается в раздельном режиме и уже кнопка берется из LeadPageV2, и deleteRecords не срабатывает корректно. В соседней теме советовали использовать deleteQuery, но она не отображает связанные записи и не выполняет каскадное удаление. Поэтому хотели попробовать сделать, чтобы по нажатию кнопки из раздельного режима выполнялся переход в совмещенный и сразу запускалась необходимая функция из LeadSectionV2.

Сам лично не сталкивался с подобным кейсом.
Значит всё же вам по исходным кода javascript надо искать логику открытия страницы в совмещенном режиме и копировать её в LeadPageV2.
Моё мнение.
Либо нужно сделать миксин и логику кнопки из LeadSection копировать в миксин, заранее немного пересмотрев логику удаления связей.

Так же, можете переходить в секцию публикуя сообщение PushHistoryState передавая в него Id текущей записи. В секции проверять наличие атрибута с Id записи (в onEntityInialized). Если атрибут есть - выполнять удаление.

Спасибо, попробовали с помощью PushHistoryState передавать Id.
В LeadPageV2 прописали :

		methods: {
		        delete: function() {
		            var recId = this.get("Id");
 
		            this.sandbox.publish("GetRecordId", this.get("Id"), [this.sandbox.id]);
		            console.log(this.sandbox.id);
 
		            var requestUrl = "SectionModuleV2/LeadSectionV2/";
		            this.sandbox.publish("PushHistoryState", {
		                hash: requestUrl
		            });
 
		        }
 
		    },
		    messages: {
		        "GetRecordId": {
		            mode: Terrasoft.MessageMode.PTP,
		            direction: Terrasoft.MessageDirectionType.PUBLISH
		        }
 
		    }

,а в LeadSectionV2 :

            onEntityInialized: function() {
                this.callParent(arguments);
 
                var recId2 = this.sandbox.id;
                this.sandbox.subscribe("GetRecordId", function() {
                    alert("check")
                }, [this.sandbox.id]);
 
                if (recId2) {
 
                    var activeRow = this.getActiveRow();
                    if (activeRow && activeRow.isNew) {
                        this.removeGridRecords([activeRow.recId2]);
                    } else {
                        var items = this.getSelectedItems();
                        if (!items || !items.length) {
                            return;
                        }
                        this.checkCanDelete(items, this.checkCanDeleteCallback, this);
                    }
                }
            }
 
 
            },
 
            messages: {
                "GetRecordId": {
                    mode: Terrasoft.MessageMode.PTP,
                    direction: Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            }

Но в консоли пишет ошибку:  message direction set as publish
И не передается Id, подскажите, пожалуйста в чем может быть ошибка?

Хм, а вы точно уверены что в месте подписки [this.sanbox.id] идентичный с [this.sanbox.id] в месте отправки?
Добавлю работающий пример передачи значений c детали в карточку через песочницу.
Так же могу предположить, что массив messages нужно было объявить до methods, но скорее всего это не имеет значения.

За это отвечает свойство конфигурационного объекта workAreaMode и соответствующее значение ConfigurationEnums.WorkAreaMode.COMBINED
пример для PushHistoryState

this.sandbox.publish("PushHistoryState", {
	hash: this.Terrasoft.combinePath("SectionModuleV2", "SysAdminUnitSectionV2",
		pageName, "edit", primaryColumnValue),
	stateObj: {
		module: "SectionModuleV2",
		operation: "edit",
		primaryColumnValue: primaryColumnValue,
		schemas: [
			"SysAdminUnitSectionV2",
			pageName
		],
		workAreaMode: ConfigurationEnums.WorkAreaMode.COMBINED,
		moduleId: this.sandbox.id,
		UsersActiveRow: this.get("ActiveRow"),
		FuncRolesActiveRow: this.get("FuncRolesActiveRow"),
		OrgRolesActiveRow: this.get("OrganizationalRolesActiveRow")
	}
});

пример для OpenCardInChain (В сути оберткой над PushHistoryState)

this.openCardInChain({
	"schemaName": "ServiceModelPage",
	"moduleId": this.sandbox.id + "_ServiceModelPage",
	"isSeparateMode": false,
	"defaultValues": defaultValues,
	"workAreaMode": ConfigurationEnums.WorkAreaMode.COMBINED
});

Огромное спасибо, получилось переключать режим по нажатию кнопки. :smile:
Не подскажите, пожалуйста, в чем может быть причина, что при переходе напрямую из раздела в карточку кастомная кнопка работает, а если перейти в совмещенный режим используя код выше, то кнопка не откликается на нажатие, и ошибки в консоли отсутствуют.

"Maria H" написал:ошибки в консоли отсутствуют.

А что за кнопка? Вероятно кнопка ищет реализацию метода в карточке секции, т.к. совмещенный режим обрабатывается секцией.

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