Иногда бывает нужно воспользоваться не просто свойством "Привязка к элементам", а например еще указать дополнительные параметры к этих элеменатам. Ну допустим не просто товары, а еще и их количество.
Первым в голову приходит решение через несколько инфоблоков или таблиц, но получается это всё очень громоздко и не всякий контент-менеджер согласиться так работать.
Поэтому очень удобным решением будет создать кастомное пользовательское свойство инфоблока, где для всех доп. полей использовать DESCRIPTION и сериализованный в него массив (если значений нужно несколько).
Далее пример простого добавления инпута к множественному свойству "привязка к Элементам" как на картинке к посту.
Создаем класс и размещаем его например в /local/php_interface/classes/listelementwithdescription.php
/*
* Пояснения:
* (*) - Мы принимаем массив array('VALUE' => , 'DESCRIPTION' => ) и должны его же вернуть. Если поле с описанием - оно будет содержаться в соответствующем ключе.
*/
class listElementWithDescription
{
// инициализация пользовательского свойства для инфоблока
function GetIBlockPropertyDescription()
{
return array(
"PROPERTY_TYPE" => "E", // основываемся на привязке к элементам
"USER_TYPE" => "listElementWithDescription",
"DESCRIPTION" => "Привязка к элементам с доп.описанием",
'GetPropertyFieldHtml' => array(__CLASS__, 'GetPropertyFieldHtml'),
"ConvertToDB" => array(__CLASS__,"ConvertToDB"),
"ConvertFromDB" => array(__CLASS__,"ConvertFromDB"),
);
}
function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName)
{
$value["DESCRIPTION"] = unserialize($value["DESCRIPTION"]);
// значения по умолчанию
$arItem = Array(
"ID" => 0,
"IBLOCK_ID" => 0,
"NAME" => ""
);
// получение информации по выбранному элементу
if(intval($value["VALUE"]) > 0)
{
$arFilter = Array(
"ID" => intval($value["VALUE"]),
"IBLOCK_ID" => $arProperty["LINK_IBLOCK_ID"],
);
$arItem = \CIBlockElement::GetList(Array(), $arFilter, false, false, Array("ID", "IBLOCK_ID", "NAME"))->Fetch();
}
// сама строка с товаром и доп.значениями
$html =
'Товар: '.
' '.$arItem["NAME"].' '.
' '.
' Количество:'
;
return $html;
}
function GetAdminListViewHTML($arProperty, $value, $strHTMLControlName)
{
return;
}
function ConvertToDB($arProperty, $value) // сохранение в базу данных
{
$return = false;
if( is_array($value) && array_key_exists("VALUE", $value) )
{
$return = array(
"VALUE" => serialize($value["VALUE"])
);
}
// сериализацию убирать не стал, если понадобится сохранять несколько значений
if( is_array($value) && array_key_exists("DESCRIPTION", $value) )
$return["DESCRIPTION"] = serialize($value["DESCRIPTION"]);
return $return;
}
function ConvertFromDB($arProperty, $value) // извлечение значений из Базы Данных
{
$return = false;
if(!is_array($value["VALUE"]))
{
$return = array(
"VALUE" => unserialize($value["VALUE"])
);
}
return $return;
}
}
И далее нам нужно его подключить и добавить обработчик события. Сделать это можно по разному, у меня всё это сделано через модуль, но можно и просто в init.php
include_once(__DIR__.'/classes/listelementwithdescription.php'); // воспользуемся обработчиком события и добавим наш кастомный тип свойства AddEventHandler('iblock', 'OnIBlockPropertyBuildList', ['listElementWithDescription', 'GetIBlockPropertyDescription']);
Или например если нужно, чтобы вместо текстовых инпутов были чекбоксы, типо этого:
Просто заменяем вывод на:
// сама строка с товаром и доп.значениями
$html =
'Товар: '.
' '.$arItem["NAME"].' '.
' ';
$html .= ' Обязательный: ';
Дальше остается только при получении данных ансериализовать переменную DESCRIPTION этого свойства
Статья основана на топике форума Битрикса и собственном опыте :)