Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Самодельная форма добавления элемента на API Битрикс

Самодельная форма добавления элемента на API Битрикс

Компонент 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" => date("d.m.Y H:i:s"), //Передаем дата создания
	     "CREATED_BY" => $GLOBALS['USER']->GetID(),  //Передаем ID пользователя кто добавляет
	     "IBLOCK_SECTION" => $section_id[$i], //ID разделов
	     "IBLOCK_ID" => $iblock_id, //ID информационного блока он 24-ый
	     "PROPERTY_VALUES" => $PROP, // Передаем массив значении для свойств
	     "NAME" => strip_tags($_REQUEST['name']),
	     "ACTIVE" => "Y", //поумолчанию делаем активным или ставим N для отключении поумолчанию
	     "PREVIEW_TEXT" => strip_tags($_REQUEST['description']), //Анонс
	     "PREVIEW_PICTURE" => $_FILES['image'], //изображение для анонса
	     "DETAIL_TEXT"  => strip_tags($_REQUEST['description_detail'],
	     "DETAIL_PICTURE" => $_FILES['image_detail'] //изображение для детальной страницы
	   );
	  
	   //Результат в конце отработки
	   if ($ID = $el->Add($fields)) {
	     echo "Сохранено";
	   } else {
	     echo 'Произошел как-то косяк Попробуйте еще разок';
	   }
	 }
	 ?>
	 <? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>

Вот и все. Результат будет отдаваться в запись элемента инфоблока. Уже по вкусу, можете оформлять как угодно, прикручивать js проверку на заполненность или на проверку данных- маски.

На базе данной заметки сделал компонент. Устроен максимально просто, поддается доработкам и расширению функционала. Компонент добавления элемента в инфоблок

Видео: Форма добавления через API

Опубликовав и прочитав записку, понял, что она не до конца понятна. Решил записать поясняющее видео

Загрузка множественного свойства типа файл

