@langleyfoxall/react-dynamic-form-builder v1.2.0-rc.8
Contents
Installation
form-builder can be installed with NPM or Yarn.
# Installing with NPM
npm i --save @langleyfoxall/react-dynamic-form-builder# Installing with Yarn
yarn add @langleyfoxall/react-dynamic-form-builderBasic Example
Check out the demo.
// ./forms/create-user.js
export default [
{
name: 'first_name',
label: 'First Name'
},
{
name: 'last_name',
label: 'Last Name'
},
{
name: 'email_address',
label: 'Email Address',
type: 'email'
},
{
name: 'password',
label: 'Password',
type: 'password'
},
{
name: 'confirmation_password',
label: 'Confirm Password',
type: 'password'
},
];// ./components/create-user-modal.jsx
import React from 'react';
import axios from 'axios';
import FormBuilder from '@langleyfoxall/react-dynamic-form-builder';
import Modal from './modal';
import Form from '../forms/create-user';
class CreateUserModal extends React.Component {
onSubmit(submission) {
return new Promise(resolve => (
axios
.post('/api/register', submission.data.form)
.then(() => console.log('Successfully signed up'))
.catch(() => console.log('Unable to sign up'))
.finally(resolve)
))
}
render() {
return (
<Modal>
<FormBuilder
form={Form}
onSubmit={this.onSubmit}
submitButton={{
text: 'Sign Up'
}}
/>
</Modal>
)
}
}
export default CreateUserModal;Usage
form-builder makes it easier to create dynamic react forms by handling most of the logic involved.
Props
The following props can be passed:
defaultInputClass(string, default:input)defaultLabelClass(string, default:label)defaultContainerClass(string, default:container)defaultValidationErrorClass(string, default:error-label)defaultSubmitClass(string, defaultsubmit)defaultValues(object, default:{})values(object, default:null)classPrefix(string, default:rdf)invalidInputClass(string, default:invalid)validInputClass(string, default:valid)validationTimeout(number, default:1000)submitButton(object,{ text, className? })onSubmit(function)loading(boolean, defaultfalse)loadingElement(element, defaultnull)formErrors(object, default:{})form(array)
defaultInputClass
defaultInputClass is appended to classPrefix on inputs.
// With default value
'rdf-input'defaultLabelClass
defaultLabelClass is appended to classPrefix on labels.
// With default value
'rdf-label'defaultContainerClass
defaultContainerClass is appended to classPrefix on input containers.
// With default value
'rdf-container'defaultValidationErrorClass
defaultValidationErrorClass is appended to classPrefix on error texts.
// With default value
'rdf-error-label'defaultSubmitClass
defaultSubmitClass is appended to classPrefix on the managed submit button.
// With default value
'rdf-submit'defaultValues
defaultValues is used to pre-populate the inputs. It matches the property name against an input name.
// With default value
{}
// With custom value
{
first_name: 'John',
last_name: 'Doe',
}values
values is used to overwrite the state of the form and set values from outside the form.
This should be used in conjunction with onChange.
// With default value
null
// With custom value
{
first_name: 'John',
last_name: 'Doe',
}classPrefix
classPrefix is used to prefix the majority of the class names.
// With default value
'rdf'invalidInputClass
invalidInputClass is appended to classPrefix on invalid inputs.
// With default value
'rdf-invalid'validInputClass
validInputClass is appended to classPrefix on valid inputs.
// With default value
'rdf-valid'submitButton
submitButton can be used to pass a managed submit button into the form.
className is optional and gets appended to classPrefix.
// With custom value
{
text: 'Sign up'
// className: 'secondary-button'
// > 'rdf-secondary-button'
}onSubmit
onSubmit should be called when the form is ready to be submitted, it is also triggered when the submitButton is pressed.
When onSubmit is triggered the callback will recieve an object containing:
{
valid, // Boolean for valid state of inputs
data: {
form, // Data from inputs
validation_errors // An object of errors for each input
}
}loading
loading is used to trigger a loading state on the form which is used to show the loading state
on the managed submit button when a loadingElement has been passed.
// With default value
falseloadingElement
loadingElement is shown when loading is true and a submitButton has been passed.
// With default value
null
// With custom value
<p>Loading...</p>formErrors
formErrors is used to display extra errors that cannot be managed internally by the form builder.
// With default value
{}
// With custom value
{
first_name: '\'John\' is an invalid first name',
}form
form is used to pass the schema used to build the form. This will be explained in more detail here.
// With custom value
[
{
name: 'first_name',
},
]Schema
A form schema can be passed into the form prop. This is used to build the form and display the inputs correctly. The schema consists of an array and child elements. A child can be an array or object. If an array is found then any objects inside will be put on the same row as each other (or wrapped in the same parent container).
Each object child needs at least a name, but can also become more complex and custom:
name(string)placeholder(string)label(string, function, string{})type(string, defaultstring)render(function/node)options(object[])radioContainerClass(string)containerClass(string)inputClass(string)defaultValue(mixed)defaultOptionText(string)validationRules(string, string[], object, object[], RegExp, RegExp[], function, function[])transformer(function{})filter(string, function, RegExp)autocomplete(boolean)renderIf(function)
name
name is used for when data is submitted and passed back to the onSubmit callback.
// With custom value
{
name: 'first_name',
}placeholder
placeholder is used to add placeholder text on empty text inputs.
// With custom value
{
name: 'first_name',
placeholder: 'Enter a first name',
}label
label is used to add a label above the input.
If an object is passed then at least text is required. className is optional.
// With custom value
{
name: 'fist_name',
label: 'First Name',
}
{
name: 'first_name',
label: {
text: 'First Name',
className: 'first-name-label'
}
}
{
name: 'first_name',
label: props => (
<label {...props}>
First Name
</label>
)
}type
type is used to change what type of input is rendered. Valid types input:
- text
- custom
- password
- date
- month
- number
- range
- color
- search
- time
- url
- week
- textarea
- checkbox
- select
- radio
// With default value
{
name: 'first_name',
type: 'string',
}If custom is passed then it is recommended that render is also set.
render
render is used when a normal input is not enough. This can be used to completely customize an input.
When using a function it recieves the following parameters:
input(current input object)value(current input value)onChange(onChange handler)onBlur(onBlur handler)errors(current input errors)state(form state)
When using a node it recieves the following props:
name(current input name)placeholder(current input placeholder)onChange(onChange handler)onBlur(onBlur handler)invalid(invalid boolean)
// With custom value
{
name: 'first_name',
render: () => (
<h1>Custom Render</h1>
),
}
{
name: 'first_name',
render: <h1>Custom Render</h1>,
}It works great with community addons, such as form-select.
// With form select
{
name: 'custom',
label: 'custom',
render: (
<Select
options={[
{ label: 'a', value: 'a' },
{ label: 'b', value: 'b' },
]}
/>
),
}
{
name: 'custom',
label: 'custom',
render: ({ name, placeholder }, value, onChange) => (
<Select
name={name}
placeholder={placeholder}
value={value}
onChange={onChange}
options={[
{ label: 'a', value: 'a' },
{ label: 'b', value: 'b' },
]}
/>
),
}options
options are used for types select or radio.
It should be an array of objects containing: text and value.
{
name: 'gender',
type: 'select',
options: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
{ text: 'Other', value: 'other' },
],
}radioContainerClass
radioContainerClass is appended to classPrefix on the container when type is radio.
// With default value
'rdf-'conatinerClass
containerClass is appended to classPrefix on the container when type is not radio.
// With default value
'rdf-container'inputClass
inputClass is appended to classPrefix on the input.
// With default value
'rdf-input'defaultValue
defaultValue is inserted as the default value when the input has text, if type is checkbox then a truthy/falsey should be passed.
// With custom value
{
name: 'first_name',
defaultValue: 'John',
}defaultOptionText
defaultOptionText is used to select a placeholder option for when type is select.
// With custom value
{
name: 'gender',
defaultOptionText: 'Select a gender...',
}validationRules
validationRules is used when wanting to validate the content of the input. Valid validation rules:
required(not empty)email(valid email)decimal(numeric with optional decimal points)
// With custom value
{
name: 'first_name',
validationRules: 'required',
}
{
name: 'age',
validationRule: /^\d+$/,
}
{
name: 'age',
validationRule: '/^\d+$/',
}
{
name: 'color',
validationRule: this.isValidColor
}
{
name: 'email_address',
validationRules: [
'required', 'email',
],
}Note: Validation rule types can also be mixed.
transformer
tranformer is used to tranform the data before it gets validated/stored.
It should be an object with the keys which define functions:
onChangeonBlur
// With custom value
{
name: 'first_name',
transformer: {
onChange: this.uppercaseWords
}
}filter
filter is used can specific characters should never get stored as a value. It
can be a string, function or RegExp. The character will be ignored if false is returned from the filter.
There are some pre-defined filters:
numericdecimal
// With pre-defined filter
{
name: 'currency',
filter: 'decimal'
}
// With function
{
name: 'currency',
filter: event => event.target.value === 'a'
}
// With RegExp
{
name: 'currency',
filter: /[A-Ba-b]/
}autocomplete
autocomplete can be used in an attempt to counter user agent autofill. By setting
autocomplete to false a random input name is generated, rather than using the name
of the input object.
// With custom value
{
name: 'username',
autocomplete: false
}renderIf
renderIf can be used to render inputs based on the state of the form. When an input
is hidden from the form the validationErrors and form value is reset.
// With custom value
{
name: 'last_name',
// Render if `first_name` has a truthy value
renderIf: ({ form }) => (
!!form.first_name
)
}Addons
A list of community addons, designed to work flawlessly with form-builder.
Make your own
Check out schema.render on how to format your component to work well with form-builder. When creating your component be mindful of what props are passed.
When using a function it recieves the following parameters:
input(current input object)value(current input value)onChange(onChange handler)onBlur(onBlur handler)errors(current input errors)state(form state)
When using a node it recieves the following props:
name(current input name)placeholder(current input placeholder)onChange(onChange handler)onBlur(onBlur handler)invalid(invalid boolean)
Similar Packages
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago