自定义react数据验证组件
我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题。如果用户提交的数据不合法,例如格式不正确、非数字类型、超过最大长度、是否必填项、最大值和最小值等等,我们需要在相应的地方给出提示信息。如果用户修正了数据,我们还要将提示信息隐藏起来。
有一些现成的插件可以让你非常方便地实现这一功能,如果你使用的是knockout框架,那么你可以借助于Knockout-Validation这一插件。使用起来很简单,例如我下面的这一段代码:
ko.validation.locale('zh-CN');
ko.validation.rules['money'] = {
validator: function (val) {
if (val === '') return true;
return /^\d+(\.\d{1,2})?$/.test(val);
},
message: '输入的金额不正确'
};
ko.validation.rules['moneyNoZero'] = {
validator: function (val) {
if (val === '') return true;
return isNaN(val) || val != 0;
},
message: '输入的金额不能为0'
};
ko.validation.registerExtenders(); var model = {
MSRP: ko.observable(0),
price: ko.observable().extend({ required: true, number: true, min: 10000, money: true, moneyNoZero: true }),
licence_service_fee: ko.observable().extend({ required: true, money: true }),
purchase_tax: ko.observable().extend({ required: true, money: true }),
vehicle_tax: ko.observable().extend({ required: true, money: true }),
insurance: ko.observable().extend({ required: true, money: true }),
commercial_insurance: ko.observable().extend({ required: true, money: true }),
mortgage: ko.observable(''),
interest_discount: ko.observable(''),
allowance: ko.observable().extend({ money: true }),
special_spec_fee_explain: ko.observable(''),
has_extra_fee: ko.observable(false),
is_new_energy: ko.observable(false)
}; model.extra_fee_explain = ko.observable().extend({
required: {
onlyIf: function () {
return model.has_extra_fee() === true;
}
}
}); model.extra_fee = ko.observable().extend({
required: {
onlyIf: function () {
return model.has_extra_fee() === true;
}
},
money: {
onlyIf: function () {
return model.has_extra_fee() === true;
}
}
}); model.new_energy_allowance_explain = ko.observable().extend({
required: {
onlyIf: function () {
return model.is_new_energy() === true;
}
}
}); model.total_price = ko.computed(function () {
var _total = Number(model.price()) + Number(model.licence_service_fee()) +
Number(model.purchase_tax()) + Number(model.vehicle_tax()) +
Number(model.insurance()) + Number(model.commercial_insurance());
if (model.has_extra_fee()) {
_total += Number(model.extra_fee());
}
if (model.is_new_energy()) {
_total -= Number(model.new_energy_allowance());
}
return isNaN(_total) ? '0' : _total.toFixed(2).replace(/(\.0*$)|(0*$)/, '');
}); model.errors = ko.validation.group(model);
ko.applyBindings(model);
更多使用方法可以查看github上的说明文档和示例。
但是,如果我们前端使用的是React框架,如何来实现和上面knockout类似的功能呢?我们可以考虑将这一相对独立的功能抽出来,写成一个React组件。看下面的代码:
class ValidationInputs extends React.Component {
constructor(props) {
super(props);
this.state = {
isValid: true,
required: this.props.required,
number: this.props.number,
min: this.props.min,
max: this.props.max,
money: this.props.money,
data: null,
errors: ""
}
} componentWillReceiveProps(nextProps) {
var that = this;
if (this.state.data !== nextProps.data) {
return setStateQ({data: nextProps.data}, this).then(function () {
return that.handleValidation();
});
}
} handleValidation() {
var fields = this.state.data; // required validation
if(this.state.required && isNilOrEmpty(fields)){
return setStateQ({errors: '必须填写', isValid: false}, this); }
// number validation
if (this.state.number) {
if (isNaN(fields)) {
return setStateQ({errors: '请输入数字', isValid: false}, this);
}
if (!isNilOrEmpty(this.state.min) && !isNaN(this.state.min) && Number(this.state.min) > Number(fields)) {
return setStateQ({errors: '输入值必须大于等于' + this.state.min, isValid: false}, this);
}
if (!isNilOrEmpty(this.state.max) && !isNaN(this.state.max) && Number(this.state.max) < Number(fields)) {
return setStateQ({errors: '输入值必须小于等于' + this.state.max, isValid: false}, this);
}
}
// money validation
if (this.state.money) {
if (fields.length > 0 && !/^\d+(\.\d{1,2})?$/.test(fields)) {
return setStateQ({errors: '输入的金额不正确', isValid: false}, this);
}
} return setStateQ({errors: '', isValid: true}, this);
} render() {
return <span className="text-danger">{this.state.errors}</span>
}
}
该组件支持的验证项有:
- required:true | false 检查是否必填项。
- number:true | false 检查输入的值是否为数字。
- 如果number为true,可通过max和min来验证最大值和最小值。max和min属性的值都必须为一个有效的数字。
- money:true | false 验证输入的值是否为一个有效的货币格式。货币格式必须为数字,最多允许有两位小数。
如何使用?
我们在父组件的render()方法中加入该组件的引用:
<div className="item">
<div className="col-xs-4">净车价:</div>
<div className="col-xs-7">
<input type="text" className="form-control" placeholder="0" value={this.state.price} onChange={this.changePrice.bind(this)}/>
<ValidationInputs ref="validation1" data={this.state.price} required="true" number="true" min="10000" max="99999999" money="true"/>
</div>
<div className="col-xs-1 text-center">元</div>
<div className="clear"></div>
</div>
我们将price变量加到父组件的state中,并给input控件绑定onChange事件,以便用户在修改了文本框中的内容时,price变量的值可以实时传入到ValidationInputs组件中。这样,ValidationInputs组件就可以立即通过自己的handleValidation()方法对传入的数据按照预先设定的规则进行验证,并决定是否显示错误信息。
注意,这里我们在引用ValidationInputs组件时,设置了一个ref属性,这是为了方便在父组件中获得ValidationInputs组件的验证结果(成功或失败)。我们可以在父组件中通过下面这个方法来进行判断(假设父组件中引用了多个ValidationInputs组件,并且每个引用都设置了不同的ref值):
// 父组件调用该方法来判断所有的输入项是否合法
checkInputs() {
for (var r in this.refs) {
var _ref = this.refs[r];
if (_ref instanceof ValidationInputs) {
if (!_ref.state.isValid) return false;
}
} return true;
}
这样,我们在父组件提交数据之前,可以通过这个方法来判断所有的数据项是否都已经通过验证,如果未通过验证,则不提交表单。
其它几个基于React的数据验证组件,不过貌似都是server端使用的:
https://github.com/edwardfhsiao/react-inputs-validation
https://github.com/learnetto/react-form-validation-demo
https://learnetto.com/blog/how-to-do-simple-form-validation-in-reactjs
自定义react数据验证组件的更多相关文章
- 容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件
大家对如下的Tip组件使用应该不陌生,要想让窗体上的控件使用ToolTip功能,只需要拖动一个ToolTip组件到窗口,所有的控件就可以使用该功能,做信息提示. 本博文要记录的,就是通过容器扩展属性 ...
- kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件
小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...
- [转]MVC自定义数据验证(两个时间的比较)
本文转自:http://www.cnblogs.com/zhangliangzlee/archive/2012/07/26/2610071.html Model: public class Model ...
- 验证组件——FluentValidation
FluentValidation FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开 ...
- [React]全自动数据表格组件——BodeGrid
表格是在后台管理系统中用的最频繁的组件之一,相关的功能有数据的新增和编辑.查询.排序.分页.自定义显示以及一些操作按钮.我们逐一深入进行探讨以及介绍我的设计思路: 新增和编辑 想想我们最开始写新增 ...
- 使用自定义验证组件库扩展 Windows 窗体
使用自定义验证组件库扩展 Windows 窗体 1(共 1)对本文的评价是有帮助 - 评价此主题 发布日期 : 8/24/20 ...
- MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息
Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...
- 通过自定义Attribute及泛型extension封装数据验证过程
需求来源: 在日常工作中,业务流程往往就是大量持续的数据流转.加工.展现过程,在这个过程中,不可避免的就是数据验证的工作.数据验证工作是个很枯燥的重复劳动,没有什么技术含量,需要的就是对业务流程的准确 ...
- asp.net mvc3 数据验证(三)—自定义数据注解
原文:asp.net mvc3 数据验证(三)-自定义数据注解 前两节讲的都是asp.net mvc3预先设定的数据注解,但是系统自由的数据注解肯定不适合所有的场合,所以有时候我们需要 ...
随机推荐
- ORACLE字符集修改ORA-02374\ORA-12899\ORA-02372
IMPDP时部分日志显示这个警告ORA-02374: conversion error loading table "MEMXXX"."T_MEMBER_XXXX&quo ...
- 20190415 - iOS11 无法连接到 App Store 的解决办法
问题:更新 iOS 11 后,打开 App Store 提示: 无法连接至 app store 解决: 进入 iOS 系统[设置][iTunes Store 与 App Store],退出当前登录用户 ...
- Python算法与数据结构--求所有子数组的和的最大值
Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...
- Java引用详解-StrongReference SoftReference WeakReference PhantomReference
1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为: 强引用 > 软引用 > 弱引用 > 虚引用 ⑴强引用(StrongR ...
- Fastadmin安装以及各种问题解决
FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架 https://www.fastadmin.net/ 参照官方文档安装,还是有坑的 首先注意:无需下载PHP.Th ...
- [Swift-2019力扣杯春季决赛]2. 按字典序排列最小的等效字符串
给出长度相同的两个字符串:A 和 B,其中 A[i] 和 B[i] 是一组等价字符.举个例子,如果 A = "abc" 且 B = "cde",那么就有 'a' ...
- 3.Git基础-查看当前文件状态、跟踪新文件、暂存文件、忽略文件、提交更新、移除文件、移动文件
1.检查当前文件状态 -- git status git diff git diff --staged git status :我们可以使用 git status 来查看文件所处的状态.当运 ...
- 精读《V8 引擎 Lazy Parsing》
1. 引言 本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧! 这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性 ...
- 【Vue】 ----- 浅谈vue的生命周期
一.概念 vue生命周期,又叫生命周期钩子函数,是组件从创建到销毁的过程. 二.主要的八大生命周期 1.首先,为方便观察每个周期的特点,我们模拟一个"one"组件的创建与销毁,并在 ...
- cocos creator主程入门教程(九)—— 瓦片地图
五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍瓦片地图,在开发模拟经营类游戏.SLG类游戏.RPG游戏,都会使用到瓦片地图.瓦片地图地面是通 ...