3.0.0-alpha.5 • Published 2 days ago

@eitje/form v3.0.0-alpha.5

Weekly downloads
472
License
ISC
Repository
github
Last release
2 days ago

Forms: opiononated React (web & native) forms library

This library empowers you to write feature-packed forms with only a few lines of code.rts It exports three main components, the most important/core component being 'Form':

Base example

import Form from 'initializers/form'
import {Input} from '@eitje/form-fields-web'

<Form onSubmit={data => login(data) }>
  <Input required field="email"/>
  <Input required secure field="password"/>
  <div fieldWrapper>
    <p> hello im just text </p>
    <Input required field="name"/>
  </div>
  <Button submitButton> Submit </Button>
</Form>

Idea

The Form component is the 'brain' of your form and manages the state of all fields & enhances all fields with some extra powers. To work efficiently, it's wise to create your own form fields components and re-use them through the application, for an example look in the form-fields-web GH library.

It knows which of its children are fields because they have the 'field' prop, just as in the example above. If you omit the field prop, the child will not be 'formified'.

Nested fields (fieldWrapper)

To 'formify' nested fields, you have to pass the prop fieldWrapper to the container (arbitrary HTML element). You can also pass namespace to the fieldWrapper to provide all of its field children with that namespace

Props

KeyExplanationDefault value
initialValuesInitial values of the form, provided as an object{}
submitInitialValuesalso submits initialValues that aren't part of the form (normally, we filter out all extra initialValues to prevent you from accidentally posting data you don't want to postfalse
onSubmitWhat to do when form is submitted, provides formData as first argdata => {}
afterSubmitFunctions to run after submit was successfull() => {}
afterSubmMessageMessage to display after successfull submit, will use eitje utils.toastnull
disableddisable whole form, prop will be passed to all childrenfalse
nestedFieldUseful if you want to edit multiple nested items in one form. This builds your nested params
afterChangecallback you can use after any field changes. Invoked with arguments (fieldName, value)
resetAfterSubmitreset form to initialValues after submitfalse
fieldPropsprops to be passed down to all form children with a field prop{}
hiddenFieldsarray of fields that should be hidden (hidden means: not visible, wont be sent along with request, wont be validated)[]

Imperative actions

There are also some actions you can call directly on the form instance. You unlock this by adding a ref to your instance.

Example:

const ref = useRef(null)

<Form ref={ref} onSubmit={data => login(data) }>

</Form>

<Button onClick={() => ref.current.resetValues() }> 
   Reset your form
</Button>

Actions:

