Кастомизация
01
Фев
3

Визуальное преобразование лукапа в пиклист

Видили когда нибудь лукап? Видили!? А пиклист? Тоже!? Хорошо – идем дальше 🙂 С точки зрения безнес-логики у них разное предназначение и отсюда разный способ реализации и как следствие разная «производительность». Да-да Вы не ослышались а – «производительность» – потому как, чтобы задать значение в пиклисте Вам нужно совершить (обычно) куда как меньше щелчков мыши. И в этом неоспоримое преимущество пиклиста. В свою очередь бывают случаи, когда количество записей представленных в лукапе невелико, но из-за необходимости хранить какую-то дополнительную информацию в них, приходится пользоваться именно лукапом. Но есть способ визуально изменить лукап – сделать его в виде пиклиста, при этом пиклист будет динамически менять свои значении при загрузке формы. Так же стоит отметить, что это чисто визуальный эффект и пиклист будет являться всего лишь «посредником» между юзвером и лукапом. Ппоэтому в лукапе, как и обычно, будет проставляться связь, что полностью сохраняет его функциональность и приемы работы с ним, например, при написании отчетов или использовании расширенного поиска.

На форме Бизнес-партнера есть лукап Территория (на вкладке Сведения, в стандартной комплектации). Чтобы выбрать в нем значение пользователь должен сделать минимум три клика мышкой. Сократим это значение до двух 🙂

  • Чтобы использовать нижеследующий код, Вам сначала необходимо подключить CRM Web Service Helper, т.к. в нем использует его функционал;
  • На онлоад повесьте такой код (я включил в листинг и код подключения CRM Web Service Helper, размещенного в папке ISV\CrmServiceToolkit):
    function load_script (url) {
    	var x = new ActiveXObject("Msxml2.XMLHTTP");
    	x.open('GET', url, false);
    	x.send('');
    	eval(x.responseText);
    	var s = x.responseText.split(/\n/);
    	var r = /^(?:function|var)\s*([a-zA-Z_]+)/i;
    	for (var i = 0; i < s.length; i++) {
    		var m = r.exec(s[i]);
    		if (m != null) {
    			window[m[1]] = eval(m[1]);
    		}
    	}
    }
    
    // Подключаем CRM Web Service JavaScript Toolkit
    load_script("/ISV/CrmServiceToolkit/CrmServiceToolkit.js");
    
    ConvertLookupToPicklist = function(lookupControl, lookupEntityName, lookupEntityPrimaryAttribute) {
    	/**
    	* CRM Lookup to Picklist Converter 1.0
    	*
    	* @author Daniel Cai
    	* @website http://danielcai.blogspot.com/
    	* @copyright Daniel Cai
    	* @license Microsoft Public License (Ms-PL), http://www.opensource.org/licenses/ms-pl.html
    	*
    	* This release is provided "AS IS" and contains no warranty or whatsoever.
    	*
    	* Date: Oct 27 2009
    	*/
    
    	var lpconverter = this;
    	var lookupEntityPrimaryKeyField = lookupEntityName + "id";
        
    	lpconverter.RetrieveLookupValues = function() {
    		var fetchXml = 
    			"<fetch mapping='logical'>" + 
    				"<entity name='" + lookupEntityName + "'>" + 
    					"<attribute name='" + lookupEntityPrimaryKeyField + "' />" + 
    					"<attribute name='" + lookupEntityPrimaryAttribute + "' />" + 
    					"<order attribute='" + lookupEntityPrimaryAttribute + "' />" + 
    				"</entity>" + 
    			"</fetch>";
    
    		var lookupValues = [];
                
    		var fetchResult = CrmServiceToolkit.Fetch(fetchXml);
    		if (fetchResult !== null) {
    			for( i = 0; i < fetchResult.length; i++) {
    				var item = new Object();
    				item[lookupEntityPrimaryKeyField] = fetchResult[i].getValue(lookupEntityPrimaryKeyField);
    				item[lookupEntityPrimaryAttribute] = fetchResult[i].getValue(lookupEntityPrimaryAttribute);
                     
    				lookupValues[i] = item;
    			}
    		}
    		return lookupValues;
    	};
        
    	lpconverter.Convert = function() {    
    		var picklistControl = document.createElement("select");
    		picklistControl.id = lookupControl.id;
    		picklistControl.name = lookupControl.name;
    		picklistControl.tabindex = lookupControl.tabindex;
    		picklistControl.req = lookupControl.req;
    		picklistControl.disabled = lookupControl.Disabled;
    		picklistControl.className = "ms-crm-selectBox";
    
    		var lookupValues = lpconverter.RetrieveLookupValues();
    		lpconverter.PopulatePicklist(picklistControl, lookupValues);
    
    		if (lookupControl.DataValue !== null) {
    			picklistControl.DataValue = lookupControl.DataValue[0].id;
            }
            
    		lookupControl.value = lookupControl.DataValue;
    		var lookupControlCell = document.getElementById(lookupControl.id + "_d");
    		lookupControlCell.removeChild(lookupControlCell.childNodes[0]);
    		lookupControlCell.appendChild(picklistControl);
    		return picklistControl;
    	};
    
    	lpconverter.PopulatePicklist = function(picklistControl, lookupValues) {
    		picklistControl.options.length = 0;
            
            // Добавляем пустую опцию в пиклист
    		var option = document.createElement("option");
    		option.value = "";
    		option.innerText = "";        
    		picklistControl.appendChild(option);        
            
    		// Добавляем все опции лукапа в пиклист
    		if (typeof lookupValues !== "undefined") {
    			for (var i = 0 ; i < lookupValues.length ; i++) {
    				option = document.createElement("option");
    				option.value = lookupValues[i][lookupEntityPrimaryKeyField];
    				option.innerText = lookupValues[i][lookupEntityPrimaryAttribute];
                    
    				picklistControl.appendChild(option);
    			}
    		}
    	};
        
        lpconverter.BuildLookupFieldValue = function(id, typename, name) {
    		if (id === null || id === "") {
    			return null;
            }
    
    		var dataValues = [];
    		var dataValue = {};
    		dataValue.id = id;
    		dataValue.typename = typename;
    		dataValue.name = name;
    		dataValues[0] = dataValue;
    
    		return dataValues;
        }
        
    	lpconverter.UpdateLookupWhenPicklistChange = function(picklistControl, lookupControl) {
    		var selectedOption = picklistControl.options[picklistControl.selectedIndex];
    		if (selectedOption.value === "")
    			lookupControl.DataValue = null;
    		else
    			lookupControl.DataValue = lpconverter.BuildLookupFieldValue(selectedOption.value, lookupEntityName, selectedOption.text);
            
    		lookupControl.FireOnChange();
    	};
    
    	lpconverter.Convert();
    };
    
    // Вызываем функцию конвертации лукапа в пиклист и передаем ей три параметра: имя лукапа, имя объекта лукапа и имя основного атрибута объекта лукапа
    new ConvertLookupToPicklist(crmForm.all.territoryid, "territory", "name");
    

    Как Вы можете видеть из комментариев, все, что Вам требуется, для изменения лукапа на писклист – это передать в функцию ConvertLookupToPicklist имя лукапа, имя объекта лукапа и его основной атрибут (по умолчанию обычно name для стандартных объектов и new_name для кастомных). Так что поменяйте это значение в соответствии с Вашими нуждами.



