表单验证工具

表单验证工具

实现思路

​ 对于表单需要校验的内容,参考element-uiant-design实现对是否必填、字符长度、大小、正则、类型校验。其中,类型包括integer、number、string、bool等。校验工具将会把校验结果返回。

​ 对于所有表单数据的一次性校验,只需要传入所有的表单数据和校验规则,校验工具将会返回校验结果。

​ 对于表单某输入项的实时校验,只需要在光标移出输入框时使用校验工具校验。此时传入所有表单的数据、校验规则、以及该项对应的字段名。校验工具将会过滤掉 required(必输校验)。最终返回校验规则

实现代码

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/***
* (一)校验示例
* let stu = {name:'',phone:''};
* let rules = {
* name:[{required:true, message:'请输入名称'}, {minLength:2, maxLength:5, message:'姓名长度在2-5个字符'}],
* phone:[{required:true, message:'请输入手机号'}, {pattern: /^1[34578]\d{9}$/,message:'请输入正确的手机号!'}]
* }
* // 校验全部表单数据
* let validateRes = validateForm(stu, rules);
*
* // 校验某个字段
* let validateRes = validateForm(stu, rules, 'name');
*
* (二)支持校验规则
* 1. 是否必填 required:true|false(message是指不符合规则的提示信息))
* 2. 字符长度校验 minLength:3|maxLength:10(包括3和10)
* 3. 数字大小校验 min:3|max:10(包括3和10)
* 4. 正则校验 pattern:/^1[34578]\d{9}$/ (注意表单输入的都是字符串)
* 5. 类型校验 type:"integer"|"number"|"string"|"bool"
*/

/************************ 校验策略对象 ******************************/
const strategies = {
required: function (val, isRequired) {
if (isRequired) {
return val.length > 0;
}
return true;
},
minLength: function (val, minLen) {
if (val.length > 0) {
return val.length >= minLen;
}
return true;
},
maxLength: function (val, maxLen) {
if (val.length > 0) {
return val.length <= maxLen;
}
return true;
},
min: function (val, minNum) {
if (val.length > 0) {
return Number(val) >= minNum;
}
return true;
},
max: function (val, maxNum) {
if (val.length > 0) {
return Number(val) <= maxNum;
}
return true;
},
pattern: function (val, patternRule) {
if (val.length > 0) {
return patternRule.test(val);
}
return true;
},
type: function (val, valType) {
if (val.length > 0) {
let isRequiredValType = false;
switch (valType) {
case "integer":
if (parseInt(val) === Number(val) && val.indexOf(".") === -1) {
isRequiredValType = true;
}
break;
case "number":
if (parseFloat(val).toString() !== "NaN") {
isRequiredValType = true;
}
default:
if (typeof val === valType) {
isRequiredValType = true;
}
}
return isRequiredValType;
}
return true;
},
};

/******************************* Validator类 ***************************************/
let Validator = function () {
this.cache = [];
};

/**
* 挑选校验规则
*/
Validator.prototype.add = function (rules) {
const _this = this;
rules.forEach(function (item) {
for (let i in item) {
if (strategies.hasOwnProperty(i)) {
const validateGroup = {};
validateGroup[i] = item[i];
validateGroup["message"] = item["message"];
_this.cache.push(validateGroup);
}
}
});
};

/**
* 开始校验
*/
Validator.prototype.start = function (curData) {
const _cache = this.cache;
for (let i = 0; i < _cache.length; i++) {
for (let j in _cache[i]) {
if (strategies.hasOwnProperty(j)) {
if (!strategies[j](curData, this.cache[i][j])) {
return { flag: false, message: this.cache[i]["message"] };
}
}
}
}
return { flag: true };
};

/************************************ 环境调用 **************************************/

/**
* 深拷贝对象数组
* @param {arr} source 数组
*/
const deepCopy = function (source) {
const arr = source.map(function (item) {
let obj = {};
for (let i in item) {
obj[i] = item[i];
}
return obj;
});
return arr;
};

/**
* 过滤子项规则,去除required
* @param {obj} allRules 所有规则
* @param {string} prop 需要获取的规则的子项
*/
const getItemRules = function (allRules, prop) {
let ValidateItemRules = deepCopy(allRules[prop]);
let validateItemRulesWithoutRequired = ValidateItemRules.filter(function (item) {
return !item.hasOwnProperty("required");
});
return validateItemRulesWithoutRequired;
};

/**
* 获取表单中的数据子项
* @param {obj} allData 所有表单数据
* @param {string} prop 需要获取的表单子项
*/
const getItemData = function (allData, prop) {
const data = JSON.parse(JSON.stringify(allData));
return data[prop].toString().trim();
};

/**
*
* @param {string} data 校验数据
* @param {obj} rules 校验规则
*/
const runValidator = function (data, rules) {
const validator = new Validator();
validator.add(rules);
return validator.start(data);
};

/**
* 校验表单
* @param {obj} data 表单数据
* @param {obj} validateRules 表单校验规则
* @param {string} prop 需要校验的子项字段
*/
const validateForm = function (data, validateRules, prop) {
if (prop) {
const curData = getItemData(data, prop);
const rules = getItemRules(validateRules, prop);
if (rules) {
const validateRes = runValidator(curData, rules);
if (!validateRes.flag) {
return { flag: false, name: prop, data: curData, message: validateRes.message };
}
}
return { flag: true };
} else {
for (let i in data) {
const rules = validateRules[i];
const curData = data[i].toString().trim();
if (rules) {
const validateRes = runValidator(curData, rules);
if (!validateRes.flag) {
return { flag: false, name: i, data: data[i], message: validateRes.message };
}
}
}
return { flag: true };
}
};

module.exports = validateForm;

0%