1) Сначала в контрол типа LookUp добавляем кнопку (обычный Button) как дочерний элемент
2) Далее в нужном месте добавляем в её меню элементы (на примере молнии ConfigurationItemToolButton)

var menuItem = CreateMenuItem(configurationItemName, configurationItemId.ToString(), "ItemClick_Yw", Page.ConfigurationItemToolButton.ClientID);
Page.ConfigurationItemToolButton.Menu.AddCaptionItem(menuItem);
Page.AddScript(string.Format("{0}.init_ev()", menuItem.ClientID));

ConfigurationItemToolButton - сама кнопка SmartTag
configurationItemName - будет Caption нашего пункта, например, название элемента
configurationItemId - GUID выбираемого элемета, который присвоим нашему LookUp-полю в случае его выбора, кладём в Tag пункта меню

3) На событии Init создаём подписку по нажатию пункта меню этой кнопки, где сами определяем, какая должна быть логика, логично, что должна быть установка значения в Lookup , но это надо написать самим, так как логика может быть любой:

Page.ConfigurationItemToolButton.AjaxEvents.MenuItemClick.Event += delegate(object sender, Terrasoft.UI.WebControls.Controls.AjaxEventArgs e) {
string ConfigurationItemIdString = e.ExtraParameters[2].Value.ToString();
int LocUnderChar = ConfigurationItemIdString.LastIndexOf("_");
if (LocUnderChar > 0)
ConfigurationItemIdString = ConfigurationItemIdString.Remove(0,LocUnderChar+1);
var clickedMenuItemCode = new Guid(ConfigurationItemIdString);                        
Page.DataSource.ActiveRow.SetColumnValue("ConfigurationItemId", clickedMenuItemCode);
Page.DataSource.ActiveRow.LoadLookupDisplayValues("ConfigurationItem");
};

Тут e.ExtraParameters[2].Value передаётся не совсем GUID, поэтому пришлось немного обрезать.
Ниже код метода CreateMeniItem и CreateSeparatorMenuItem

protected virtual Terrasoft.UI.WebControls.Controls.MenuItem CreateMenuItem(string caption, string tag, string signalName, string targetControlID) {
                        var menuItem = new Terrasoft.UI.WebControls.Controls.MenuItem(caption);
menuItem.Tag = tag;
menuItem.AjaxEvents.Click.SignalName = signalName;
menuItem.Name = "menuItem_" + Guid.NewGuid().ToString("N");
menuItem.CreatedByAjax = true;
menuItem.AjaxEvents.Click.AjaxEventTargetControlID = targetControlID;
return menuItem;
                }

                protected virtual MenuSeparator CreateSeparatorMenuItem(string caption) {
                        return new MenuSeparator {
        Name = "menuItem_" + Guid.NewGuid().ToString("N"),
        Caption = caption,
        CreatedByAjax = true
};
}

Нравится

Поделиться

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

Коллеги, есть важное решение одного вопроса по поводу BPMonline. Как известно, BPMonline – это не десктоп , и один из ярких примеров – это разница между объектом на сервере и его клиентским отображением в браузере. Наши UI-контролы могут быть неотрисованы (неотрендерены) на клиенте, что означает, что к контролу нельзя обращаться со стороны клиента во многих случаях, например, нельзя обращаться к его свойствам, так как они могут быть undefined, а также не все методы можно вызывать, так как тоже может быть работа с undefined логикой. Поэтому правильнее работать с контролом, когда он уже отрисован. Если вы добавляете клиентский скрипт (Page.AddScript) на PageLoadComplete, то на этот момент контрол может уже быть на странице, либо ещё нет, и имеем два кейса. Поэтому для добавления своей логики, её нужно обернуть таким кодом

string script = @" if (Edit.rendered) {{ /*Ваша логика работы с контролом*/ }}
else {{
Edit.on('rendercomplete',function(event) {{ /*Ваша логика работы с контролом*/ }}, Edit);
}}"
;

, где Edit – это Page.Edit.ClientID вашего контрола
Конкретно , такая ситуация обязательна,если ваша логика – функция при событии нажатия на клавишу (но я думаю, что и любое событие), тогда лучше делать это так (на одном примере):
string script = @"var {0}KeyPressFunction = function(event) {{  if(event.getKey() == 45 && event.altKey == true) {{   /*логика работы функции*/     }}
}};
if ({0}.rendered) {{ {0}.el.on(Ext.isIE || Ext.isSafari3 ? 'keydown' : 'keypress', {0}KeyPressFunction  , {0}); }}
else {{
{0}.on('rendercomplete',function(event) {{ {0}.el.on(Ext.isIE || Ext.isSafari3 ? 'keydown' : 'keypress', {0}KeyPressFunction , {0}) }}, {0});
}}"
;
Page.AddScript(string.Format(script,Page.SymptomsMemoEdit.ClientID));