Создаем массив со свойствами файлов, методом 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;
Роман Юшкин30.06.2018
Понимаю, что звучит странно, потому что у всех все нормально,но, у меня после вставки кода в add_form_result, вышло такое:
Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ',' or ')' in /var/www/u0441588/data/www/***.ru/add_form_result.php on line 47

---
На 47 строке Детальное фото, менять '=>' на ')' или на ',' не знаю зачем. но пробовал! Разумеется не помогает. Что с этим не так?
Niko Kaleva26.01.2019
Здравствуйте
А подскажите как с помощью подобной формы отправлять type="file" ["MORE_PHOTO"] если свойство множественное?
Спасибо за уроки
Даурен Смаилов12.03.2020
Множественные файлы (костыль)
В форме: <input type="file" name="file1" required> <input  type="file" name="file2"> <input type="file" name="file3">$PROP['file'] = В коде: array($_FILES['file1'],$_FILES['file2'], $_FILES['file3']);
Даурен Смаилов12.03.2020
Цитата
Даурен Смаилов пишет:
$PROP['file'] = В коде: array($_FILES['file1'],$_FILES['file2'], $_FILES['file3']);
В коде: $PROP['file'] = array($_FILES['file1'],$_FILES['file2'], $_FILES['file3']);
Михаил Базаров12.03.2020
Цитата
Даурен Смаилов написал:
В коде: $PROP['file'] = array($_FILES['file1'],$_FILES['file2'], $_FILES['file3']);
Можно использовать компонент
bitrix:main.file.input
Код
<? $APPLICATION->IncludeComponent("bitrix:main.file.input", "dragn_n_drop", Array(
                        "INPUT_NAME" => "file", // name использованный в обработке
                        "MULTIPLE" => "Y",  // Разрешить множественную загрузку
                        "MODULE_ID" => "main",
                        "MAX_FILE_SIZE" => "",
                        "ALLOW_UPLOAD" => "A",
                        "ALLOW_UPLOAD_EXT" => ""
                    ),
                        false
); ?>
Виталий Близнецов18.04.2020
Добрый день, Михаил.  Установил  компонент  -  Компонент добавления элемента в инфоблок.

1. При выборе конкретных свойств в компоненте   "Свойства, выводимые в форме:",  на странице все равно отображается весь список свойств инфоблока.

2. В шаблоне компонента увидел опечатку (dragN_n_drop)  "bitrix:main.file.input", "dragn_n_drop",

3. При загрузке файла через компонент "bitrix:main.file.input"  возникает ошибка "При сохранении файла произошла ошибка." .  Перепроверял это свойство на других компонентах, файлы загружаются. С правами и типом файла все норм.

Спасибо.
Михаил Базаров19.04.2020
Цитата
Виталий Близнецов написал:
Компонент добавления элемента в инфоблок
Да, там есть несколько багов. Пока, ни как не доработаю его.
Сейчас, в процессе, доска объявлений- на ней этот компонент дорабатываю (добавление объявлений пользователями, к у авито)
Как докручу выложу.

По множественному добавлению файлов:
Такая доработка обработчика

Создаем массив со свойствами файлов, методом 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;
Виталий Близнецов20.04.2020
Цитата
Михаил Базаров пишет:
[QUOTE][URL=/club/user/13806/]Виталий Близнецов[/URL] написал:
Компонент добавления элемента в инфоблок[/QUOTE] Да, там есть несколько багов. Пока, ни как не доработаю его.
Сейчас, в процессе, доска объявлений- на ней этот компонент дорабатываю (добавление объявлений пользователями, к у авито)
Как докручу выложу.

По множественному добавлению файлов:
Такая доработка обработчика

Создаем массив со свойствами файлов, методом CFile::MakeFileArray и передаем в $PROP["MORE_PHOTO"] (в моем случае, свойство с доп картинками) [CODE] $arMorePhoto["VALUE"];
   $i = 0;
   foreach ($_POST["MORE_PHOTO"] as $morePhoto) {
       $arMorePhoto['n'.$i] = array("VALUE"=>CFile::MakeFileArray($morePhoto));
       $i++;
   }
$PROP["MORE_PHOTO"] = $arMorePhoto; [/CODE]
Добрый день, Михаил.
Этот код я скопировал в component.php
Только не совсем понял как в шаблоне вывести это свойство  $PROP["MORE_PHOTO"] у меня свойство  $PROP["ZAGR_LOGO"]

добавил в шаблоне вместо компонента  "bitrix:main.file.input", но видимо "name"   не передается
Код
 <? if ($field['PROPERTY_TYPE'] == "F") { ?>
                    
                <input type="file"  name="<? echo $PROP["ZAGR_LOGO"] ?>" value="">

Спасибо, за уроки!
Виталий Близнецов23.04.2020
Добрый день, Михаил.
Немного изменил настройки компонента  bitrix:main.file.input и файлы стали закачиваться. Установил шаблон по умолчанию ""  и  "MULTIPLE"=>"N" , так заработало)

Код
  <?$APPLICATION->IncludeComponent("bitrix:main.file.input", "",
                array(
                 "INPUT_NAME"=> $field['CODE'],
                 "MULTIPLE"=>"N",
                 "MODULE_ID"=>"iblock",
                 "MAX_FILE_SIZE"=>"",
                 "ALLOW_UPLOAD"=>"F", 
                 "ALLOW_UPLOAD_EXT"=> ''
                  ),
                   false
                    
                );?>
Виталий Близнецов23.04.2020
Остался такой вопрос.
Компонент выводит все свойства инфоблока. При выборе в списке компонента, все равно все свойства отображаются.
В файле component.php  добавил символьный код 'CODE' => FASE_MAKET, фильтр заработал.
Вопрос: как вывести конкретный список свойств, а не все свойства инфоблока в форму?

Спасибо!
Код
if (CModule::IncludeModule("iblock"))

    $arResult[] = array(
        'IBLOCK_ID' => $arParams['IBLOCK_ID'],
        'PROPERTY_IDS' => $arParams['PROPERTY_CODES'],
        
    );

$arResult['PROPERTY_DATAS'] = array();
$properties = CIBlockProperty::GetList(
    Array("name" => "sort"),
    Array("ACTIVE" => "Y", "IBLOCK_ID" => $arParams['IBLOCK_ID'], 'CODE' => FASE_MAKET,)
);
while ($prop_fields = $properties->GetNext()) {
    array_push($arResult['PROPERTY_DATAS'], $prop_fields);
}

Александр Семашко18.05.2020
Добрый день. Спасибо за форму. Подскажите, кто нибудь уже изменял данную форму, что бы она работала при редактировании элемента. Поделитесь пожалуйста
Павел Шестаков01.07.2020
Добрый день.
Все что нужно уже сделано, но вот возникла такая проблема.
Инфоблок куда пишу данные имеет свойство "Товар" - привязка к элементу инфоблока каталог товаров. При создании заявки нужно сделать выбор 1-3 элементов из каталога.  Как это реализовать полноценно на API не могу разобраться (новичок еще), прошу помощи натолкнуть на мысль.
Михаил Базаров01.07.2020
Цитата
Павел Шестаков написал:
Добрый день.
Все что нужно уже сделано, но вот возникла такая проблема.
Инфоблок куда пишу данные имеет свойство "Товар" - привязка к элементу инфоблока каталог товаров. При создании заявки нужно сделать выбор 1-3 элементов из каталога.  Как это реализовать полноценно на API не могу разобраться (новичок еще), прошу помощи натолкнуть на мысль.
Суть в том, что вам нужно получить список товаров методом
https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php
загнать их в select
И передать в нужное свойство (привязка к элементам) ID выбранного товара
Arsen Sheremeta30.09.2020
Здравствуйте.
У меня пошаговая форма на 6 шагов. Подскажите пожалуйста как сделать чтоб после первого шага форма  создавала запись (элемент), а с каждым следующим шагом, обновляла туже запись а не создавала новую? Спасибо!
Михаил Базаров30.09.2020
Цитата
Arsen Sheremeta пишет:
Здравствуйте.
У меня пошаговая форма на 6 шагов. Подскажите пожалуйста как сделать чтоб после первого шага форма  создавала запись (элемент), а с каждым следующим шагом, обновляла туже запись а не создавала новую? Спасибо!
На первом шаге создаете элемент методом: CIBlockElement::Add
На остальных обновляете методом: CIBlockElement::Update
Arsen Sheremeta30.09.2020
Цитата
Михаил Базаров пишет:
[QUOTE][URL=/club/user/14020/]Arsen Sheremeta[/URL] пишет:
Здравствуйте.
У меня пошаговая форма на 6 шагов. Подскажите пожалуйста как сделать чтоб после первого шага форма  создавала запись (элемент), а с каждым следующим шагом, обновляла туже запись а не создавала новую? Спасибо![/QUOTE] На первом шаге создаете элемент методом: CIBlockElement::Add
На остальных обновляете методом: CIBlockElement::Update
Спасибо!
Roma Rampagev03.10.2020
Все сделал
Максим Максимов16.03.2021
Добрый день
Спасибо за базу знаний по битрикс !
А есть ли возможность сделать и вашей формы редактор статей на сайте ?

Не только создавать статью но и изменять её?
Михаил Базаров20.03.2021
Цитата
Максим Максимов написал:
Добрый день
Спасибо за базу знаний по битрикс !
А есть ли возможность сделать и вашей формы редактор статей на сайте ?

Не только создавать статью но и изменять её?
В целом да. Нужно передать сюда ID статьи и по нему получить все содержимое элемента (методом CIBlockElement::GetByID)
Заполнить им все поля, а дальше в обработчике обновлять с помощью $el->Update

Штука получится монструозная- лучше сделать свой компонент.

Как сделать такой компонент добавления/редактирования элемента, будет рассмотрено в этом курсе
https://camouf.ru/video/board/
Владимир25.06.2021
Здравствуйте!
Хорошее видео. Не подскажете как это всё отправить на почту?
Столкнулся с проблемой нет нигде описание как добавить в форму обратной связи поле "select", решил попробовать как у вас на видео, но не понятно как оправлять ее на почту... ну и прикрутить recaptcha.
Спасибо!

Случайные заметки

FTP доступ на Виртуальной машине Битрикс

Просмотров: 14338 Комментариев: 14
Бывает что нужно открыть FTP доступ к заранее известной папке на сайте под управлением 1С Битрикс, который работает на виртуальной машине от Битрикс. ...

Спойлер в списке новостей Битрикс

Просмотров: 10485 Комментариев: 3
Иногда нужно сделать спойлеры в копонентах Битрикс, в основном конечно, имеет смысл при очень больших обьемах контента. Скорее всего в каталогах, но д...