Несколько примечаний:

  • Этот скрипт дает Вам намного больше гибкости, чем использование стандартного лукапа. Т.к. Вы можете использовать свой собственный запрос, чтобы выбрать нужные записи для отображения в picklist’е – т.е. задать фильтр;
  • Данный picklist – динамический, поскольку пользователь может добавить/редактировать/удалить любую запись в объекте лукапа, что, соответственноЮ изменит список, отображаемый в этом picklist’е;
  • Из-за природы picklist’а, у лукапа не должно быть слишком много записей, т.к. в противном случаи в пиклисте будет слишком длинный список.
Комментарии (3)
  • Руслан 01.02.2010

    У меня в DropDownList по умолчанию не проставляется значение, хотя id устанавливается, в чем проблема может быть?

  • Руслан 01.02.2010

    Возникает ошибка после строки

    picklistControl.DataValue = lookupControl.DataValue[0].id

    «Ошибка в изменяемом поле»

    туда подставляется «{GUID}»
    А если я например убираю «{}» то без ошибок, но не устанавливается как надо значение…

    Что это может быть скажите плиз

  • Руслан 01.02.2010

    Проблему решил, вот мой код для MS CRM 2011

    ConvertFieldToPicklist = function (lookupControl, lookupAttribute, lookupEntityName, lookupEntityPrimaryAttribute, fieldToReplace) {

    var lookupEntityPrimaryKeyField = lookupEntityName + «id»;

    var RetrieveLookupValues = function () {
    var fetchXml =
    «» +
    «» +
    «» +
    «» +
    «» +
    «» +
    «»;

    var lookupValues = [];

    var fetchResult = CrmServiceToolkit.Fetch(fetchXml);
    if (fetchResult !== null) {
    for (i = 0; i < fetchResult.length; i++) {
    var item = new Object();
    item[lookupEntityPrimaryKeyField] = fetchResult[i].getValue(lookupEntityPrimaryKeyField);
    item[lookupEntityPrimaryAttribute] = fetchResult[i].getValue(lookupEntityPrimaryAttribute);

    lookupValues[i] = item;
    }
    }
    return lookupValues;
    };

    var PopulatePicklist = function (picklistControl, lookupValues) {
    picklistControl.options.length = 0;

    // Add blank option item
    var option = document.createElement("option");
    option.value = "";
    option.innerText = "";
    picklistControl.appendChild(option);

    // Add all options from code table (lookup entity)
    if (typeof lookupValues !== "undefined") {
    for (var i = 0; i < lookupValues.length; i++) {
    option = document.createElement("option");
    option.value = lookupValues[i][lookupEntityPrimaryKeyField];
    option.innerText = lookupValues[i][lookupEntityPrimaryAttribute];

    picklistControl.appendChild(option);
    }
    }
    };

    BuildLookupFieldValue = function(id, typename, name) {
    if (id === null || id === "") {
    return null;
    }

    var dataValues = [];
    var dataValue = {};
    dataValue.id = id;
    dataValue.typename = typename;
    dataValue.name = name;
    dataValues[0] = dataValue;

    return dataValues;
    }

    UpdateLookupWhenPicklistChange = function(picklistControl, lookupControl) {
    var selectedOption = picklistControl.options[picklistControl.selectedIndex];
    if (selectedOption.value === "")
    lookupControl.DataValue = null;
    else
    lookupControl.DataValue = BuildLookupFieldValue(selectedOption.value, lookupEntityName, selectedOption.text);

    Xrm.Page.getAttribute(fieldToReplace).fireOnChange();
    //lookupControl.FireOnChange();
    };

    (function Convert() {
    var picklistControl = document.createElement("select");
    var replaceFieldControl = document.getElementById(fieldToReplace);
    picklistControl.id = replaceFieldControl.id;
    picklistControl.name = replaceFieldControl.name;
    picklistControl.tabIndex = replaceFieldControl.tabIndex;
    picklistControl.req = replaceFieldControl.req;
    picklistControl.Disabled = replaceFieldControl.Disabled;
    picklistControl.className = "ms-crm-selectBox";
    picklistControl.onchange = function () { UpdateLookupWhenPicklistChange(picklistControl, lookupControl); };

    var lookupValues = RetrieveLookupValues();
    PopulatePicklist(picklistControl, lookupValues);

    if (lookupAttribute.getValue() !== null) {
    picklistControl.DataValue = lookupAttribute.getValue()[0].id;
    }

    var lookupControlCell = document.getElementById(fieldToReplace + "_d");
    lookupControlCell.childNodes[0].style.display = 'none';
    //lookupControlCell.removeChild(lookupControlCell.childNodes[0]);
    lookupControlCell.appendChild(picklistControl);
    return picklistControl;
    })();
    }

*

code