Как сделать сложное, многосоставное свойство

2k
Алексей,
Как сделать сложное, многосоставное свойство
Как сделать сложное, многосоставное свойство

Когда нужно заполнить, например, таблицу и при этом лень делать справочник, то можно сделать суперкостылище) Хранить данные в поле DESCRIPTION.

Когда нужно заполнить, например, таблицу и при этом лень делать справочник, то можно сделать суперкостылище) Хранить данные в поле DESCRIPTION.

Алгоритм такой:

  • С помощью события OnIBlockPropertyBuildList делаем кастомное свойство.
  • В нём делаем необходимые поля. В моём случае это: сортировка, привязка к элементу, файл и описание. Исходным свойством было обычное "Привязка к элементу"
  • Далее привязку сохраняем в VALUE, а все остальные поля сериализуем и сохраняем в DESCRIPTION

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

AddEventHandler('iblock', 'OnIBlockPropertyBuildList', array('CMyEvents', 'GetUserTypeDescription'));
AddEventHandler('iblock', 'OnBeforeIBlockElementUpdate', array('CMyEvents', 'savePicture'));
class CMyEvents
{

	function sortRowTable($a, $b) {
		if ($a['SORT'] == $b['SORT']) {
			return 0;
		}
		return ($a['SORT'] < $b['SORT']) ? -1 : 1;
	}

	function savePicture(&$arParams)
	{
		$arProp = \Bitrix\Iblock\PropertyTable::getList(['filter' => ['CODE' => 'CUSTOM_PROP_CODE'], 'select' => ['ID']])->fetch();
		// сохраним и запишем новые
		if ($_FILES['desc-img']) {
			$p=0;foreach ($arParams["PROPERTY_VALUES"][$arProp['ID']] as $k => $arVal) {

				$arVals = unserialize($arVal['DESCRIPTION']);
				$arVals['DESCRIPTION'] = $_REQUEST['desc'][$p];
				$arVals['SORT'] = $_REQUEST['desc-sort'][$p];
				$arVals['FILE'] = $_REQUEST['desc-img-saved-id'][$p];

				foreach ($_FILES['desc-img']["size"] as $i => $size) {
					if ($size > 0) {
						// Записываем ID файла в описание
						if ($i === $p) {
							$arFile = array(
								'name' => $_FILES['desc-img']["name"][$i],
								'type' => $_FILES['desc-img']["type"][$i],
								'tmp_name' => $_FILES['desc-img']["tmp_name"][$i],
								'size' => $size,
							);
							if ($id = CFile::SaveFile($arFile, 'def-table')) {
								$arVals['FILE'] = $id;
							}
						}
					}
				}
				$arParams["PROPERTY_VALUES"][$arProp['ID']][$k]['DESCRIPTION'] = serialize($arVals);
				$p++;}
		}

		if ($_REQUEST['desc-sort']) { // Отсортируем значения в свойстве
			$arTmp = $arParams["PROPERTY_VALUES"][$arProp['ID']];
			$i = 0;foreach ($arTmp as $n => $v) {
				$arTmp[$n]['SORT'] = $_REQUEST['desc-sort'][$i];
			$i++;}
			usort($arTmp, array("CMyEvents", "sortRowTable"));
			$arParams["PROPERTY_VALUES"][$arProp['ID']] = array_combine(array_keys($arParams["PROPERTY_VALUES"][$arProp['ID']]), $arTmp);
		}
	}

	function GetUserTypeDescription()
	{
		return array(
			"PROPERTY_TYPE" => "E",
			"USER_TYPE" => "ElementListDescriprion",
			"DESCRIPTION" => 'Строка в таблице',
			"GetPropertyFieldHtml" => array("CMyEvents", "GetPropertyFieldHtml"),
		);
	}

	function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName)
	{
		$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"],
			);
			$rsItem = CIBlockElement::GetList(array(), $arFilter, false, false, array("ID", "IBLOCK_ID", "NAME"));
			$arItem = $rsItem->GetNext();
		}
		$arVals = unserialize($value["DESCRIPTION"]);
		if ($fileId = $arVals['FILE']) {
			$arFile = CFile::GetFileArray($fileId);
		}

		$value["DESCRIPTION"] = trim(preg_replace("/\[\d+\]/", "", $value["DESCRIPTION"]));
		$html .= '<table border="1"><tr>'.
			'<td><input type="text" name="desc-sort[]" value="'.($arVals['SORT'] ?: '500').'" style="width: 50px;"/></td>'.
			'<td><span id="sp_' . md5($strHTMLControlName["VALUE"]) . '_' . $key . '" >' . $arItem["NAME"] . '</span>&nbsp;'.
				'<input name="' . $strHTMLControlName["VALUE"] . '" id="' . $strHTMLControlName["VALUE"] . '" value="' . htmlspecialcharsex($value["VALUE"]) . '" size="5" type="text">'.
				'<input type="button" value="..." onClick="jsUtils.OpenWindow(\'/bitrix/admin/iblock_element_search.php?lang=' . LANG . '&IBLOCK_ID=' . $arProperty["LINK_IBLOCK_ID"] . '&n=' . $strHTMLControlName["VALUE"] . '\', 600, 500);">'.
			'</td>' .
			'<td>'.($arFile ? '<input type="hidden" name="desc-img-saved-id[]" value="'.$arFile["ID"].'"><span>'.
				'<a href="'.$arFile["SRC"].'" target="_blank">'.$arFile["ORIGINAL_NAME"].'</a></span>&nbsp;': '').'<input type="file" value="" name="desc-img[]">'.
			'</td>'.
			'<td><input type="hidden" name="' . $strHTMLControlName["DESCRIPTION"] . '" value="'.htmlentities($value["DESCRIPTION"]).'"><input type="text" name="desc[]" value="'.$arVals['DESCRIPTION'].'" /></td>'.
			'</tr></table>';

		return $html;
	}
}

Вот так это выводится, например, в компоненте:

Пример вывода сложного свойства

Есть вопросы или нашли ошибку? Напишите комментарий (можно без регистрации), отвечать стараюсь быстро.

Опубликовано 18 января 2022 | Обновлено 31 мая 2022
костыли, инфоблоки, свойства, примеры кода
Поделиться
Похожие статьи
Сужение вариантов в зависимости от другого свойства
Кастомное свойство привязки c небольшим костылём. Сделано для удобного заполнения свойства в админке...
Читать дальше » 0
Алексей,
Комментарии
❮…❯
Авторизуйтесь чтобы получать уведомления об ответе
Когда нужно заполнить, например, таблицу и при этом лень делать справочник, то можно сделать суперкостылище) Хранить данные в поле DESCRIPTION.