1.5.4 • Published 3 years ago

simple-form-factory v1.5.4

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

simple-form-factory

Create forms using whatever form components you want

NPM JavaScript Style Guide

Install

npm install --save simple-form-factory

Usage

import { FormFactory } from 'simple-form-factory'

    <FormFactory
      sessionKey='example'
      initialValues={initialValues}
      validation={validation}
      componentList={componentList}
      blueprint={blueprint}
      SubmitButton={(props)=>SubmitButton({...props, setInitialValues})}
      CancelButton={CancelButton}
    />

Props

sessionKey?: string // caches the state object in session memory
initialValues?: object // The initial form values, for the factory to manage
validation?: () => ErrorObject 
componentList?: ComponentsObject 
blueprint: BluePrintObject
SubmitButton?: (props)=>React.Component
CancelButton?: (props)=>React.Component
fieldMapper?: bool // enables field mapper mode
fieldMapperConfig?: FieldMapperObj // required for field mapper mode
updateLocalState?: (props)=>props // Call back function that returns current form values
updateLocalErrors?: (props)=>props // Call back function that returns current form errors
submitCount?: int // you can track your own submitCount, accessible in your componentsList 

Object Definitions
inputObject = {...HTML.InputProps, hideColumn: (props)=>boolean, hideInput: (props)=>boolean } // id && type are required
col = { 1: inputObject, 2: inputObject, ...rest }
ErrorObject = {[field]: 'Error', [field2]: undefined} // field: 'error message'
ComponentsObject =  { Input: (props)=>React.Component, Select: (props)=>React.Component} // props has all the input props, errors and value
BluePrintObject = { rows: int, cols: col[]}

FieldMapperObj = { 
  topRows: col[], 
  mapConfig: {
    rowIds: string[],
    rowStyle?: JSX.StyleObject,
    rowTitle?: ({ rowid }) => React.Component | any, cols: col
}}

Useful Examples

// 3 rows, 1st row : 3 cols, 2nd row : 1 cols, 3rd row : 4 cols, 
const basicBlueprint = { rows: 3, cols: [
{ 1: {...inputProps}, 2: {...inputProps}, 3: {...inputProps} },
{ 1: {...inputProps} },
{ 1: {...inputProps}, 2: {...inputProps}, 3: {...inputProps}, 4: {...inputProps} },
]}

// 2 top level inputs, 3 field mapped rows, 3 columns in each row
const fieldMapperBlueprint = {
  topRows: [{ 1: {...inputProps}, 2: {...inputProps}],
  mapConfig: {
    rowIds: ['Example', 'Example 2', 'Example 3'],
    rowStyle: { alignItems: 'center' },
    rowTitle: ({ rowid }) => rowid !== 'topRow' && <h4>{rowid}</h4>,
    cols: { 
      1: { id: 'firstName', type: 'text', title: 'First Name', onChange: (props)=>null },
      2: { id: 'middleName', type: 'text', title: 'Middle Name', onChange: (props)=>null },
      3: { id: 'lastName', type: 'text', title: 'Last Name', onChange: (props)=>null },
      }
  }
}

Advanced Full Example

import React from 'react'
import { blueprint } from './blueprint'
import { FormFactory } from 'simple-form-factory'

const componentList = {
  Input: (props) => {    
  return <>
  <p>title example</p>
  <input {...props} />
  {!!props.errors[props.id] && <div>{props.errors[props.id]}</div>}
  </>
},
  Select: (props) => {
    return <select {...props}></select>
  }
}

const SubmitButton = (props)=>{
  function handleSubmit(e){
    e.preventDefault()
    props.setInitialValues(props.formValues)
    props.setDirty(false)
  }
return <button disabled={!props.dirty} type="submit" onClick={handleSubmit}>Submit</button>
}

const CancelButton = ()=><button>Delete</button>

const Example = () => {
  const [initialValues, setInitialValues] = React.useState({
    name: 'Brandon',
    middleName: 'Jamal',
    lastName: 'irving'
  })
  function validation(values){
    const errors = {}
    if(!values.name.length) errors.name = 'Error'
    return errors
  }
  return (
    <FormFactory
      initialValues={initialValues}
      validation={validation}
      componentList={componentList}
      blueprint={blueprint}
      SubmitButton={(props)=>SubmitButton({...props, setInitialValues})}
      CancelButton={CancelButton}
    />
  )
}

Advanced Field Mapper Example

import React from 'react'
import { FormFactory } from 'simple-form-factory'

const fieldMapperBlueprint = {
  topRows: [{ 1: { id: 'selectAll', type: 'checkbox', title: 'Select All' }}],
  mapConfig: {
    rowIds: ['Example', 'Example 2', 'Example 3'],
    rowStyle: { alignItems: 'center' },
    rowTitle: ({ rowid }) => rowid !== 'topRow' && <h4>{rowid}</h4>,
    cols: { 
      1: { id: 'firstName', type: 'text', title: 'First Name', onChange: (props)=>null },
      2: { id: 'middleName', type: 'text', title: 'Middle Name', onChange: (props)=>null,
      3: { id: 'lastName', type: 'text', title: 'Last Name', onChange: (props)=>null },
      }
  }
}

const componentList = {
  Input: ({
    id,
    errors,
    rowid,
    value,
    type,
    title,
    onChange,
    baseid,
    submitcount
  }) => {
    const rowErrors =
      (submitcount && !!errors[rowid] && errors[rowid][baseid]) || ''

    return (
      <>
        <p>{title}</p>
        {type === 'checkbox' ? (
          <input
            checked={value}
            id={id}
            type={type}
            value={value}
            onChange={onChange}
          />
        ) : (
          <input id={id} type={type} value={value} onChange={onChange} />
        )}

        {!!rowErrors.length && <div>{rowErrors}</div>}
      </>
    )
  },
  Select: ({
    id,
    errors,
    rowid,
    value,
    type,
    title,
    onChange,
    baseid,
    options,
    submitcount
  }) => {
    const rowErrors =
      (submitcount && !!errors[rowid] && errors[rowid][baseid]) || ''
    return (
      <>
        <h3>{title}</h3>
        <select id={id} type={type} value={value} onChange={onChange}>
          {options.map(({ value, label }, i) => (
            <option value={value} key={i}>
              {label}
            </option>
          ))}
        </select>
        {!!rowErrors.length && <div>{rowErrors}</div>}
      </>
    )
  }
}

export const initialFielValuedMapper = (defaultName) => ({
  selectAll: true,
  firstName: defaultName,
  middleName: '',
  lastName: ''
})

const ExampleMapper = () => {
    const [exampleFields, setexampleFields] = React.useState({})
    const [errors, seterrors] = React.useState({})
    const [submitCount, setsubmitCount] = React.useState(0)
    const hasErrors = () =>{
      let isErrors = false
      Object.keys(errors).forEach(row=>{
        const rowErrors = errors[row]
        Object.keys(rowErrors).forEach(field=>{
          if(rowErrors[field]) isErrors = true
        })
      })
      return isErrors
    }
  
    const rowValidationConfig = {
      firstName: (props)=>{
        let error = null
        if(props.value.length < 3){
          error= 'Enter more'
        }
        return error
      },
    }
  
    function handleSubmit() {
      console.log('log: handleSubmit', {hasErrors: hasErrors(), errors, submitCount, exampleFields})
      setsubmitCount(prevCount => prevCount+=1)
    }
  
    const initialValues = {
      'Example': initialFielValuedMapper('Brandon'),
      'Example 2': initialFielValuedMapper('Levi'),
      'Example 3': initialFielValuedMapper('Tyler'),
    }
  
    return (
      <React.Fragment>
      <FormFactory
        rowValidationConfig={rowValidationConfig}
        fieldMapper
        fieldMapperConfig={config}
        componentList={mapComponentList}
        updateLocalState={setexampleFields}
        updateLocalErrors={seterrors}
        submitCount={submitCount}
        initialValues={initialValues}
      />
      <button onClick={handleSubmit}>Submit</button>
      </React.Fragment>
    )
  }

License

MIT © brandon-irving

1.5.4

3 years ago

1.5.3

3 years ago

1.5.2

3 years ago

1.5.1

3 years ago

1.4.2

3 years ago

1.5.0

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.1

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

1.0.1-0

3 years ago

1.0.0

3 years ago