Как сделать сложное, многосоставное свойство
Когда нужно заполнить, например, таблицу и при этом лень делать справочник, то можно сделать суперкостылище) Хранить данные в поле 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> '. '<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> ': '').'<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; } }
Вот так это выводится, например, в компоненте:
Есть вопросы или нашли ошибку? Напишите комментарий (можно без регистрации), отвечать стараюсь быстро.