npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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