ActionExplanationParams
setValues(vals)Set values imperatively{key: value}
resetValues(empty)Reset form state to defaultIf empty is false (default), form will reset to initialValues, otherwise empty object.
getValue(field)Get value of field
submitSubmit the form
validateValidate the form (renders errors)
getValues(fieldsreturn values as object {field: value, field2: value}array of fields
blockSubmit(field, blocked)blocks or de-blocks the form from submitting, automatically re-enables it after 15 secondsfield is name of the field to allow your UI components to render a special 'blocked' state, blocked is a boolean designating whether it's a block or a de-block

MultiForm

The second component is 'MultiForm', which 'duplicates' its children. Useful if you're editing multiple resources at the same time. You can pass it field children, just as you do with form, and it will render that children x amount of times (controllable by you through the amtForms prop). There's also built-in support for adding/deleting forms. An example might help:

<MultiForm  formProps={{styleKind: 'modal', allowEmpty: true}}  afterSubmit={onCancel} onSubmit={data => inviteUser(data)} 
                       autoAdd  amtForms={3}>
      <div className="fRow" fieldWrapper>
        <Input field="email" required/>
        <DropdownPicker  containerStyle={ContainerStyleRow} multiple field="team_ids" labelField="naam" items={teams} />
      </div>

  <Button type="primary" ignoreForm submitButton>{t('submitS')}</Button>
</MultiForm>

This MultiForm will render three forms and will automatically add another form when the last form is changed.

Building your own fields

Props passed to every field

These props are passed by the form to the fields, making them 'formified', which you must implement when building your own.

KeyExplanationDefault value
onChangefunction to update the form's state, do not override this as it will break the form
submitFormWay of submitting form inside a field (useful when you want to submit on enter in an input for example)
formDataCurrent state of input data
blockSubmitTemporarily block submitting of the form, useful if you need to wait on something like asset upload. Will auto unblock after 5 sec, blockSubmit(false) opens the submit again
errorerror text
valuecurrent value
getNextfunction to get the next form child, useful for setting focus

NOTE: Further info about field props can be found on the form-fields-web page

You can use the above ^ props to build your own form fields, made even easier by the following methods:

Easy way (HOC)

This library exports an HOC to simplify the field building process, called makeField. This HOC renders a container and automatically sets the opacity to 0.2 when the field is disabled. Also, it renders the label & potential error. This HOC uses the useFormField hook internally, you can also use the hooks yourself if you have more custom needs. That's explained underneath.

Example of building an input field:

const _Input = (props) => {
  const {value, secure, onChange, ...rest} = props
  const InputEl = secure ? AntInput.Password : AntInput

  return (
        <InputEl {...rest} value={value} onChange={e => onChange(e.target.value)}/>
    )
}

export const Input = makeField(props) 

Now you can import this component to make the first example work!

Advanced way (hooks)

This library also exports two hooks, these hooks simplify the props a bit. You should always use useFormField, usePicker only when working with a select-like input

  • useFormField: returns {error, disabled, label, value}
  • usePicker: returns {pickerItems, selectedItem, selectedBaseItem}

To clarify: pickerItems is an array of objects structured like {key, label, value}. This way it can easily be consumed by any input without that input having to know about the structure of your record

selectedItem is the currently selected item(s) in {key, label, value} style, while selectedBaseItem is the original record (before conversion).

3.0.0-alpha.5

2 days ago

3.0.0-alpha.4

10 days ago

3.0.0-alpha.3

2 months ago

3.0.0-alpha.1

2 months ago

3.0.0-alpha.2

2 months ago

3.0.0

2 months ago

3.0.0-alpha

2 months ago

2.0.28

9 months ago

2.0.29

9 months ago

2.0.35

8 months ago

2.0.36

8 months ago

2.0.33

8 months ago

2.0.34

8 months ago

2.0.31

9 months ago

2.0.32

9 months ago

2.0.30

9 months ago

2.0.26

9 months ago

2.0.27

9 months ago

2.0.24

9 months ago

2.0.25

9 months ago

2.0.22

10 months ago

2.0.23

10 months ago

2.0.21

10 months ago

2.0.19

1 year ago

2.0.20

1 year ago

2.0.15

1 year ago

2.0.16

1 year ago

2.0.13

1 year ago

2.0.14

1 year ago

2.0.17

1 year ago

2.0.18

1 year ago

2.0.3

2 years ago

2.0.5

2 years ago

2.0.4

2 years ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.9

1 year ago

2.0.8

2 years ago

2.0.11

1 year ago

2.0.12

1 year ago

2.0.10

1 year ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0-alpha.19

2 years ago

2.0.0-alpha.22

2 years ago

2.0.0-alpha.21

2 years ago

2.0.0-alpha.20

2 years ago

2.0.0-alpha.28

2 years ago

2.0.0-alpha.27

2 years ago

2.0.0-alpha.26

2 years ago

2.0.0-alpha.25

2 years ago

2.0.0-alpha.24

2 years ago

2.0.0-alpha.23

2 years ago

2.0.0-alpha.18

2 years ago

2.0.0-alpha.17

2 years ago

2.0.0-alpha.16

2 years ago

2.0.0-alpha.15

2 years ago

2.0.0-alpha.14

2 years ago

2.0.0-alpha.9

2 years ago

2.0.0-alpha.11

2 years ago

2.0.0-alpha.10

2 years ago

2.0.0-alpha.13

2 years ago

2.0.0-alpha.12

2 years ago

2.0.0-alpha.7

2 years ago

2.0.0-alpha.8

2 years ago

2.0.0-alpha.3

2 years ago

2.0.0-alpha.4

2 years ago

2.0.0-alpha.5

2 years ago

2.0.0-alpha.6

2 years ago

2.0.0

2 years ago

1.10.17

2 years ago

2.0.0-alpha.2

2 years ago

2.0.0-alpha

2 years ago

1.11.0

2 years ago

1.10.15

2 years ago

1.10.16

2 years ago

1.10.13

2 years ago

1.10.14

2 years ago

1.10.11

2 years ago

1.10.12

2 years ago

1.10.9

2 years ago

1.10.8

2 years ago

1.10.7

2 years ago

1.10.10

2 years ago

1.10.5

2 years ago

1.10.4

2 years ago

1.10.3

2 years ago

1.10.2

2 years ago

1.10.6

2 years ago

1.10.1

2 years ago

1.10.0

2 years ago

1.9.1

3 years ago

1.9.0

3 years ago

1.8.8

3 years ago

1.8.7

3 years ago

1.8.6

3 years ago

1.8.5

3 years ago

1.8.4

3 years ago

1.8.3

3 years ago

1.8.2

3 years ago

1.8.1

3 years ago

1.8.0

3 years ago

1.7.20

3 years ago

1.7.19

3 years ago

1.7.18

3 years ago

1.7.17

3 years ago

1.7.16

3 years ago

1.7.14

3 years ago

1.7.15

3 years ago

1.7.13

3 years ago

1.7.11

3 years ago

1.7.12

3 years ago

1.7.10

3 years ago

1.7.9

3 years ago

1.7.8

3 years ago

1.7.7

3 years ago

1.7.6

3 years ago

1.7.5

3 years ago

1.7.4

3 years ago

1.7.3

3 years ago

1.7.2

3 years ago

1.7.1

3 years ago

1.7.0

3 years ago

1.6.12

3 years ago

1.6.11

3 years ago

1.6.10

3 years ago

1.6.9

3 years ago

1.6.8

3 years ago

1.6.7

3 years ago

1.6.6

3 years ago

1.6.5

3 years ago

1.6.4

3 years ago

1.6.3

3 years ago

1.6.2

3 years ago

1.6.1

3 years ago

1.6.0

3 years ago

1.5.14

3 years ago

1.5.13

3 years ago

1.5.12

3 years ago

1.5.9

3 years ago

1.5.8

3 years ago

1.5.10

3 years ago

1.5.11

3 years ago

1.5.7

3 years ago

1.5.6

3 years ago

1.5.5

3 years ago

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.5.0

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.16

3 years ago

1.2.15

3 years ago

1.2.14

3 years ago

1.2.13

3 years ago

1.2.12

3 years ago

1.2.11

3 years ago

1.2.8

3 years ago

1.2.9

3 years ago

1.2.10

3 years ago

1.2.7

3 years ago

1.2.6

3 years ago

1.2.5

3 years ago

1.2.4

3 years ago

1.2.3

3 years ago

1.2.0

3 years ago

1.2.2

3 years ago

1.2.1

3 years ago

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.6

3 years ago

1.1.5

3 years ago

1.1.4

3 years ago

1.1.2

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.2

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.1

4 years ago

1.0.0

4 years ago