redux-form-manager
v3.0.2
Published
Redux form manager
Downloads
25
Maintainers
Readme
Redux Form Manager
A Form control built with and for React with Redux. Initially built for use in Redux Project
Validatation in form is easy to go...
If you liked, gimme a star, Thanks.
Release Issues
Latest version is v3.0.0
v3.0.0
- Update feature core.getFormError to dispatch firstError of formData to reducer.
- Update feature export new function { getErrorMessage } from 'redux-form-manager'
- Update New Demo https://hlex.github.io/redux-form-manager/demo
v2.16.0
- Fixed bugs rules
equalLength
,maxLength
,minLength
cannot validate and show message properly. - Update rules usage in README.md
- Fixed bugs rules
v2.15.0
- Add
lodash
to peerDependencies for features updateNestedFieldData
- Add
v2.14.0
- Add feature - add props
afterUpdateWhenValid
(default = false) (thanks for KIRAN H)
- Add feature - add props
v2.13.0
- Fixed bugs Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the FormValidation component. (thanks for KIRAN H)
v2.12.0
v2.10.0
- Update React to version 15.6.0
- Using PropTypes from 'prop-types'
v2.9.0
- Add feature -
props in formData
formData: (state, props) => {}
- Add feature -
Special Thanks to 'GA-MO'
This Component Repository created by React Component Boilerplate
React Component boilerplate for creating new React Compoment and everything you need to get started.
I recommend you to use it if you wanna create some awesome component for this world !
Prerequisite
This project uses library React-Redux-Gamo-boilerplate, React, Redux, React-Redux and ES2015 syntax, so make sure that you are capable with it.
- React-Redux-Gamo-boilerplate https://github.com/GA-MO/react-redux-gamo-boilerplate
- ES2015 https://babeljs.io/learn-es2015/
- React https://facebook.github.io/react/
- Redux http://redux.js.org/
- React-Redux https://github.com/reactjs/react-redux
Fast date with Demo & Examples
Live demo: https://hlex.github.io/redux-form-manager/demo
The live demo is still running redux-form-manager v3.0.0
Welcome to clone or fork and give me some pull request.
you can run this repository in your local machine by this command
$ npm run dev
it will serve at localhost:9000
Getting Started
$ npm install redux-form-manager --save
or if you prefer yarn..
$ yarn add redux-form-manager
WARNING !
Basically, we are using loganfsmyth/babel-plugin-transform-decorators-legacy (@ symbol) in any tutorials so make sure that you have added it in your .babelrc
Read more about loganfsmyth/babel-plugin-transform-decorators-legacy
if you don't want to, let's using this format to activate instead.
Stand Alone
export default bindFormValidation(core, afterFieldChange, mapStateToValidationPriority)(YourContainer)
With Connect (React-Redux)
const connectedComponent = connect(mapStateToProps, mapDispatchToProps)(YourContainer)
export default bindFormValidation(core, afterFieldChange, mapStateToValidationPriority)(
connectedComponent
)
Advanced Usage: Reveal Key Features
There are many features we have provided
- Rendering User Interface with any React Components.
- Doing things after update function when any fields dispatched.
- Creating custom validation rules.
- Handling dynamic field properties.
- Customizing action type of each field.
- Validating each field by priority.
- Using Nested field data such as array of object.
- Dispatch firstError to outside container.
- Using other event to dispatch.
Basic Usage: Just copy paste
Create new js file and then copy following codes
import React, { Component } from 'react'
import { bindFormValidation } from 'redux-form-manager'
class TextInputField extends Component {
handleChange = (e) => {
const { onChange } = this.props
onChange(e.target.value)
}
render = () => {
const {
label,
value,
disable,
placeholder,
hidden,
errorMessage,
} = this.props
return (
<div className={`box-form-input ${hidden && 'hidden'}`}>
<label>{label}</label>
<input
type='text',
value={value}
disabled={disabled}
placeholder={placeholder}
onChange={this.handleChange}
/>
<div className='error-message'>{errorMessage}</div>
</div>
)
}
}
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <TextInputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core)
export default class Form extends Component {
render() {
const { formData, renderInputField, firstError } = this.props
return (
<div>
<h1>Form</h1>
{renderInputField(formData.firstname)}
{renderInputField(formData.lastname)}
<h4>error: {firstError}</h4>
</div>
)
}
}
Boom! you got a form with field that could be validated, your page also. Look at your console that
Documentation
Table of Contents
Get Started
Form Data & Field Data Properties
Features
- Rendering User Interface with any React Components.
- Customizing RenderInputField function.
- Doing things after update function when any fields dispatched.
- Creating custom validation rules.
- Handling dynamic field properties.
- Customizing action type of each field.
- Validating each field by priority.
- Using Nested field data such as array of object.
- Dispatch firstError to outside container.
- Using other event to dispatch.
Concept
Coming soon.
Setup
install npm packages
$ npm install redux-form-manager --save
or if you prefer yarn..
$ yarn add redux-form-manager --save
import library at the start of your js file
import { bindFormValidation } from 'redux-form-manager'
InputField
InputField is a UI component that receive event from user. You can create any JSX UI as you want. You just reminded that binding function props with renderUIInputField updateValue.
import React, { Component } from 'react'
class TextInputField extends Component {
handleChange = (e) => {
const { onUpdateValue } = this.props
onUpdateValue(e.target.value)
}
render = () => {
const {
label,
value,
disable,
placeholder,
hidden,
errorMessage,
} = this.props
return (
<div className={`box-form-input ${hidden && 'hidden'}`}>
<label>{label}</label>
<input
type='text',
value={value}
disabled={disabled}
placeholder={placeholder}
onChange={this.handleChange}
/>
<div className='error-message'>{errorMessage}</div>
</div>
)
}
}
Tips for InputField
You can create InputField Component that can morph to other inputs by defining props 'type' such as text, select, checkbox, radio etc.
import React, { Component } from 'react'
import TextInput from 'your/component/path'
import SelectInput from 'your/component/path'
class InputField extends Component {
render() {
switch (type) {
case 'text':
return <TextInput {...this.props}></TextInput>
case 'select':
return <SelectInput {...this.props}></SelectInput>
default:
return <TextInput {...this.props}></TextInput>
}
}
}
export default InputField
bindFormValidation()
bindFormValidation is a higher order function that return function which grant component to have form manager modules which are 'formData', 'renderInputField()', 'firstError'
Core
core is an object to assign variables to bindFormValidation()
all of these keys are required. (Please copy them)
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core)
actionType (defaultActionType in action)
As you know, redux's store has dispatch function which it is a process that fire action to reducer contains actionType and any variables. defaultActionType is a default actionType of store.dispatch when you didn't send fieldData's actionType (we'll talk about this later).
Working Example
Create new js file and then copy following codes
import React, { Component } from 'react'
import InputField, { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: [
required: 'Please fill in your firstname.'
],
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: [
required: 'Please fill in your lastname.'
],
}
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
switch (fieldData.type)
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core)
export default class Form extends Component {
render() {
const { formData, renderInputField, firstError } = this.props
return (
<div>
<h1>Form</h1>
{
renderInputField(formData.firstname)
}
{
renderInputField(formData.lastname)
}
<h4>error: {firstError}</h4>
</div>
)
}
}
Form Data
The common variable of this package is 'formData'
formData is a metadata of the form which it's type is Object. you can describe properties of your form in this variable. In any formData, it contains many fieldDatas.
Example
const formData = {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: [
required: 'Please fill in your firstname.'
],
},
}
Field Data
Another variable of this package, 'fieldData'
fieldData is an Object that define properties of the field. For example, firstname field would have properties like this
Field Data Schema (Recommended)
| Property | Type | ------------- |:-------------: | name | String () | value | String, Object () | rules | Object (*) | type | String | label | String | placeholder | String | disabled | Boolean | hidden | Boolean
(*) is required
You can add any keys as your Component need.
we can define fieldData as follow.
const firstname = {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
Switch UI
In ordinary form, we know that there are many input types such as 'text', 'select', 'radio', 'checkbox' etc. In redux-form-manager we also provide you to config your input type.
just switch (case) in renderUIInputField
import React, { Component } from 'react'
import { bindFormValidation } from 'redux-form-manager'
import TextInput from 'your/component/path'
import SelectInput from 'your/component/path'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'text',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
age: {
name: 'age',
type: 'select',
label: 'Age',
value: '',
placeholder: '',
disabled: false,
hidden: false,
options: [
{
label: '15 years old',
value: '15',
},
{
label: '20 years old',
value: '20',
}
]
rules: {
required: 'Please select your age.'
},
}
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
switch (fieldData.type) {
case 'text':
return <TextInput {...fieldData} onChange={updateValue} />
case 'select':
return <SelectInput {...fieldData} onChange={updateValue} />
default:
return <InputField {...fieldData} onChange={updateValue} />
}
}
}
@bindFormValidation(core)
export default class Form extends Component {
render() {
const { formData, renderInputField, firstError } = this.props
return (
<div>
<h1>Form</h1>
{ renderInputField(formData.firstname) }
{ renderInputField(formData.age) }
<h4>error: {firstError}</h4>
</div>
)
}
}
Custom UI
Building your own custom UI, we are going to use 2nd parameter of renderInputField.
import React, { Component } from 'react'
import { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core)
export default class Form extends Component {
renderMyInputComponent = (fieldData, updateValue) => {
return (
<MyInputComponent
{...fieldData}
onUpdateValue={(value) => updateValue(fieldData.key, value)}
/>
)
}
render() {
const { formData, renderInputField, firstError } = this.props
return (
<div>
<h1>Form</h1>
{ renderInputField(formData.firstname, this.renderMyInputComponent) }
{ renderInputField(formData.lastname) }
<h4>error: {firstError}</h4>
</div>
)
}
}
class MyInputComponent extends Component {
handleChange = (e) => {
const { onUpdateValue } = this.props
onUpdateValue(e.target.value)
}
render() {
return (
const {
label,
value,
disable,
placeholder,
hidden,
errorMessage,
} = this.props
<div className={`box-form-input ${hidden && 'hidden'}`}>
<label>{label}</label>
<input
type='text',
value={value}
disabled={disabled}
placeholder={placeholder}
onChange={this.handleChange}
/>
<div className='error-message'>{errorMessage}</div>
</div>
)
}
}
mapStateToValidationPriority
Validating each field by priority.
import React, { Component } from 'react'
import InputField, { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const mapStateToValidationPriority = state => {
return ['lastname', 'firstname']
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core, null, mapStateToValidationPriority)
afterFieldChange
Doing after update function when any field dispatch.
import React, { Component } from 'react'
import InputField, { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const mapStateToValidationPriority = state => {
return []
}
const afterFieldChange = (dispatch, state) => {
return {
firstname: (value, key) => {
dispatch({
type: 'FORM/CHANGE/CUSTOMER',
key: 'lastname',
value: value
})
},
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core, afterFieldChange, mapStateToValidationPriority)
actionType
Customizing action type of each field.
import React, { Component } from 'react'
import InputField, { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
actionType: 'MY_ACTION_FIRSTNAME',
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
},
},
lastname: {
actionType: 'MY_ACTION_LASTNAME',
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const afterFieldChange = (dispatch, state) => {
return {
firstname: (value, key) => {
dispatch({
type: 'FORM/CHANGE/CUSTOMER',
key: 'lastname',
value: value
})
},
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core, afterFieldChange)
Custom Validation Rules
Rules build-in list
rules: {
'required': `${message}`,
'require': `${message}`,
'email': `${message}`,
'thaiMobile': `${message}`,
'thaiPhone': `${message}`,
'thaiId': `${message}`,
'thaiFullname': `${message}`,
'equalLength': {
length: `${length}`,
message: `${message}`
},
'maxLength': {
maxLength: `${length}`,
message: `${message}`
},
'minLength': {
minLength: `${length}`,
message: `${message}`
},
'alphabet': `${message}`,
'number': `${message}`,
'correctBracket': `${message}`,
'notStartWithSpacing': `${message}`,
'notContainDoubleSpacing': `${message}`,
'notEndWithSpacing': `${message}`,
'notContainSpecialChar': `${message}`,
}
Creating custom validation rules.
import React, { Component } from 'react'
import InputField, { bindFormValidation } from 'redux-form-manager'
const createForm = (state) => {
return {
firstname: {
name: 'firstname',
type: 'input',
label: 'Firstname',
value: '',
placeholder: 'write down your firstname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your firstname.'
customValidate: [
{
message: 'ชื่อต้องขึ้นต้นด้วยตัวเลข',
valid: value => {
return /^\d/.test(value)
}
}
]
},
},
lastname: {
name: 'lastname',
type: 'input',
label: 'Lastname',
value: '',
placeholder: 'write down your lastname',
disabled: false,
hidden: false,
rules: {
required: 'Please fill in your lastname.'
},
}
}
}
const core = {
actionType: 'FORM/CHANGE/CUSTOMER',
formData: (state, props) => createForm(state),
renderUIInputField: (fieldData, updateValue) => {
return <InputField {...fieldData} onChange={updateValue} />
}
}
@bindFormValidation(core)
Nested Field Data
Using Nested field data such as array of object.
Dynamic Field Data properties
Handling dynamic field properties.
Dispatch firsterror
Dispatch firstError to outside container.
Other Dispatchs
Using other event to dispatch.
Contribution
just clone and pull request.
Please open any issues, I will solve it as fast as possible.
Contact me [email protected]
Thank you for your support !