Компонент iblock.element.add.form написан таким образом, что вы не сможете (не попотев изрядно и не используя js) как угодно переставлять поля ввода. Например сделать заполненеие текста анонса до ввода разделов. Или переставить чекбоксы свойств до ввода названия (хотя это глупо, но вы не сможжете сделать такую глупость даже если захотите)
При разработке информационных порталов, или просто сложных сайтов, на которых пользователям доступно самостоятельное добавление элементов инфоблока, часто возникает потребность в создании достаточно сложных форм добавления элементов
В большинстве случаев, достаточно воcпользоваться стандартным компонентом iblock.element.add.form. Однако, данный компонент очень давно не обновляется. Назвать его гибким и тонко настраеваемым ни как нельзя. Достаточно часто, для создания формы приходиться писать свои костыли. Например: форму добавления элемента инфоблока через API Битрикс
Компонент iblock.element.add.form написан таким образом, что вы не сможете (не попотев изрядно и не используя js) как угодно переставлять поля ввода. Например сделать заполненеие текста анонса до ввода разделов. Или переставить чекбоксы свойств до ввода названия (хотя это глупо, но вы не сможете сделать такую глупость даже если захотите)
Расскажу как сделать форму через API. Абсолютным костылем данный способ не назвать, в любом случае задача будет решена. И у вас будет возможность оформлять форму как угодно.
Работать будем с методом CIBlockElement::Add - добавляет новый элемент информационного блока. Перед добавлением элемента вызываются обработчики события OnBeforeIBlockElementAdd, из которых можно изменить значения полей или отменить добавление элемента вернув сообщение об ошибке.
Создаем форму на произвольной странице сайта или в основном шаблоне
Для начала: имеем инфоблок "Тест", у которого созданы свойства "Строка", "Список", "Чекбокс", "Файл", "Привязка к разделам". ID этого инфоблока 12
Кстати: в стандартном компоненте не хватает некоторых свойств, например он не умеет выводить свойство привязка к раздел. Как это реализовать можете подсмотреть тут
Далее: Создаем в корне сайта страницу add_form_page.php с таким содержимым
<?
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
//Подключаем модуль инфоблоков
CModule::IncludeModule('iblock');
$IBLOCK_ID = 12; //ИД инфоблока с которым работаем
?>
<form name="add_my_ankete" action="/add_form_result.php" method="POST" enctype="multipart/form-data">
Название
<input type="text" name="name" maxlength="255" value="">
Картинка анонса
<input type="file" size="30" name="image" value="">
Свойство Строка
<input type="text" name="line" maxlength="255" value="">
Выпадающий список не множественный
<select name='selector'>
<option value='#'>Выберите из списка</option>
<option value="60">1</option>
<option value="61">2</option>
</select>
Текст анонса
<textarea name="description" placeholder="Заполните поле"></textarea>
Выбор раздела- множественный
<select name='section_id[]' multiple>
<option value='#'>Выберите из списка или начните вводить название</option>
<?
$arFilter = array('IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y', "DEPTH_LEVEL" => "2");
$arSelect = array('ID', 'NAME');
$rsSection = CIBlockSection::GetTreeList($arFilter, $arSelect);
while ($arSection = $rsSection->Fetch()) {
?>
<option value="<?= $arSection['ID']; ?>"><?= $arSection['NAME']; ?></option>
<?}?>
</select>
Чекбокс
<label><input type="checkbox" name="chek_box" value="47"> Рассрочка </label>
Произвольный файл
<input type="file" size="30" name="file_pol" value="">
Привязка к подразделам конкретного раздела другого мнфоблока чекбоксы
<?
$rsParentSection = CIBlockSection::GetByID(5741);
if ($arParentSection = $rsParentSection->GetNext()) {
$arFilter = array('IBLOCK_ID' => $arParentSection['IBLOCK_ID'], '>LEFT_MARGIN' => $arParentSection['LEFT_MARGIN'], '<RIGHT_MARGIN' => $arParentSection['RIGHT_MARGIN'], '>DEPTH_LEVEL' => $arParentSection['DEPTH_LEVEL']);
$rsSect = CIBlockSection::GetList(array('left_margin' => 'asc'), $arFilter);
while ($arSect = $rsSect->GetNext()) {
?>
<label><input name='service_dop[]' type="checkbox" value="<?= $arSect['ID']; ?>"> <?= $arSect['NAME']; ?></label>
<?}}?>
<input type="submit" value="Отправить">
</form>
<?require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>
Это наша форма, которую заполняет пользователь
Рядом создаем файл add_form_result.php, которому будет передаваться POST запрос и пользователю будет выдаваться сообщение о результате добавления. Содержимое файла:
<?
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
?>
<?
if (!empty($_REQUEST['name']) and !empty($_REQUEST['description'])) {
CModule::IncludeModule('iblock');
echo 'Вот такие данные мы передали';
echo '<pre>';
print_r($_POST);
echo '<pre>';
//Погнали
$el = new CIBlockElement;
$iblock_id = 24;
$section_id = false;
$section_id[$i] = $_POST['section_id']; //Разделы для добавления
//Свойства
$PROP = array();
$PROP['LINE'] = $_POST['line']; //Свойство Строка
$PROP['SELECTOR'] = $_POST['selector']; //Свойство список
$PROP['CHEK_BOX'] = $_POST['chek_box']; //Свойство чекбокс
$PROP['FILE_POL'] = $_FILES['file_pol']; //Свойство файл
$PROP['SECTIONS_SV'][$c] = $_POST['sections_sv']; //Чекбоксы привязка к разделам
//Основные поля элемента
$fields = array(
"DATE_CREATE" =& gt;
date("d.m.Y H:i:s"), //Передаем дата создания
"CREATED_BY" =& gt; $GLOBALS['USER'] ->GetID(), //Передаем ID пользователя кто добавляет
"IBLOCK_SECTION" =& gt; $section_id[$i], //ID разделов
"IBLOCK_ID" =& gt; $iblock_id, //ID информационного блока он 24-ый
"PROPERTY_VALUES" =& gt; $PROP, // Передаем массив значении для свойств
"NAME" =& gt; strip_tags($_REQUEST['name']),
"ACTIVE" =& gt; "Y", //поумолчанию делаем активным или ставим N для отключении поумолчанию
"PREVIEW_TEXT" =& gt; strip_tags($_REQUEST['description']), //Анонс
"PREVIEW_PICTURE" =& gt; $_FILES['image'], //изображение для анонса
"DETAIL_TEXT" =& gt; strip_tags($_REQUEST['description_detail'],
"DETAIL_PICTURE" =& gt; $_FILES['image_detail'] //изображение для детальной страницы
);
//Результат в конце отработки
if ($ID = $el ->Add($fields)) {
echo "Сохранено";
} else {
echo "Элемент не добавлся из за ошибки: ".$el->LAST_ERROR;
}
}
?>
<? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>
Вот и все. Результат будет отдаваться в запись элемента инфоблока. Уже по вкусу, можете оформлять как угодно, прикручивать js проверку на заполненность или на проверку данных- маски.
На базе данной заметки сделал компонент. Устроен максимально просто, поддается доработкам и расширению функционала. Компонент добавления элемента в инфоблок
Видео: Форма добавления через API
Опубликовав и прочитав записку, понял, что она не до конца понятна. Решил записать поясняющее видео
Обновленное видео, как сделать компонент на базе этой заметки
Спустя какое-то время после написании заметки, сделан видеокурс по созданию доски объявлений. В течении трех серий видеокурса, рассматриваю как сделать компонент на базе способов и методов описанных в заметке.
Кроме того, рассмотрен вариант использования D7 методов. Сам компонент используется и для добавления элемента инфоблока и для редактирования.
Загрузка множественного свойства типа файл
Создаем массив со свойствами файлов, методом CFile::MakeFileArray и передаем в $PROP["MORE_PHOTO"] (в моем случае, свойство с доп картинками)
$arMorePhoto["VALUE"];
$i = 0;
foreach ($_POST["MORE_PHOTO"] as $morePhoto) {
$arMorePhoto['n'.$i] = array("VALUE"=>CFile::MakeFileArray($morePhoto));
$i++;
}
$PROP["MORE_PHOTO"] = $arMorePhoto;