UPD 12.10.2015
Сделал модуль свойства инфоблоков - привязка к сущностям CRM.
Скачать можно
Была поставлена задача: в пользовательских списках сделать возможность выбирать компанию и товар из модуля CRM.
Игорь Карпович писал про это , но такое решение не устраивало: на портале более 20000 товаров и более 20000 контрагентов (компаний).
Для удобного поиска и выбора товара/компании необходимо использовать стандартный компонент (crm.entity.selector), который используется в модуле CRM.

Создаем пользовательские свойства для привязки к компании и товару. Создаем файлы usertype_company_crm.php и usertype_product_crm.php, инклудим их в init.php . Ознакомиться с кодом можно скачав файлы, я лишь остановлюсь на некоторых моментах.
Мое пользовательское свойство условно делится на 3 составляющих: отображение в карточке элемента, отображение в списке элементов и отображение в фильтре.
Итак по порядку
1. GetEditForm - функция, которая подключает всплывающее окошко на страницу редактирования (карточки) элемента в админке и в публичной части. Для записи и отправки свойства сделан скрытый инпут
<input type="hidden" id='<?=$fieldIdentifier?>' name="<?=$strHTMLControlName["VALUE"]?>" value="<?=$value['VALUE']?>" |
<sc ript>
$(window).load(function() {
...
$('#crm-<?=$userIdentifier?>-box').live('DOMSubtreeModified', function() {
try{ var product=$('#crm-<?=$userIdentifier?>-box').find('a').attr('href');
$('#<?=$userIdentifier?>').val(product.replace(/[^\d]/gi, ''));
}
catch(e){
$('#<?=$userIdentifier?>').val('');
}
...
});
});
</sc ript>
|
Следующий фрагмент кода решает задачу сильного подтормаживания при поиске товаров. (именно товаров, т.к. с компаниями такого не наблюдалось).
На ввод символов стоит обработчик события "keyup", что означает, что после каждого введенного символа происходит post запрос к компоненту crm.product.list, а именно к файлу list.ajax.php, который и осуществляет поиск по товарам. И если пользователь вводит слово "мотопомпа", то происходит 9 обращений (!) к этому фалу, что при количестве товаров более 20к выдает сильные тормоза (на скрине apache не загружен, в рабочие часы запросы могут исполнятся по 2-3 минуты!)

Для решения этой проблемы написал небольшую функцию, которая ставит таймер и выполняет отложенный поиск, что позволяет выполнять всего 1 запрос вместо нескольких и в разы сэкономить время. Поясню "тонкое место" при загрузке скрипта на страницу происходит отложенная смена обработчика события для поля ввода (у меня она установлена в 1500 миллисекунд). Сделано это потому, что форма выбора товара подгружается отложено и не сразу присутствует на странице.
<sc ript>
$(window).load(function() {
...
setTimeout(function(){
BX.unbindAll(BX('crm-crm-form-<?=str_replace('_','-',$strHTMLControlName['FORM_NAME'])?>-product-id-open_<?=$fieldIdentifier?>-search-input'));
BX.bind(BX('crm-crm-form-<?=str_replace('_','-',$strHTMLControlName['FORM_NAME'])?>-product-id-open_<?=$fieldIdentifier?>-search-input'), "keyup", function(event){ switchTimer();});
},1500);
function switchTimer() {
timeHandlerId=getCookie('timeHandlerId');
if(timeHandlerId!=0)
clearTimeout(timeHandlerId);
var crmID="crm-form-<?=str_replace('_','-',$strHTMLControlName['FORM_NAME'])?>-product-id-open";
timeHandlerId=setTimeout(function(){
CRM.SearchChange(crmID)
},2000);
document.cookie='timeHandlerId='+timeHandlerId;
}
// возвращает cookie с именем name, если есть, если нет, то undefined
function getCookie(name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
...
});
</sc ript> |
И последнее, что было необходимо - отображение списка товаров списком, а не таблицей. За это отвечает код
<st yle type="text/css">
#crm-crm-form-<?=str_replace('_','-',$strHTMLControlName['FORM_NAME'])?>-product-id-open_<?=$fieldIdentifier?>-block-product .crm-block-cont-contact-info {
width: 330px!important;
}
#crm-crm-form-<?=str_replace('_','-',$strHTMLControlName['FORM_NAME'])?>-product-id-open_<?=$fieldIdentifier?>-block-search .crm-block-cont-contact-info {
width: 330px!important;
}
</style>
|

2. Функция, отвечающая за отображение в списке элементов - выводит название товара с ссылкой на карточку товара в crm
function GetPublicViewHTML($arProperty, $value, $strHTMLControlName)
{
if($value['VALUE']!=''){
$rsGroup=CCrmProduct::GetList(array(), array("ID"=>$value['VALUE']));
$arGroup=$rsGroup->Fetch();
if($arGroup)
return '<a target="blank" href="/crm/product/show/'.$arGroup["ID"].'/">'.$arGroup["NAME"].'</a>';
else
return "";
}
else return "";
}
|
При отображении в фильтре используется crm.field.filter , тогда как не в фильтре подключается system.field.edit. За это отвечает флаг 'FILTER'=>'Y', компонента crm.entity.selector. Плюс при показе в фильтре изменяются некоторые стили.
Приведенный мною пример кода создает свойство для привязке к товару.
Для того, чтобы создать привязку к компании необходимо в параметрах компонента crm.entity.selector указать
'ENTITY_TYPE' => 'COMPANY' |
Порядок действий для подключения свойства привязка к товару в ваш проект (аналогично для свойства привязка к компании):
- Скачиваем файл usertype_product_crm.php
- Если не подключен JQuery - добавляем в файл строчку CJSCore::Init(‘jquery’); (спасибо Денис Диденко )
- Кладем его в /bitrix/php_interface/include/
- В /bitrix/php_interface/init.php пишем
include($_SERVER["DOCUMENT_ROOT"]."/bitrix/php_interface/include/usertype_product_crm.php");
- Заходим в свойства инфоблока, выбираем тип свойства "Привязка к товару CRM"