自定义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预先设定的数据注解,但是系统自由的数据注解肯定不适合所有的场合,所以有时候我们需要 ...
随机推荐
- 禁止WPS2019开机自启动
最近开机发现WPS总是自己启动,导致开机速度会慢5s左右,从网上找了很多办法都没用,包括运行+msconfig,启动项里面没有WPS:杀毒软件自启动管理里面也没有找到WPS,百度了一圈也没有找到任何有 ...
- Certbot为域名申请免费SSL证书
Certbot(Let's Encrypt)是一个非盈利性认证机构通过运行互联网安全研究小组(ISRG)提供X.509 证书的传输层安全性不收取任何费用(TLS)加密.证书有效期为90天,在此期间可以 ...
- JavaScript 中的四舍五入
在 JavaScript 中,对数值进行四舍五入操作的场景有以下几种: 向上取整:ceil 向下取整:floor 四舍五入:round 固定精度:toFixed 固定长度:toPrecision 取整 ...
- ReactNative之从HelloWorld中看环境搭建、组件封装、Props及State
开篇呢,先给大家问个好,今天是中秋节,祝大家中秋节快乐!!虽然是中秋节,但是木有回家还是总结一下知识点写写博客吧,想着昨天总结一下的,但是昨天和几个同学小聚了一下,酒逢知己总是千杯少呢,喝的微醺不适合 ...
- 【Python实践-2】求一个或多个数的乘积
# -*- coding: utf-8 -*- #定义一个函数,可接收一个或多个数并计算乘积 def product(*numbers): s=1 for n in numbers: s=s*n re ...
- 《深入理解 JVM 虚拟机》 --- 看书笔记
1.JVM 内存溢出 1.堆溢出:堆要不断的创建对象,如果避免了垃圾回收来清除这些对象,就会产生JVM内存溢出.一般手段是通过内存映像分析工具对Dump出来的堆转储快照进行分析,分清楚到底是内存泄露还 ...
- 分布式基础通信协议:paxos、totem 和 gossip(转载)
背景: 在分布式中,最难解决的一个问题就是多个节点间数据同步问题.为了解决这样的问题,涌现出了各种奇思妙想.只有在解决了如何进行信息同步的基础之上才衍生出形形色色的应用.这里开始介绍几种分布式通信协议 ...
- springboot~@Valid注解对嵌套类型的校验
@Valid注解可以实现数据的验证,你可以定义实体,在实体的属性上添加校验规则,而在API接收数据时添加@valid关键字,这时你的实体将会开启一个校验的功能,具体的代码如下,是最基本的应用: 实体: ...
- java的spi 的简单应用
1.什么是java的spi SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制. 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一 ...
- 微信公众号开发C#系列-1、微信公众平台注册
微信公众号简介 微信公众号分为服务号.订阅号.企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以. 我们所说的微信公众号开发主要指的是公众号的账号类型,公众号的账号类型分为订阅号.服务号.企 ...