Создание формы на основе веб-формы Битрикса

0 1.1K

Вариантов создания разнообразных форм обратной связи, заказать звонка и опросников существует великое множество. В блоге мы уже рассматривали вариант создания на основе компонента bitrix.feedback, в этой же статье мы создадим форму на основе компонента form.result.new. Преимущество данного компонента в том, что он способен собирать данные, которые отправляет пользователь у себя в панели, плюс мы можем с легкостью создать столько полей, сколько нам потребуется.

И так, первым делом разместим компонент и сохраним его шаблон. Основной код шаблона компонента я немного урезал, примерно на 80% xD.

Так же создадим вопросы для формы

<script src="<?=$component->__template->GetFolder()?>/js.js"></script>

  <?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>

  <?=($arResult["isFormErrors"] == "Y")? $arResult["FORM_ERRORS_TEXT"] : ''?>

    <?if(!empty($arResult["FORM_NOTE"])):?>
      <?=$APPLICATION->RestartBuffer();?>
      <div class="form__message--success"><?=$arResult["FORM_NOTE"]?></div>
      <?die();?>
    <?else:?>
      <?if($arResult["isFormNote"] != "Y"):?>
        <?=$arResult["FORM_HEADER"]?>
        <?
        foreach ($arResult["QUESTIONS"] as $quest) {
          $settings = array(
            'class' => 'form__control form__control--'.$quest["STRUCTURE"][0]["FIELD_TYPE"],
            'type' => $quest["STRUCTURE"][0]["FIELD_TYPE"],
            'placeholder' => $quest["CAPTION"],
            'name' => 'form_'.$quest["STRUCTURE"][0]["FIELD_TYPE"].'_'.$quest["STRUCTURE"][0]["ID"],
            'data-required' => ($quest["REQUIRED"] === 'Y')? 'true' : '',
          );

          echo ($settings['type'] === 'text')? '<input ' :  '<textarea ';
          foreach ($settings as $param => $value) {
            echo $param.'="'.$value.'"';
          }
          echo ($settings['type'] === 'text')? '>' : '></textarea>';
        }
        ?>
        <input class="form__control form__control--btn" type="submit" value="Отправить" <?=(intval($arResult["F_RIGHT"]) < 10 ? "disabled=\"disabled\"" : "");?> name="web_form_submit"/>
        <input type="hidden" name="web_form_apply" value="Y" />
        <?=$arResult["FORM_FOOTER"]?>
      <?
      endif;
    endif?>

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

var form = document.querySelector('.form');

  form.addEventListener('submit', function(e) {
    
    var error = 0;
    var errorName;
    var closeWindow;
    var closeIcon = '×';
    var errorWindow = '<div id="tool-status" class="form__tool-status form__tool-status--error">'+
                        '<span class="form__tool-close">' + closeIcon + '</span>' +
                        'Поле: ' +
                        '{errorName}' +
                        ' является обязательным' +
                      '</div>';
    var inputs = Array.prototype.slice.call(form.querySelectorAll('[data-required="true"]')); 

    inputs.forEach(function (input) {

      if(input.value.trim() === '') {

        e.preventDefault();

        var name =  input.getAttribute('placeholder').replace(' *','');

        error += 1;

        if(error === 1) {
          errorName = name;
        } else {
          errorName = errorName + ', ' + name;  
        }

        input.classList.add('form__control-status--error');

      } else {

        input.classList.remove('form__control-status--error');

      }

    });

    if(document.getElementById('tool-status')) return;
    if(error > 0) {
      form.insertAdjacentHTML('afterbegin', errorWindow.replace('{errorName}', errorName));

      closeWindow = form.querySelector('.form__tool-close');

      closeWindow.addEventListener('click', function handler(e){
        form.querySelector('.form__tool-status').classList.add('form__tool-hide');
        closeWindow.removeEventListener(e.type, handler);
      });

      setTimeout(function() {
        if(form.querySelector('.form__tool-status')) {
          form.querySelector('.form__tool-status').classList.add('form__tool-hide');
        }
      }, 3000);

    }

    form.querySelector('.form__tool-status').addEventListener('transitionend', function handler(e) {
      form.querySelector('.form__tool-status').removeEventListener(e.type, handler);
      this.parentNode.removeChild(this);
    });

  });

В файл стилей запишите следующее.

.form {
    width: 31rem;
    position: relative;
    margin: 2rem auto;
  }
  .form__message--success {
    text-align: center;
    background: #666;
    color: #fff;
    padding: 1.5rem 0;
  }
  .form__control {
    outline: none;
    width: 100%;
    display: block;
    border: 0;
    padding: 0.8rem;
    background: #333;
    font-size: inherit;
    font-family: inherit;
    color: #fff;
  }
  .form__control--textarea {
    resize: none;
    height: 6.2rem;
  }
  .form__control--btn {
    cursor: pointer;
    background: #3ca1b1;
  }
  .form__control--btn:active {
    background: #666;
  }
  .form__control--text, .form__control--textarea {
    -webkit-transition: all 0.4s;
    transition: all 0.4s;
  }
  .form__control--text:focus, .form__control--textarea:focus {
    background: #666;
  }
  .form__control::-webkit-input-placeholder {
    color: #999;
  }
  .form__control::-moz-placeholder {
    color: #999;
  }
  .form__control:-ms-input-placeholder {
    color: #999;
  }
  .form__control::placeholder {
    color: #999;
  }
  .form__control:focus::-webkit-input-placeholder {
    color: #fff;
  }
  .form__control:focus::-moz-placeholder {
    color: #fff;
  }
  .form__control:focus:-ms-input-placeholder {
    color: #fff;
  }
  .form__control:focus::placeholder {
    color: #fff;
  }
  .form__tool-status {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: .5rem;
    color: #fff;
    max-height: 40px;
    -webkit-transition: max-height .4s, padding .4s;
    transition: max-height .4s, padding .4s;
    overflow: hidden;
  }
  .form__tool-status--error {
    background: #d2656d;
  }
  .form__tool-hide {
    max-height: 0;
    padding: 0 .5rem;
  }
  .form__tool-close {
    position: absolute;
    right: .1rem;
    top: -.7rem;
    font-size: 1.5rem;
    cursor: pointer;
  }
  .form__tool-close:hover {
    opacity: .6;
  }
  .form__control-status--error::-webkit-input-placeholder {
    color: #d2656d;
  }
  .form__control-status--error::-moz-placeholder {
    color: #d2656d;
  }
  .form__control-status--error:-ms-input-placeholder {
    color: #d2656d;
  }
  .form__control-status--error::placeholder {
    color: #d2656d;
  }
  [id*="wait_comp_"] {
    display:none;
  }

Со стилями думаю все понятно, за исключением последней строки которая отрубает Битриксовый прелоудер который появляется при отправке формы если используется Ajax. Если его использовать не задумываете, то можно просто удалить данный стиль.

Получилось у меня такая вот формочка.

Ссылка на пример codepen.io

Комментарии