@apass/form-builder
v1.2.3
Published
Form building tool
Downloads
31
Readme
form-builder
Инструмент для быстрого создания интерфейсов форм
Основная идея в том, чтобы один раз описать набор полей и схем данных для них, а потом просто строить из них формы, как из кирпичей.
Layout – описание расположения полей в грид-системе. Описываем на какой строке будут находиться те или иные колонки, их респонсивность и какое поле внутри нее мы хотим отобразить.
Schema – схема данных для поля. Это могут быть данные для автокомплита запрашиваемые с бекенда или просто набор опций для селекта или радио кнопок.
Fields – Набор полей (кирпичей) из которых будет строиться форма. Используем дефолтный набор с классическими HTML инпутами или подключить, например, material-ui.
Installation
npm install @apass/form-builder --save
Getting started
import FormBuilder from 'form-builder'
В качестве примера возьмем классическую форму обратной связи.
Начнем с того, что опишем лейаут формы. Лейаут строится на базе классической 12 колоночной грид системе. В основе лежит библиотека https://github.com/sealninja/react-grid-system.
- Первый ряд: фамилия, имя.
- Второй ряд: дата рождения.
- Третий ряд: тип вопроса.
- Четвертый ряд: текст вопроса.
- Пятый ряд: согласие на обработку данных.
const MyForm: React.FC = () => {
return (
<FromBuilder
layout={[
[ 'name|sm:6', 'surname|sm:6' ],
[ 'birth|sm-content' ]
[ 'questionType' ],
[ 'question' ]
[ 'isAgree' ],
]}
/>
)
}
После того как мы описали лейаут, описываем что из себя представляют поля. Для этого нам потребуется схема.
- Поля name и surname это простые текстовые инпуты, соответственно добавляем в схему два ключа name и surname с типом text, а в лейблы пишем "Имя" и "Фамилия".
- Поле birth должно быть выбором даты указываем тип date.
- Для поля questionType нам потребуются опции типов вопросов, добавляем их в схему с ключем options
- Поле question должно быть большим, соответственно указываем тип textarea и пишем количество рядов.
- Поле isAgree это чекбокс, указываем тип checkbox.
const MyForm: React.FC = () => {
return (
<FromBuilder
layout={[
[ 'name|sm:6', 'surname|sm:6' ],
[ 'birth|sm-content' ]
[ 'questionType' ],
[ 'question' ]
[ 'isAgree' ],
]}
schema={{
name: { type: 'text', label: 'Имя' },
surname: { type: 'checkbox', label: 'Фамилия' },
birth: { type: 'date', label: 'Дата рождения'},
questionType: {
type: 'select',
label: 'Тип вопроса',
options: [
{ label: 'Консультация', value: 1 },
{ label: 'Покупка', value: 2 },
{ label: 'Статус заказа', value: 3 },
]
},
question: { type: 'textarea', label: 'Вопрос'},
isAgree: { type: 'checkbox', label: 'Согласен с ФЗ-66'},
}}
/>
)
}
Форма практически готова, не хватает только валидации полей. Для этого нам понадобится validation где мы пишем условия для необходимых полей. Полный список правил можно посмотреть тут https://github.com/mikeerickson/validatorjs/blob/master/README.md. Для валидации используется библиотека validatejs с laravel validator подобным синтаксисом. Для вывода ошибок на русском языке не забудьте указать validationLang='ru'.
const MyForm: React.FC = () => {
return (
<FromBuilder
layout={[
[ 'name|sm:6', 'surname|sm:6' ],
[ 'birth|sm-content' ]
[ 'questionType' ],
[ 'question' ]
[ 'isAgree' ],
]}
schema={{
name: { type: 'text', label: 'Имя' },
surname: { type: 'checkbox', label: 'Фамилия' },
birth: { type: 'date', label: 'Дата рождения'},
questionType: {
type: 'select',
label: 'Тип вопроса',
options: [
{ label: 'Консультация', value: 1 },
{ label: 'Покупка', value: 2 },
{ label: 'Статус заказа', value: 3 },
]
},
question: { type: 'textarea', label: 'Вопрос'},
isAgree: { type: 'checkbox', label: 'Согласен с ФЗ-66'},
}}
validation={{
name: 'required|max:128',
surname: 'max:128',
birth: 'required',
question: 'required|max:1024',
isAgree: 'required',
}}
validationLang='ru'
/>
)
}
Итак, форма готова. Теперь нужно решить, как мы будем управлять вводимыми данными – controlled или uncontrolled. В примере делаем форму контролируемой передав ей value с изначальным значением полей. Затем добавляем обработчик изменений onChange чтобы записывать каждое изменение в стейт.
const MyForm: React.FC = () => {
const [formValue, setFormValue] = useState({
name: '',
surname: '',
birth: '',
questionType: '',
question: '',
isAgree: '',
})
const handleChange = useCallback(e => {
const { name, value } = e.target
setFormValue(prev => ({ ...prev, [name]: value }))
}, [])
return (
<FromBuilder
layout={[
...
]}
schema={{
...
}}
validation={{
...
}}
validationLang='ru'
value={formValue}
onChange={handleChange}
/>
)
}
Последний штрих - добавление кнопки отправки и обработчика onSubmit.
const MyForm: React.FC = () => {
const [formValue, setFormValue] = useState({
name: '',
surname: '',
birth: '',
questionType: '',
question: '',
isAgree: '',
})
const handleChange = useCallback(e => {
const { name, value } = e.target
setFormValue(prev => ({ ...prev, [name]: value }))
}, [])
const handleSubmit = useCallback((e, formValue, errors, formData) => {
fetch('https://example.com/question', {
method: 'POST',
body: formData,
})
}, [])
return (
<FromBuilder
layout={[
...
]}
schema={{
...
}}
validation={{
...
}}
validationLang='ru'
value={formValue}
onChange={handleChange}
onSubmit={handleSubmit}
>
<button>Отправить</button>
</FormBuilder>
)
}