1.2.3 • Published 4 years ago

@apass/form-builder v1.2.3

Weekly downloads
48
License
ISC
Repository
-
Last release
4 years ago

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>
    )
  }
1.2.3

4 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.1.5

4 years ago

1.1.4

4 years ago

1.1.1

4 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.1.0

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.3

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago