Меню

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

Просмотров: 56983

Компонент 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;
Максим Максимов 16.03.2021
Добрый день
Спасибо за базу знаний по битрикс !
А есть ли возможность сделать и вашей формы редактор статей на сайте ?

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

Не только создавать статью но и изменять её?
В целом да. Нужно передать сюда ID статьи и по нему получить все содержимое элемента (методом CIBlockElement::GetByID)
Заполнить им все поля, а дальше в обработчике обновлять с помощью $el->Update
Владимир 25.06.2021
Здравствуйте!
Хорошее видео. Не подскажете как это всё отправить на почту?
Столкнулся с проблемой нет нигде описание как добавить в форму обратной связи поле "select", решил попробовать как у вас на видео, но не понятно как оправлять ее на почту... ну и прикрутить recaptcha.
Спасибо!
Антон 02.06.2023
Добрый!
Как это все обернут в popUp окно после отправки данных?

    //Результат в конце отработки   if ($ID = $el->Add($fields)) {     echo "Сохранено";   } else {     echo 'Произошел как-то косяк Попробуйте еще разок';   } }

все сделал все работает прекрасно но не красиво нужно всплывающие окно https://bazarow.ru/blog-note/2449/
Михаил Базаров 02.06.2023
Цитата
Антон написал:
Добрый!
Как это все обернут в popUp окно после отправки данных?
//Результат в конце отработки   if ($ID = $el->Add($fields)) {     echo "Сохранено";   } else {     echo 'Произошел как-то косяк Попробуйте еще разок';   } }
все сделал все работает прекрасно но не красиво нужно всплывающие окно https://bazarow.ru/blog-note/2449/

Вариантов много, но самый простой:
- В параметры компонента передать параметр "AJAX_MODE"=>"Y", в компонент не надо ни чего добавлять- там само сработает.
- Саму форму взять в скрытый div, спозицианированный во всплывающее окно.
- При клике на нужную кнопку или ссылку, добавлять этому div-у класс включающий его в показ.
И все сработает.

Более сложный вариант, вот так текстом не расскажу, могу только наводку дать.
Размещаете форму на некой странице и подгружаете ее (форму) в ajax popap. Что бы не мучаться с оконной библиотекой битрикса, можно воспользоваться fancybox - там есть метод работы с подгрузкой сраниц во всплывающее окно.
Дмитрий 05.05.2024
Спасибо за видео, как раз то, что нужно. Только такой вопрос, можно ли таким способом сделать компонент? Чтобы форма и результат хранились в нем, а не в корне самого сайта. И добавлять его на нужную страницу
Михаил Базаров 05.05.2024
Цитата
Дмитрий написал:
Спасибо за видео, как раз то, что нужно. Только такой вопрос, можно ли таким способом сделать компонент? Чтобы форма и результат хранились в нем, а не в корне самого сайта. И добавлять его на нужную страницу
Вот тут, на протяжении 3-х серий рассказываю как это все завернуть в собственный компоненте. Там, как раз эту заметку и беру за основу
https://bazarow.ru/video/video_new/seazon_2_2024/add_edit_form_2/
Гость 07.11.2024
Здраствуйте. Сделал форму, но выдает ошибку, никак не пойму в чем дело.

Вот такие данные мы передалиArray
(
   [name] => Владимир
   [phone] => +7(999) 999-99-99
   [date] => 2024-11-07
   [doktor] => 81
   [usluga] => 19
   [description_detail] => 1
)
Произошел как-то косяк Попробуйте еще разок
Владимир 07.11.2024
Код форм ниже
Код
<?
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_detail'])) {
    CModule::IncludeModule('iblock');

    echo 'Вот такие данные мы передали';
    echo '<pre>';
    print_r($_POST);
    echo '<pre>';

    //Погнали
    $el = new CIBlockElement;
    $iblock_id = 9;
    //$section_id = false;
    //$section_id[$i] = $_POST['section_id']; //Разделы для добавления

    //Свойства
    $PROP = array();

    $PROP['PHONE'] = $_POST['phone']; //Свойство Строка
    $PROP['SPECIALIST'][$c] = $_POST['doktor']; //Свойство Строка
    $PROP['SERVICE'][$c] = $_POST['usluga']; //Свойство Строка
    //$PROP['SELECTOR'] = $_POST['selector']; //Свойство список
    //$PROP['CHEK_BOX'] = $_POST['chek_box']; //Свойство чекбокс
    //$PROP['FILE_POL'] = $_FILES['file_pol']; //Свойство файл
    //$PROP['SPECIALIST'][$c] = $_POST['specialist']; //Чекбоксы привязка к разделам
    //$PROP['SERVICE'][$c] = $_POST['service']; //Чекбоксы привязка к разделам

    //Основные поля элемента
    $fields = array(
         //"DATE_CREATE" => date("d.m.Y H:i:s"), //Передаем дата создания
        //"CREATED_BY" => $GLOBALS['USER'] ->GetID(1),  //Передаем ID пользователя кто добавляет
        "IBLOCK_ID" => $iblock_id, //ID информационного блока он 9-ый
        "PROPERTY_VALUES" => $PROP, // Передаем массив значении для свойств
        "NAME" => strip_tags($_REQUEST['name']),
        //"ACTIVE" => "Y", //поумолчанию делаем активным или ставим N для отключении поумолчанию
        "DETAIL_TEXT" => strip_tags($_REQUEST['description_detail'])
      );

      //Результат в конце отработки
      if ($ID = $el ->Add($fields)) {
           echo "Сохранено";
       } else {
           echo 'Произошел как-то косяк Попробуйте еще разок';
       }
}
?>
<? require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>
Михаил Базаров 09.11.2024
Вместо " echo 'Произошел как-то косяк Попробуйте еще разок';"
впишите
Код
echo "Error: ".$el->LAST_ERROR;

Покажет ошибку

Стоимость и сроки разработки сайтов и приложений

Окончательная стоимость и сроки разработки сайта формируются после обсуждения деталей на этапе заказа. Как правило, они редко выходят за обозначенные ниже рамки.

Интернет магазин: разработка с нуля от 400 000 руб.
от 5-ти недель

Cоздание интернет-магазина на 1С-Битрикс. Разработка с нуля, оптимизация кода под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Сайт на готовом решении / шаблоне от 150 000 руб.
от 7-ми дней

Готовое решение — вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Запускается на одном из 200-та (на ваш выбор) готовых решений.

Мобильное приложение от 400 000 руб.
от 1-го месяца

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Вы можете скачать развернутый опросник на разработку. После ознакомления, задам уточняющие вопросы и оценю проект по стоимости и срокам разработки.