Динамические панели для формы на чистом js

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

Речь идет о динамически добавляемых и удаляемых блоках по клику, скажем, на "плюс" либо "минус". Это бывает нужно в проекте для добавления однотипоной информации в формах. Пример уже готовой реализации взят из одного проекта:

Мой скрипт не требует зависимостей. Весит в "неминифициованном" состоянии 4кб. 

Установка

Посмотреть файлы проекта и скачать его можно на моей странице на гитхабе - https://github.com/sazanof/dynamic-panels.

composer require sazanof/dynamic-panels

Подключение

Для того, чтобы подключить скрипты, необходимо добавить в head (или перед закрывающимся </body>) 2 строчки:

<script src="path/to/polyfills.js"></script>
<script src="path/to/dynamic-panels.js"></script>

Скрипт с полифиллами необходим, елси вам нужна более расширенная браузерная поддержка, так как некоторые браузеры до сих пор не умеют понимать closest, forEach, например.

По сути, все. Один скрипт. Дальше вся css стилизация на ваш вкус.

Использование скрипта

Использовать скрипт тоже очень просто:

<script>
    window.addEventListener('DOMContentLoaded',function () {
        var ex1 = new DynamicPanels({
            id:'example1',
            name_key:'details'
        }).init();
        var ex2 = new DynamicPanels({
            id: 'example2',
            name_key: 'dd',
            classes: {
                inner :'.custom_dp_class',
                header : '.custom_dp_class-header',
                title : '.custom_dp_class-title',
                actions : '.custom_dp_class-actions'
            }
        }).init();
    })
</script>

Параметры

  • id - id элемента, в котором находятся панели
  • name_key - имя массива полей (аля name="details[1][description]")
  • classes - прочие классы для стилизации.

Пример формы HTML

Для использования в повторяющихся кусках формы доступны все стандартные элементы (поля ввода, переключатели, выпадающие списки).

<div id="example1">
	<div class="form-group dynamic" data-pos="1">
		<div class="dynamic-header">
			<div class="dynamic-title">
				Position #<span>1</span>
			</div>
			<div class="dynamic-actions">
				<span class="btn" data-plus>+</span>
				<span class="btn" data-minus>-</span>
			</div>
		</div>
		<div class="form-group-inner">
			<label>Title</label>
			<input type="text" name="details[1][title]">
		</div>
		<div class="form-group-inner">
			<label>Option</label>
			<input type="text" name="details[1][option]">
		</div>
		<div class="form-group-inner">
			<label>Photo</label>
			<input type="file" name="photos[]">
		</div>
	</div>
</div>