AXForum  
Вернуться   AXForum > Блоги > CRM, SharePoint и Черная Магия
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
  • Консалтинг
  • Проектирование
  • Разработка
  • Обучение


MVP 2010, 2011
Оценить эту запись

Полезный Popup. Часть 3. Lookup Actions

Запись от Артем Enot Грунин размещена 31.03.2010 в 18:24
Обновил(-а) Артем Enot Грунин 01.04.2010 в 08:04

В своих прошлых статьях данной серии я рассказал о способах и целях создания всплывающих подсказкок в MS CRM. В последней из них я пришел к понимаю необходимости создания универсального решения: кода, который можно натравить на любой лукап, который бы мог, исходя из заданных разработчиком настроек, вывести для пользователя некие полезные данные, которые можно было бы использовать на этой форме. Представляю вашему вниманию очередное промежуточное решение: Lookup Actions. Данное решение основано на системной библиотеке popupmenu.js. В этой реализации всплывающее меню не отражает данные лукапа, но передает нужное значение в обработчик.
Код:
var ERR_NO_ITEMS = "Варианты не найдены ";
var ERR_NO_DATA  = "Выберете значение ";

_useTel = function(oArg)
{
    crmForm.all.phonenumber.DataValue = oArg.Value;
    // defalut
}

_useTel2 = function(oArg)
{
    crmForm.all.phonenumber.DataValue = oArg.Value;

    // скрыть попап (по умолчанию)
    return false;
}

_useTel3 = function(oArg)
{
    crmForm.all.phonenumber.DataValue = oArg.Value;
    // не скрывать попап
    return true;
}

var oToHelper = new LookupActions(crmForm.all.to);

var oAccountType = oToHelper.addType("account", "/_imgs/ico_16_1.gif");
oAccountType.addField("Исп. основной тел.", "telephone1", "/_imgs/ico_16_4210.gif", _useTel);
oAccountType.addField("Исп. дополнителельный тел.", "telephone2", "/_imgs/ico_16_4210.gif", _useTel2);
oAccountType.addField("Исп. факс", "fax", "/_imgs/ico_18_4204.gif", _useTel3);

var oContactType = oToHelper.addType("contact", "/_imgs/ico_16_2.gif");
oContactType.addField("Исп. основной тел.", "telephone1", "/_imgs/ico_16_4210.gif", _useTel);
oContactType.addField("Исп. дополнителельный тел.", "telephone2", "/_imgs/ico_16_4210.gif", _useTel);
oContactType.addField("Исп. мобильный телефон", "mobilephone", "/_imgs/ico_16_4210.gif", _useTel);
oContactType.addField("Исп. факс", "fax", "/_imgs/ico_18_4204.gif", _useTel);


var FromHelper = new LookupActions(crmForm.all.from);
var UserType = FromHelper.addType("systemuser", "");
UserType.addField("Исп. основной тел.", "address1_telephone1", "/_imgs/ico_16_4210.gif", _useTel);
UserType.addField("Исп. дополнителельный тел.", "address1_telephone2", "/_imgs/ico_16_4210.gif", _useTel);
UserType.addField("Исп. Мобильный тел.", "mobilephone", "/_imgs/ico_16_4210.gif", _useTel);
UserType.addField("Исп. факс", "address1_fax", "/_imgs/ico_18_4204.gif", _useTel);