Обращаю внимание, что для keypress нужно подписываться на el, а не на сам элемент
Список возможных ивентов (первый аргумент в методе “on”) доступен по свойству events у контрола (или элемента el)
В Chrome в консоли разработчика или в watch это можно посмотреть.

Нравится

Поделиться

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

Два типа передачи данных между клиентом и сервером:
Первый через ThrowClientEventWithParameters описан ранее, но тут надо использовать своё событие, что не всегда обязательно, хотя может этот ThrowClientEventWithParameters кладёт в контекст страницы, если узнаете – как это сделать, то можно обойтись и без ThrowClientEventWithParameters

Второй способ – использовать customData – поле, которое есть на каждой странице:
Чтение\запись на сервере

var customData = ((Page)Page.AspPage).CustomData;
if (customData.ContainsKey("tempData")) {
var tempData = (JObject)customData["tempData"];
if (tempData != null) {
var data = (JObject)tempData[clientId];
if (data != null) {
var jValue = (JValue)data[parameter];
if (jValue != null) {
 jValue.Value = value; // если хотите прочитать, то достаточно убрать эту строчку и прочитать jValue.Value
}}}}

Для работы скрипта нужно подключить в using неймспейс Terrasoft.Common.Json
Здесь clientId – это идентификатор конкретного контрола Page.Control.ClientID, parameter – имя параметра, который мы читаем\записываем, value – значение. jValue.Value типа Object поэтому при чтении надо преобразовать в нужный тип. Можно ли таким образов передавать ссылочные объекты (классы), не уверен, но обычные можно

Чтение\запись этого параметра на клиенте: В нужном месте добавляем скрипт

string Script = @”var ParamValue = {0}.getCustomData('parameter');
{0}.setCustomData('parameter', value);
Page.AddScript(String.Format(Script, Page.Control.ClientID));

‘parameter’ – имя параметра должно совпадать с серверным.
Остальное по смыслу

Нравится

Поделиться

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

Коллеги,
Хакинг BPMonline продолжается и его невозможно остановить. Кто ещё не знает, вы можете подписаться на клиентское событие, предшествующее аналогичному серверному событию для какого-либо контрола. Достаточно одной строчки. Добавлять нужно на PageLoadComplete. Выглядит это так (обязательно со скобками и т.д.):

string script = @" function(){ //тело функции } ()";
Page.SomeControl.AjaxEvents.SomeEvent.OnClientEvent=script;

Зачем это нужно? Порядок запуска методов будет такой: ClientEventScript ->AJAX-> ServerPageInit -> ServerPageLoad -> ServerEventScript
И вы получаете уникальную возможность сделать что-то со страницей ещё до того, мы зайдем на сервер и его события Init и PageLoad. Например, вам нужно знать, была ли нажат кнопка сразу же на PageLoad после того, как она была нажата. Если вы сделаете флаг нажатия в ServerEventScript, то он будет установлен уже после того, как сработает Init, а если вы такой флаг добавите в клиентскую часть, то его можно вычитать на PageLoad и узнать, что кнопка была нажата(как передавать параметры между клиентом и сервером, расскажу отдельно). Кроме того, некоторая часть логики недоступна на сервере или её выставление на сервере будет ненужным-поздним.

Ниже пример, как это делается, а также кое-какие другие возможности.

string script = @" function(){
var savetofileparam = new Object();
savetofileparam.MenuItem = itemIndex;
var SaveMenuItemParams = Ext.util.JSON.encodeObject(savetofileparam, 3);
Terrasoft.AjaxMethods.ThrowClientEventWithParameters('"
+ InstanceUId + @"', 'SaveToFileCustomEvent',SaveMenuItemParams, {eventMask:{showMask:false}, isUpload: true}  ); } ()";
Page.SaveFileButton.AjaxEvents.MenuItemClick.OnClientEvent=script;

Тут мы добавляем функцию на клик пункта меню у кнопки, а также кидаем другое событие, которому передаём параметры в виде JSON-словаря SaveMenuItemParams (itemIndex-номер пункта, это передаётся в параметрах события, я узнал это опытным путём, у каждого клиентского события свои параметры). Также передаём параметры showMask и isUpload именно на клиенте, так как на сервере их передача не приводит к желаемому эффекту, потому что вычитываются они ранее ещё на клиенте. 'SaveToFileCustomEvent' – это произвольный message-событие. Если событие с таким названием определить на сервере, то можно его перехватить и выполнить свой код, при этом вычитав параметры, которые были упакованы, вот так ():

Dictionarystring, object> SaveMenuItemParams = context.ThrowEventArgs as Dictionarystring, object>;
if (SaveMenuItemParams != null) {
if (SaveMenuItemParams.ContainsKey("MenuItem")) {
  //код работы с  SaveMenuItemParams["MenuItem"]
 }
}

Нравится

Поделиться

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