Кастомизация
23
Мар
4

CRM Lookup Preview

CRM Lookup Preview (Предварительный просмотр лукапа) представляет собой «всплывающую подсказку», которая появляется при наведение на какую-либо запись выбранной в лукапе. В этой подсказке в отформатированном (HTML) виде содержится информация о записи, на которую наведена мышка. Компонент работает как с одиночными лукапами так и partylist’ам (т.е. лукапами в которых можно выбрать сразу несколько записей различных объектов). Причем если какой-либо тип объекта не перечислен в коде, то для него предварительный просмотр не работает.

Следующий пример демонстрирует работу CRM Lookup Preview для лукапа «Кому» на форме объекта E-mail…

  • Повесьте на onLoad формы Электронная почта такой код:
    // Задаем имя схемы лукапа 
    var PrvToLui = new LookupPreview("to");
    
    // Задаем имя объекта и поля, которые необходимо вернуть объекту (на который наведена мышка)
    var accountEntity = PrvToLui.AddEntity("account");
    
    accountEntity.AddAttribute("Street", "address1_line1");
    accountEntity.AddAttribute("City", "address1_city");
    accountEntity.AddAttribute("State", "address1_stateorprovince");
    accountEntity.AddAttribute("Zip", "address1_postalcode");
    
    /*
    Добавляем связанный объект (для объекта на который наведена мышка в лукапе) поля которого мы также хотим вернуть.
    В AddLinked передается имя связанного объекта и имя лукапа (через который этот связанный объект открывается) на форме объекта на который наведена мышка в лукапе. А в AddAttribute передаются названия полей связанного объекта, которые необходимо вернуть.
    */
    var contactEntity = accountEntity.AddLinked("contact", "primarycontactid");
    contactEntity.AddAttribute("Primary Contact", "fullname");
    contactEntity.AddAttribute("Contact Phone", "telephone1");
    
    // Настраиваем предпросмотр для Контактов выбранных в лукапе
    var contactEntity = PrvToLui.AddEntity("contact");
    contactEntity.AddAttribute("Street", "address1_line1");
    contactEntity.AddAttribute("City", "address1_city");
    contactEntity.AddAttribute("State", "address1_stateorprovince");
    contactEntity.AddAttribute("Zip", "address1_postalcode");
    
    // Настраиваем предпросмотр для Интересов выбранных в лукапе
    var leadEntity = PrvToLui.AddEntity("lead");
    leadEntity.AddAttribute("Full Name", "fullname");
    
    // Настраиваем предпросмотр для Пользователей выбранных в лукапе
    var userEntity = PrvToLui.AddEntity("systemuser");
    userEntity.AddAttribute("Preferred Phone", "preferredphonecode");
    userEntity.AddAttribute("Main Phone", "address1_telephone1");
    
    var buEntity = userEntity.AddLinked("businessunit", "businessunitid");
    buEntity.AddAttribute("Business Unit", "name");
    
    function LookupPreview(lookupId) {
        var Instance = this;
        Instance.Lookup = document.getElementById(lookupId);
    
        if (isNullOrEmpty(Instance.Lookup))
            return;
    
        //Public 
        Instance.Entities = [];
    
        Instance.AddEntity = function(entityName) {
            var Entity = new Object();
            Entity.Name = entityName;
            Entity.AddAttribute = function(labelName, attrName) {
                var Attributes = Instance.Entities[entityName].Attributes;
                var attribute = new Attribute(entityName, attrName, labelName, attrName);
                Attributes[Attributes.length] = attribute;
                DisplayAttributes[DisplayAttributes.length] = attribute;
            }
            Entity.Attributes = [];
            Entity.LinkedByName = [];
            Entity.LinkedByIndex = [];
            Entity.AddLinked = function(lnkEntityName, referencingAttribute) {
                var LinkEntity = new Object();
                LinkEntity.Name = lnkEntityName;
                LinkEntity.Attributes = [];
                LinkEntity.RefAttribute = referencingAttribute;
                LinkEntity.AddAttribute = function(labelName, attrName) {
                    var attribute = new Attribute(entityName, attrName, labelName, LinkEntity.RefAttribute + "." + attrName);
                    LinkEntity.Attributes[LinkEntity.Attributes.length] = attribute;
                    DisplayAttributes[DisplayAttributes.length] = attribute;
                }
                Entity.LinkedByIndex[Entity.LinkedByIndex.length] = Entity.LinkedByName[name] = LinkEntity;
                return LinkEntity;
            }
            Instance.Entities[entityName] = Entity;
            return Entity;
        }
    
        Instance.Show = function(dataElement) {
            var control = Instance.Lookup;
            var DataValue = control.DataValue;
    
            if (isNullOrEmpty(DataValue))
                return;
            if (isNullOrEmpty(Instance.Entities[DataValue[dataElement.Index].typename]))
                return;
    
            TooltipPopup = window.createPopup();
    
            if (!dataElement.PreviewHTML) {
                var ToolTipHTML = "<fieldset style='width:100%;height:100%;border:1px solid gray;background-color: #d8e8ff;filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#eff3ff,EndColorStr=#c6dfff);padding-left:2px;'><legend style='background-color:#eff3ff;width:100;padding-left:13px;border:1px solid gray;font-size:12px;font-family:tahoma'><b>Preview</b></legend>";
                var xmlHttp = CreateXmlHttp();
                var xml = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"";
                xml += " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
                xml += " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
                xml += GenerateAuthenticationHeader();
                xml += "<soap:Body>";
                xml += "<Fetch xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">";
                xml += "<fetchXml>";
    
                var fetchxml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>";
                var DataVal = control.DataValue[dataElement.Index];
                var entity = DataVal.typename;
                fetchxml += "<entity name='" + entity + "'>";
                var attributes = Instance.Entities[entity].Attributes;
                for (var i = 0; i < attributes.length; i++)
                    fetchxml += "<attribute name='" + attributes[i].Name + "'/>";
                fetchxml += "<filter type='and'>";
                fetchxml += "<condition attribute='" + entity + "id' operator='eq' value='" + DataVal.id + "'/>";
                fetchxml += "</filter>";
    
                for (var i = 0; i < Instance.Entities[entity].LinkedByIndex.length; i++) {
                    var linked = Instance.Entities[entity].LinkedByIndex[i];
                    fetchxml += "<link-entity name='" + linked.Name + "' from='" + linked.Name + "id' to='" + linked.RefAttribute + "' visible='false' link-type='outer'>";
                    for (var j = 0; j < linked.Attributes.length; j++)
                        fetchxml += "<attribute name='" + linked.Attributes[j].Name + "'/>";
                    fetchxml += "</link-entity>";
                }
                fetchxml += "</entity>";
                fetchxml += "</fetch>";
    
                xml += _HtmlEncode(fetchxml);
                xml += "</fetchXml>";
                xml += "</Fetch>";
                xml += "</soap:Body>";
                xml += "</soap:Envelope>";
    
                xmlHttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false);
                xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
                xmlHttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
                xmlHttp.send(xml);
    
                var resultDoc = loadXmlDocument(xmlHttp.responseXML.text);
                var previewHtml = "<br style='line-height:2px'/><table width='100%' style='font:12 px tahoma'>";
                dataElement.Width = 0;
                //debugger
                for (var i = 0, j = 1; i < DisplayAttributes.length; i++) {
                    var attribute = DisplayAttributes[i];
                    if (attribute.Entity != entity) continue;
    
                    var attrNode = resultDoc.selectSingleNode("//" + attribute.XPathName);
                    var attrValue = (attrNode) ? attrNode.text : "";
    
                    dataElement.Height = (j++) * 20;
                    var maxLength = (attrValue.length + attribute.Label.length) * 11
                    if (dataElement.Width < maxLength)
                        dataElement.Width = maxLength;
                    previewHtml += "<tr><td style='padding:3px 0px 0px 0px;color:brown'><nobr>" + attribute.Label + "</nobr></td><td><nobr>" + attrValue + "</nobr></td></tr>";
    
                }
    
                dataElement.Height += 20;
    
                ToolTipHTML += previewHtml;
                ToolTipHTML += "</table></fieldset>";
                dataElement.PreviewHTML = ToolTipHTML;
            }
    
            TooltipPopup.document.body.innerHTML = dataElement.PreviewHTML;
    
            var Position = getControlPostion();
            var Left = Position.X + 1;
            var Top = Position.Y + 5;
    
            TooltipPopup.show(Left, Top - dataElement.parentElement.scrollTop, dataElement.Width, dataElement.Height, null);
        }
    
        Instance.Hide = function() {
            if (TooltipPopup)
                TooltipPopup.hide();
        }
    
        Instance.OnLookupChange = function() {
            var jump = 0;
            if (Instance.Lookup.DataValue != null) {
                var DataElementsLen = Instance.Lookup.parentElement.previousSibling.childNodes[0].childNodes.length;
                var DataValuesLen = Instance.Lookup.DataValue.length;
                jump = (DataElementsLen == DataValuesLen) ? 1 : 2;
    
                for (var i = 0; i < DataValuesLen * jump; i += jump) {
                    var DataValueElemet = Instance.Lookup.parentElement.previousSibling.childNodes[0].childNodes[i];
                    if (!isNullOrEmpty(DataValueElemet.onmouseover)) continue;
    
                    DataValueElemet.Preview = Instance;
                    DataValueElemet.Index = i / jump;
                    DataValueElemet.onmouseover = function() {
                        this.Preview.Show(this);
                    }
                    DataValueElemet.onmouseout = function() {
                        this.Preview.Hide();
                    }
                }
            }
        }
    
        //Private 
        var TooltipPopup;
        var DisplayAttributes;
    
        function Init() {
            DisplayAttributes = [];
            Instance.Lookup.attachEvent("onchange", Instance.OnLookupChange);
            Instance.OnLookupChange();  //First Time
        }
    
        function Attribute(entityName, attrName, attrLabel, attrXpathName) {
            this.Name = attrName;
            this.Entity = entityName;
            this.Label = attrLabel;
            this.XPathName = attrXpathName;
        }
    
        function getControlPostion() {
            control = event.srcElement;
            var Position = new Object();
            var controlHeight = control.offsetHeight;
            var iY = 0, iX = 0;
            while (control != null) {
                iY += control.offsetTop;
                iX += control.offsetLeft;
                control = control.offsetParent;
            }
            Position.X = iX + screenLeft;
            Position.Y = iY + screenTop + controlHeight;
            return Position;
        }
    
        function isNullOrEmpty(obj) {
            return obj == null || typeof (obj) == "undefined" || obj == "";
        }
    
        Init();
    }
    

    В этом коде Вам необходимо настрить (в самом начале) для каких объектов (из возможных оттобразить в лукапе) необходимо показывать превью. Также необходимо задать поля которые необходимо показать. Заметьте, что компонент может отображать не только поля с целевого объекта, но и связанных с ним!

  • Смотрим 🙂


Комментарии (4)
  • Николай 23.03.2010

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

  • slivka_83 23.03.2010

    хм… интересная задумка 🙂

    Теоретически можно 🙂 Если совместить эту статью с http://mmcrm.ru/?p=1198 🙂

    Добрый день 🙂

  • Елена 23.03.2010

    ДОбрый день.
    Повесила этот код на онлод фомы инцидента (Case).
    Выдает ошибку:
    There was an error with thisfield’s customized event.
    Field:window
    Event:onload
    Error:Object doesn’t support property or method ‘AddEntity’

  • slivka_83 23.03.2010

    Здрасьте. Ну, код довольно сложный тут дебажить нада. Возможно после какого то ролапе перестал работать.

*

code