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

@schibstedspain/sui-form-builder

v1.5.0

Published

## Description > This component is a form builder, which from a configuration file, generates the different fields of the form and defines their interaction between them.

Downloads

14

Readme

FormBuilder

Description

This component is a form builder, which from a configuration file, generates the different fields of the form and defines their interaction between them.

Installation

$ npm install @schibstedspain/sui-form-builder --save

Usage

import FormBuilder from '@schibstedspain/sui-form-builder'

return (
  <FormBuilder
    config={ptaFormSettings}
    showErrors={isSubmitted && showErrors}
    onLoad={handleLoad}
    onSelect={handleSelect}
    onInputChange={handleInputChange}
    onError={handleError}
  />)

Config

Defines the form items and dependencies between fields.

{
  country: {
    type: 'select',
    label: 'Countries',
    placeholder: 'Select a country',
    next: 'city',
    errors: {
      empty: {
        text: 'Required'
      }
    }
  },
  city: {
    type: 'select',
    label: 'Cities',
    placeholder: 'Select a city',
    next: 'street',
    errors: {
      empty: {
        text: 'Required'
      }
    }
  },
  comments: {
    type: 'text-area',
    label: 'Comments',
    placeholder: 'Type your comments'
    persists: true,
    errors: {
      empty: {
        text: 'Required'
      },
      notAllowed: {
        character: {
          text: 'Do not enter special characters',
          pattern: /[`~@#$^&¬|=<>{}[\]\\]/
        },
        phone: {
          text: 'Do not enter phone numbers',
          pattern: /[0-9]{9}/
        },
        mail: {
          text: 'Do not enter email addresses',
          pattern: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
        },
        url: {
          text: 'Do not enter web browsing addresses',
          pattern: /http|www|ftp/
        }
      }
    }
    
  },
  [...]
}

Accepted config properties

type: string (Required)

select | input | text-area | button-group

next: string

When the user selects an item from this field, the next field refers to the next field from which data will be requested

placeholder: string

Sets input or textarea placeholder

label: string

Sets the formField label

errors: object

Sets the error text to be displayed in case of error in the field

persists: boolean

Defines whether the field data should persist if the user selects one of the higher-level fields.

inputType: string

text | number

size: string

short | long

Accepted config errors properties

empty: object

Defines the error case in which the form field has no value.

notAllowed: object

Defines the error case in which the form field has an invalid character.

Accepted config empty error properties

text: string

Defines the error text that will be displayed if the form field has no value.

Accepted config notAllowed error properties

nameOfYourError: object

Defines the error type name.

Accepted config notAllowed nameOfYourError properties

text: string

Defines the error text that will be displayed if the form field has match with the current condition.

pattern: regex

Defines the error pattern to be evaluated.

onLoad

The form initializes with the next sequence:

1.- Generates an initial state of the form using the config received via props. That means, define the form fields without any value. 2.- Executes the onLoad function from props. 3.- Updates the form state with the returned items list received

  const onLoad = () => {  
    const fieldItems = {
      country: [
        {id: 0, name: 'Germany'},
        {id: 1, name: 'Italy'}
      ]
    }
    return fieldItems
  }

So the country form field, will be initialized as a select, with Germany and Italy options.

Notice that you can initialize as much items as you need. If you have no dependencies between form fields, you can fill the form completely.

onSelect

Once the user selects an item, onSelectChange func will be triggered. This func will receive the nextField, and the selected items (params)

  const [selectedValues, setSelectedValues] = useState(null)
  const [showErrors, setShowErrors] = useState(false)

  const handleSelect = async ({nextField, params}) => {
    console.log(nextField) // city
    console.log(params) // {country: 0}

    const previousPersistsValue = Object.values(selectedValues).filter(
      value => ptaFormSettings[value] && ptaFormSettings[value].persists
    )
    const previousPersistsValues = getValues(previousPersistsValue)
    params = {
      ...params,
      ...previousPersistsValues
    }
    setSelectedValues(params)
    setShowErrors(true)
    return getItems({nextField, params})
  }

  <form className={FORM_WRAP_CLASS} onSubmit={handleSubmit}>
    <FormBuilder
      config={ptaFormSettings}
      showErrors={isSubmitted && showErrors}
      onLoad={handleLoad}
      onSelect={handleSelect}
      onInputChange={handleInputChange}
      onError={handleError}
    />
    <AtomButtom isSubmit disabled={isSubmitted && hasErrors}>
      {submitText}
    </AtomButtom>
  </form>

onInputChange

Once the user selects an item, onInputChange func will be triggered. This func will receive the current field to update

  const [selectedValues, setSelectedValues] = useState(null)

  const handleInputChange = field => {
    setSelectedValues({...selectedValues, ...field})
  }

so the form formBuilder will update the state adding the options list to the city field.

onError

when one of the fields of the form changes state, this function sends to the wrapper component, the error state of these fields

  const handleError = error => consol.log(error) // {country: 'required', city: 'required'}

  <form className={FORM_WRAP_CLASS} onSubmit={handleSubmit}>
    <FormBuilder
      config={ptaFormSettings}
      showErrors={isSubmitted && showErrors}
      onLoad={handleLoad}
      onSelect={handleSelect}
      onInputChange={handleInputChange}
      onError={handleError}
    />
    <AtomButtom isSubmit disabled={isSubmitted && hasErrors}>
      {submitText}
    </AtomButtom>
  </form>

showErrors

when the user sets showError to true, FormsBuilder will display error messages

  const [showErrors, setShowErrors] = useState(false)

  const handleSubmit = e => {
    e.preventDefault()
    setIsSubmitted(true)
    setShowErrors(true)
    !hasErrors && publishDraft()
  }

  <form className={FORM_WRAP_CLASS} onSubmit={handleSubmit}>
    <FormBuilder
      config={ptaFormSettings}
      showErrors={isSubmitted && showErrors}
      onLoad={handleLoad}
      onSelect={handleSelect}
      onInputChange={handleInputChange}
      onError={handleError}
    />
    <AtomButtom isSubmit disabled={isSubmitted && hasErrors}>
      {submitText}
    </AtomButtom>
  </form>

Auto-cleaning the form

When a user selects a field of the form, the default behavior is to clear the following fields that are dependent on the previous one. For instance, if the city field depends on the country:

{
  country: {
    type: 'select',
    next: 'city'
  },
  city: {
    type: 'select'
  }
}

and the user has already selected a country and a city, once the user sets a new country, the form will automatically delete the cities list.

This behavior can be avoided, by setting persists: true in the config:

{
  country: {
    type: 'select',
    next: 'city'
  },
  city: {
    type: 'select',
    persist: true
  }
}