function LookupActions(oLField)
{
    var Field = oLField;
    var Types = [];

    var Items = [];
    var ItemCount = 0;

    var PopUp = null;

    // Вспомогательный класс - добавленные элементы меню
    function LItem(oTypeName, oGUID, oField)
    {
        this.TypeName = oTypeName;
        this.GUID = oGUID;
        this.Field = oField;
    }

    // Вспомогательный класс - тип
    function LType(oTypeName, oIcon)
    {
        this.TypeName = oTypeName;
        this.Icon = oIcon;

        this.Fields = [];
        // Регистрация нового поля внутри типа
        this.addField = function(oLabel, oSchema, oIcon, ofnCallBack)
        {
            var oField = new LField(oLabel, oSchema, oIcon, ofnCallBack);
            this.Fields.push(oField);
        }
    }

    // Вспомогательный класс - поле
    function LField(oLabel, oSchema, oIcon, ofnCallBack)
    {
        this.Label = oLabel;
        this.Schema = oSchema;
        this.Icon = oIcon;
        this.fnCallBack = ofnCallBack;
    }

    // Ф-ция инициализатор
    function reRenderControl()
    {
        var oLabel = crmForm.all[Field.id + "_c"];
        oLabel.style.textDecoration = "underline";
        oLabel.style.color = "blue";
        oLabel.attachEvent("onclick", showPopUP);
        Field.attachEvent("onchange", clearOnChange);
    }

    // Регистрация нового типа
    this.addType = function(oTypeName, oIcon)
    {
        var oType = new LType(oTypeName, oIcon);
        Types[oTypeName] = oType;
        return Types[oTypeName];
    }

    // Принудительная чистка
    this.crear = clearOnChange;

    function clearOnChange()
    {
        ItemCount = 0;        
        Items = [];
        
        PopUp = null;
    }

    function fnNoDataClick()
    {
        // Открывает окно лукапа
        Field.click();
    }

    function fnNoItemsClick()
    {
        // вызывается если для данного типа не заданы настройки
        PopUp.Hide();
    }


    function populatePopUp()
    {
        PopUp = new PopupMenu(); 

        if (Field.DataValue == null)
        {
            PopUp.AddMoreLink(ERR_NO_DATA, fnNoDataClick, 0, "/_imgs/ico/16_info.gif");
             return;
        }

        var oLookups = Field.DataValue;

        for (var i=0; i < oLookups.length; i++)
        {
            var oLookup = oLookups[i];
            var oType = Types[oLookup.typename];
            
            if (oType == null) break;

            // Если значение одно, то не нужно уточнять к чему относится подсказка
            if (oLookups.length != 1)
            {
                PopUp.AddNotification(oLookup.name, oType.Icon);
                ItemCount++;
            }

            var oFields = oType.Fields;
            for (var j=0; j < oFields.length; j++)
            {
                var oField = oFields[j];
                PopUp.AddMenuItem(oField.Label, masterOnClick, 0, oField.Icon);

                oMenuItem = new LItem(oLookup.typename, oLookup.id, oField);
                Items[ItemCount] = oMenuItem;
                ItemCount++;
            }

            PopUp.AddSeperator();
            ItemCount++;
        }
        
        if (ItemCount == 0)
        {    
            PopUp.AddMoreLink(ERR_NO_ITEMS, fnNoItemsClick, 0, "/_imgs/ico/16_info.gif");
        }

    }

    // Обработка клика по ссылке
    showPopUP = function()
    {
        if (PopUp == null) populatePopUp();

        var oLookField = crmForm.all[Field.id + "_d"];
        var oPos = getControlPostion(oLookField);

        PopUp.Show(oPos.X , oPos.Y, null, null);
    }

    // Получаем данные по выбранному атрибуту
    function retriveAttribData(oTypeName, oGUID, oSchema)
    {
        var oSOAP = "<?xml version='1.0' encoding='utf-8'?>"+ 
                "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
                            " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
                            " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ 
                    GenerateAuthenticationHeader() + 
                "<soap:Body>"+ 
                    "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+ 
                        "<entityName>" + oTypeName + "</entityName>"+ 
                            "<id>"+ oGUID + "</id>"+ 
                        "<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:ColumnSet'>"+ 
                        "<q1:Attributes>"+ 
                            "<q1:Attribute>" + oSchema + "</q1:Attribute>"+ 
                        "</q1:Attributes>"+ 
                        "</columnSet>"+ 
                    "</Retrieve>"+ 
                "</soap:Body>"+ 
                "</soap:Envelope>";

        var xmlHTTP = new ActiveXObject("Msxml2.XMLHTTP");
        xmlHTTP.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
        xmlHTTP.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
        xmlHTTP.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xmlHTTP.setRequestHeader("Content-Length", oSOAP.length);

        xmlHTTP.send(oSOAP);

        var oResponseXML = xmlHTTP.responseXML;

        var errorCount = oResponseXML.selectNodes('//error').length;
        if (errorCount != 0)
        {
            var msg = oResponseXML.selectSingleNode('//description').nodeTypedValue;
            alert(msg);
            return null;
        }
        else
        {
            var oSchemaNode = oResponseXML.selectSingleNode("//q1:" + oSchema);
            return oSchemaNode != null ? oSchemaNode.nodeTypedValue : null;
        }
    }

    function masterOnClick(oEvent)
    {
        var oMItem = oEvent.srcElement;

        while (oMItem.name != "menuItem")
        {
            oMItem = oMItem.parentElement;
        }
        var oMenuID = oMItem.menuID;
        var oMenuItem = Items[oMenuID];

        var oTypeName = oMenuItem.TypeName;
        var oGUID = oMenuItem.GUID;
        var oSchema = oMenuItem.Field.Schema;

        var Args = new Object();
        Args.TypeName = oTypeName;
        Args.GUID = oGUID;

        if (oSchema != null)
        {
            var oValue = retriveAttribData(oTypeName, oGUID, oSchema);

            Args.Schema = oSchema;
            Args.Value = oValue;
        }

        var dontHidePopUp = oMenuItem.Field.fnCallBack(Args);

        if (!dontHidePopUp)
        {
            if (PopUp.IsOpen()) PopUp.Hide();
        }
    }

    function getControlPostion(oControl)  
    {       
        var Position = new Object();       
        var controlHeight = oControl.offsetHeight;       
        var iY = 0, iX = 0;       
        while( oControl != null )       
        {             
            iY += oControl.offsetTop;  
            iX += oControl.offsetLeft;  
            oControl = oControl.offsetParent;
        }       
        Position.X = iX + screenLeft;       
        Position.Y = iY + screenTop + controlHeight;       
        return Position;  
    }

    // Перерабатываем контрол
    reRenderControl();
}
Результат выглядит так:

Нажмите на изображение для увеличения
Название: lookupActions.jpg
Просмотров: 747
Размер:	136.0 Кб
ID:	50

+ Поддерживает как одиночные лукапы, так и множественные
+ При отстутствии значения в лукапе предлогает открыть диалог поиска
+ Если для типа лукапа не настроены подсказки выводит уведомление
+ Если в лукапе выбрано только одно значение, то заголовок типа не выводится
+ В обработчик передается тип записи, гуид, имя схемы атрибута и его значение
+ Меню может оставаться на экране, или автоматически скрываться
+ Можно добавлять произвольные элементы меню (без запроса значения атрибута)

- Не показывет значения атрибутов лукапа
- Иконка типа не подтягивается из поля лукапа (было лень)
Размещено в CRM
Просмотров 22404 Комментарии 0
Всего комментариев 0

Комментарии

 


Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 20:55.