react-form-validator-component
Advanced tools
Comparing version 1.6.5 to 1.6.6
{ | ||
"name": "react-form-validator-component", | ||
"version": "1.6.5", | ||
"version": "1.6.6", | ||
"main": "build/lib/index.js", | ||
@@ -5,0 +5,0 @@ "repository": "git@github.com:JDLT-Ltd/react-form-validator-component.git", |
@@ -90,5 +90,5 @@ # React Form Validator | ||
`Validator` has one **required** props | ||
`Validator` has one **required** prop | ||
* `fields` - an object with one property per input field | ||
The key to each property must match the `name` attribute of the input field it refers to, and its value is an object with one property: a `rules` array of any combination of strings referring to our predefined validation rules and user-defined custom rules. You can optionally provide a `defaultValue` property for each field. This is only required if you want to validate your form on load but are using form field components which don't correlate one-to-one with actual DOM nodes. E.g. `semantic-ui-react`'s `DropDown` component. In that case, the Validator's default method of checking values on load will fail. | ||
The key to each property must match the `name` attribute of the input field it refers to, and its value is an object with one property: a `rules` array of any combination of strings referring to our predefined validation rules and user-defined custom rules. You can optionally provide a `defaultValue` property for each field. This is only required if you want to validate your form on load but are using form field components which don't correlate one-to-one with actual DOM nodes. E.g. `semantic-ui-react`'s `DropDown` component (i.e. the matching `name` attribute cannot be found on a DOM node containing the value to be validated). In those cases, the Validator's default method of checking values on load will fail. However, validation on *change* will be unaffected. | ||
@@ -100,3 +100,3 @@ #### Optional Props | ||
* `parent` - a reference to the component whose state `Validator` should add validated form data to. | ||
By default a property will be added to `parent`'s state with a key equal to the `name` attribute of its `input` and a value equal to the valid input. | ||
By default a property will be added to `parent`'s state with a key equal to the `name` attribute of its `input` and a value equal to the validated input. | ||
* `onValidate` - A handler defining what to do with validated input. | ||
@@ -108,3 +108,3 @@ By default, `Validator` will set `parent.state[fieldName]` to be either valid input or null if input is invalid. | ||
* `validateOnLoad` - a boolean | ||
By defautl `Validator` will attempt to validate every field that is prepopulated on `componentDidMount`. (empty fields will not dsiplay errors - however they will prevent set isFormValid to false). | ||
By defautl `Validator` will attempt to validate every field that is prepopulated on `componentDidMount`. (Empty required fields will not dsiplay errors - however they will set isFormValid to false). | ||
If you want to avoid validation running on load, simply set the value to false. | ||
@@ -114,3 +114,3 @@ | ||
RFVC let's you use a mixture of predefined rules and your personal custom rules, just as it let's you provide your own functionality for `onPassValidation`. | ||
You can use a mixture of predefined rules and your personal custom rules, just as it let's you provide your own functionality for `onPassValidation`. | ||
@@ -169,5 +169,4 @@ #### Default Rules | ||
An object with a property for each field which will be `true` if it's valid and `false` if it's not. | ||
An object with a property for each field. The key matches the `name` property of the field and the value will be `true` if that field is valid and `false` if it's not. | ||
#### `fields` | ||
@@ -204,3 +203,3 @@ | ||
`onChange` will validate the input provided and then update the parent components state, adding any valid input and removing possible invalid input. | ||
`onChange` will validate the input provided and then update the parent component's state, adding any valid input and removing possible invalid input. | ||
@@ -207,0 +206,0 @@ #### `errors` |
@@ -41,3 +41,3 @@ import React from 'react' | ||
name: 'something', | ||
rules: ['isPhoneNumber'], | ||
rules: [], | ||
required: 'test', | ||
@@ -44,0 +44,0 @@ label: 'Something' |
@@ -5,2 +5,5 @@ import React from 'react' | ||
import * as defaultRules from './rules' | ||
import addToStateProperty from './utils/addToStateProperty' | ||
import toArray from './utils/toArray' | ||
export default class Validator extends React.Component { | ||
@@ -10,29 +13,5 @@ constructor(props) { | ||
this.state = { | ||
errors: Object.keys(props.fields).reduce((accumulator, currentValue) => { | ||
accumulator[currentValue] = [] | ||
return accumulator | ||
}, {}), | ||
groupValidation: Object.keys(props.fields).reduce((groupValidation, currentField) => { | ||
const fieldValue = props.fields[currentField] | ||
if (fieldValue.required && typeof fieldValue.required === 'string') { | ||
groupValidation[fieldValue.required] = Object.assign({}, groupValidation[fieldValue.required], { | ||
[currentField]: (fieldValue.rules && fieldValue.rules.length > 0) || fieldValue.required ? false : true | ||
}) | ||
return groupValidation | ||
} | ||
return groupValidation | ||
}, {}), | ||
validation: Object.keys(props.fields).reduce((accumulator, currentValue) => { | ||
const fieldValue = props.fields[currentValue] | ||
//if field is a member of a group, add that group to validation and add the field to validation.groupValidation | ||
if (fieldValue.required && typeof fieldValue.required === 'string') { | ||
accumulator[fieldValue.required] = false | ||
return accumulator | ||
} else { | ||
accumulator[currentValue] = | ||
(fieldValue.rules && fieldValue.rules.length > 0) || fieldValue.required ? false : true | ||
return accumulator | ||
} | ||
}, {}), | ||
errors: this.initialiseStateErrors(props.fields), | ||
groupValidation: this.initialiseStateGroupValidation(props.fields), | ||
validation: this.initialiseStateFieldValidation(props.fields), | ||
isFormValid: false | ||
@@ -42,58 +21,63 @@ } | ||
componentDidUpdate(prevProps) { | ||
if (this.props.fields !== prevProps.fields) | ||
this.setState( | ||
{ | ||
fields: this.props.fields, | ||
errors: Object.keys(this.props.fields).reduce((accumulator, currentValue) => { | ||
accumulator[currentValue] = [] | ||
return accumulator | ||
}, {}), | ||
groupValidation: Object.keys(this.props.fields).reduce((groupValidation, currentField) => { | ||
const fieldValue = this.props.fields[currentField] | ||
if (fieldValue.required && typeof fieldValue.required === 'string') { | ||
groupValidation[fieldValue.required] = Object.assign({}, groupValidation[fieldValue.required], { | ||
[currentField]: (fieldValue.rules && fieldValue.rules.length > 0) || fieldValue.required ? false : true | ||
}) | ||
componentDidMount() { | ||
this.validateFieldsProp() | ||
this.addRequiredRuleToFields() | ||
this.validateFormAndUpdateState() | ||
// TODO: only remove errors from empty fields | ||
if (this.props.validateOnLoad) | ||
Object.values(this.props.fields).forEach(field => this.removeAllErrorMessages(field.name)) | ||
} | ||
return groupValidation | ||
} | ||
return groupValidation | ||
}, {}), | ||
validation: Object.keys(this.props.fields).reduce((accumulator, currentValue) => { | ||
const fieldValue = this.props.fields[currentValue] | ||
//if field is a member of a group, add that group to validation and add the field to validation.groupValidation | ||
if (fieldValue.required && typeof fieldValue.required === 'string') { | ||
accumulator[fieldValue.required] = false | ||
return accumulator | ||
} else { | ||
accumulator[currentValue] = | ||
(fieldValue.rules && fieldValue.rules.length > 0) || fieldValue.required ? false : true | ||
return accumulator | ||
} | ||
}, {}), | ||
isFormValid: false | ||
}, | ||
() => console.log('fields has changed') | ||
) | ||
// each field gets an (empty) array for its errors | ||
initialiseStateErrors(fields) { | ||
return Object.keys(fields).reduce((accumulator, currentValue) => { | ||
accumulator[currentValue] = [] | ||
return accumulator | ||
}, {}) | ||
} | ||
onValidate = (name, value) => { | ||
this.props.parent.setState({ [name]: value }) | ||
initialiseStateGroupValidation(fields) { | ||
return Object.keys(fields).reduce((groupValidation, currentField) => { | ||
const field = fields[currentField] | ||
if (field.required && typeof field.required === 'string') { | ||
groupValidation[field.required] = Object.assign({}, groupValidation[field.required], { | ||
[currentField]: (field.rules && field.rules.length > 0) || field.required ? false : true | ||
}) | ||
return groupValidation | ||
} | ||
return groupValidation | ||
}, {}) | ||
} | ||
toArray = object => { | ||
return Object.entries(object).reduce((accumulator, [key, value]) => { | ||
return accumulator.concat({ | ||
key, | ||
value | ||
initialiseStateFieldValidation(fields) { | ||
return Object.keys(fields).reduce((accumulator, currentValue) => { | ||
const fieldValue = fields[currentValue] | ||
//if field is a member of a group, add that group to validation and add the field to validation.groupValidation | ||
if (fieldValue.required && typeof fieldValue.required === 'string') { | ||
accumulator[fieldValue.required] = false | ||
return accumulator | ||
} else { | ||
accumulator[currentValue] = | ||
(fieldValue.rules && fieldValue.rules.length > 0) || fieldValue.required ? false : true | ||
return accumulator | ||
} | ||
}, {}) | ||
} | ||
componentDidUpdate(prevProps) { | ||
const currentProps = this.props | ||
if (currentProps.fields !== prevProps.fields) | ||
this.setState({ | ||
fields: currentProps.fields, | ||
errors: this.initialiseStateErrors(currentProps.fields), | ||
groupValidation: this.initialiseStateGroupValidation(currentProps.fields), | ||
validation: this.initialiseStateFieldValidation(currentProps.fields), | ||
isFormValid: false | ||
}) | ||
}, []) | ||
} | ||
// merge value with current property on state | ||
addToStateProperty = (target, value) => { | ||
this.setState({ | ||
[target]: Object.assign(this.state[target], value) | ||
}) | ||
// default behaviour for handling successfully validated input | ||
onValidate = (fieldName, fieldValue) => { | ||
this.props.parent.setState({ [fieldName]: fieldValue }) | ||
} | ||
@@ -105,3 +89,3 @@ | ||
if (messagePosition > -1) errorArray.splice(messagePosition, 1) | ||
this.addToStateProperty('errors', { [fieldName]: errorArray }) | ||
addToStateProperty('errors', { [fieldName]: errorArray }, this) | ||
} | ||
@@ -115,10 +99,14 @@ | ||
if (!validation) { | ||
this.addToStateProperty('errors', { | ||
[fieldName]: [...new Set([...(this.state.errors[fieldName] || []), errorMessage])] | ||
}) | ||
addToStateProperty( | ||
'errors', | ||
{ | ||
[fieldName]: [...new Set([...(this.state.errors[fieldName] || []), errorMessage])] | ||
}, | ||
this | ||
) | ||
} else this.removeError(fieldName, errorMessage) | ||
} | ||
validateRules = (fieldName, fieldValue, fieldRules) => { | ||
return fieldRules.reduce((accumulator, fieldRule) => { | ||
validateRules = (fieldName, fieldValue, fieldRules) => | ||
fieldRules.reduce((accumulator, fieldRule) => { | ||
const rule = defaultRules[fieldRule] || fieldRule | ||
@@ -131,3 +119,2 @@ const validation = rule.validator(fieldValue) | ||
}, true) | ||
} | ||
@@ -173,3 +160,4 @@ validateGroup = (fieldName, fieldValue, groupName) => { | ||
validateField = (fieldName, fieldValue) => { | ||
// Check if field is in a group | ||
const field = this.props.fields[fieldName] | ||
// Check whether field is in a group | ||
const groupName = | ||
@@ -180,9 +168,4 @@ this.props.fields[fieldName].required && typeof this.props.fields[fieldName].required === 'string' | ||
// ensure that empty non-required fields pass validation and don't throw errors | ||
if (!groupName && !this.props.fields[fieldName].required && fieldValue.length === 0) { | ||
this.setState( | ||
{ | ||
validation: Object.assign(this.state.validation, { [fieldName]: true }) | ||
}, | ||
() => this.removeAllErrorMessages(fieldName) | ||
) | ||
if (!groupName && !field.required && fieldValue.length === 0) { | ||
addToStateProperty('validation', { [fieldName]: true }, this) | ||
return true | ||
@@ -194,3 +177,3 @@ } | ||
// standard validation | ||
const fieldRules = this.props.fields[fieldName].rules | ||
const fieldRules = field.rules | ||
const isFieldValid = this.validateRules(fieldName, fieldValue, fieldRules) | ||
@@ -204,3 +187,2 @@ this.setState({ | ||
validateFieldAndUpdateState(fieldName, fieldValue) { | ||
console.log('fieldName: ', fieldName, 'fieldValue: ', fieldValue) | ||
const onValidate = this.props.fields[fieldName].onValidate || this.props.onValidate || this.onValidate | ||
@@ -220,13 +202,10 @@ | ||
validateFormAndUpdateState = () => { | ||
const fieldNames = Object.values(this.props.fields).map(field => field.name) | ||
const fields = Object.values(this.props.fields).filter(field => field) | ||
fieldNames.filter(field => field).forEach(fieldName => { | ||
let fieldValue = | ||
Object.values(this.props.fields).find(field => { | ||
return field.name === fieldName | ||
}).defaultValue || | ||
(document.getElementsByName(fieldName)[0] && document.getElementsByName(fieldName)[0].value | ||
? document.getElementsByName(fieldName)[0].value | ||
: '') | ||
this.validateFieldAndUpdateState(fieldName, fieldValue) | ||
fields.forEach(field => { | ||
const valueFromDom = document.getElementsByName(field.name)[0].value | ||
const fieldValue = | ||
field.defaultValue || (document.getElementsByName(field.name)[0] && valueFromDom ? valueFromDom : '') | ||
this.validateFieldAndUpdateState(field.name, fieldValue) | ||
}) | ||
@@ -240,13 +219,13 @@ } | ||
validateFieldsInput = () => { | ||
validateFieldsProp = () => { | ||
Object.values(this.props.fields).forEach(field => { | ||
if (!field.name) throw new Error('Please provide a name value for all of your fields') | ||
if (!field.name) throw new Error(`Please provide a name value for all of your fields`) | ||
if (!field.rules) | ||
throw new Error('Please provide a rules array for each field (or an empty array for non-validated fields)') | ||
throw new Error( | ||
`Please provide a rules array for field ${field.name} (or an empty array for non-validated fields)` | ||
) | ||
}) | ||
} | ||
componentDidMount() { | ||
this.validateFieldsInput() | ||
// Add isRequired rule is field is required and not in a group | ||
// Add isRequired rule if field is required and not in a group | ||
addRequiredRuleToFields() { | ||
Object.values(this.props.fields).forEach(field => { | ||
@@ -259,5 +238,2 @@ if (field.required === true) { | ||
}) | ||
this.validateFormAndUpdateState() | ||
if (this.props.validateOnLoad) | ||
Object.values(this.props.fields).map(field => this.removeAllErrorMessages(field.name)) | ||
} | ||
@@ -270,3 +246,3 @@ | ||
isFieldValid: validation, | ||
fields: this.toArray(this.props.fields || {}), | ||
fields: toArray(this.props.fields || {}), | ||
onChange: this.onChange, | ||
@@ -273,0 +249,0 @@ errors |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17
324582
711
229