forked from perscrew/react-native-form-validator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
139 lines (123 loc) · 4.02 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
'use strict';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import defaultRules from './defaultRules';
import defaultMessages from './defaultMessages';
export default class ValidationComponent extends Component {
constructor(props) {
super(props);
// array to store error on each fields
// ex:
// [{ fieldName: "name", messages: ["The field name is required."] }]
this.errors = [];
// Retrieve props
this.deviceLocale = props.deviceLocale || 'en'; // ex: en, fr
this.rules = props.rules || defaultRules; // rules for Validation
this.messages = props.messages || defaultMessages;
this.state = { error: false };
}
/*
* Method validate to verify if each children respect the validator rules
* Fields example (Array) :
* fields = {
* input1: {
* required:true,
* numbers:true,
* maxLength:5
* }
*}
*/
validate(fields) {
// Reset errors
this._resetErrors();
// Iterate over inner state
for (const key of Object.keys(this.state)) {
// Check if child name is equals to fields array set up in parameters
const rules = fields[key];
if (rules) {
// Check rule for current field
this._checkRules(key, rules, this.state[key]);
}
};
return this.isFormValid();
}
// Method to check rules on a spefific field
_checkRules(fieldName, rules, value) {
for (const key of Object.keys(rules)) {
const isRuleFn = (typeof this.rules[key] == "function");
const isRegExp = (this.rules[key] instanceof RegExp);
if ((isRuleFn && !this.rules[key](rules[key], value)) || (isRegExp && !this.rules[key].test(value))) {
this._addError(fieldName, key, rules[key], isRuleFn);
}
}
}
// Add error
// ex:
// [{ fieldName: "name", messages: ["The field name is required."] }]
_addError(fieldName, rule, value, isFn) {
const errMsg = this.messages[this.deviceLocale][rule].replace("{0}", fieldName).replace("{1}", value);
let [error] = this.errors.filter(err => err.fieldName === fieldName);
// error already exists
if (error) {
// Update existing element
const index = this.errors.indexOf(error);
error.messages.push(errMsg);
error.failedRules.push(rule);
this.errors[index] = error;
} else {
// Add new item
this.errors.push({
fieldName,
failedRules: [rule],
messages: [errMsg]
});
}
this.setState({ error: true });
}
// Reset error fields
_resetErrors() {
this.errors = [];
}
// Method to check if the field is in error
isFieldInError(fieldName) {
return (this.errors.filter(err => err.fieldName === fieldName).length > 0);
}
isFormValid() {
return this.errors.length == 0;
}
// Return an object where the keys are the field names and the value is an array with the rules that failed validation
getFailedRules() {
let failedRulesPerField = {}
for (let index = 0; index < this.errors.length; index++) {
let error = this.errors[index];
failedRulesPerField[error.fieldName] = error.failedRules
}
return failedRulesPerField
}
// Return the rules that failed validation for the given field
getFailedRulesInField(fieldName) {
const foundError = this.errors.find(err => err.fieldName === fieldName)
if (!foundError) {
return []
}
return foundError.failedRules
}
// Concatenate each error messages
getErrorMessages(separator="\n") {
return this.errors.map((err) => err.messages.join(separator)).join(separator);
}
// Method to return errors on a specific field
getErrorsInField(fieldName) {
const foundError = this.errors.find(err => err.fieldName === fieldName)
if (!foundError) {
return []
}
return foundError.messages
}
}
// PropTypes for component
ValidationComponent.propTypes = {
deviceLocale: PropTypes.string, // Used for language locale
rules: PropTypes.object, // rules for validations
messages : PropTypes.object // messages for validation errors
}