Свойство "Привязка к элементам" с описанием или дополнительными input-ами 1С-Битрикс

Свойство "Привязка к элементам" с описанием или дополнительными input-ами 1С-Битрикс

Иногда бывает нужно воспользоваться не просто свойством "Привязка к элементам", а например еще указать дополнительные параметры к этих элеменатам. Ну допустим не просто товары, а еще и их количество.

Первым в голову приходит решение через несколько инфоблоков или таблиц, но получается это всё очень громоздко и не всякий контент-менеджер согласиться так работать.

Поэтому очень удобным решением будет создать кастомное пользовательское свойство инфоблока, где для всех доп. полей использовать 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 этого свойства

Статья основана на топике форума Битрикса и собственном опыте :)


Возврат к списку