【表单验证】基于jQuery的高度灵活的表单验证(无UI)
表单验证是前端开发过程中常见的一个需求,产品需求、业务逻辑的不同,表单验证的方式方法也有所区别。而最重要的是我们要清楚,表单验证的核心原则是——错误信息提示准确,并且尽可能少的打扰/干扰用户的输入和体验。
该插件依赖于jQuery,demo地址:点击
基于以上原则,个人总结出表单验证的通用方法论:
为了使开发思路更加清晰,我将表单验证的过程分为两步:第一步,用户输入完验证当前输入的有效性;第二步,表单提交时验证整个表单。考虑如下布局:
<form action="">
<ul>
<li><label for="username">用户名</label>
<input type="text" name="username" id="username" placeholder="用户名"/></li>
<li>
<label for="password">密码</label>
<input type="text" name="password" id="password" placeholder="密码"/>
</li>
<li>
<label for="password">确认密码</label>
<input type="text" name="password2" id="password-confirm" placeholder="确认密码"/>
</li>
<li>
<label for="phone">手机</label>
<input type="text" name="mobile" id="phone"/>
</li>
<li>
<label for="email">邮箱</label>
<input type="text" name="email" id="email"/>
</li>
</ul>
<button type="submit" id="submit-btn">提交</button>
</form>
一个较为通用的JS验证版本如下:
(function (window, $, undefined) {
/**
* @param {String} $el 表单元素
* @param {[Array]} rules 自定义验证规则
* @param {[Boolean]} isCheckAll 表单提交前全文验证
* @param {[Function]} callback 全部验证成功后的回调
* rules 支持四个字段:name, rule, message, equalTo
*/
function Validator($el, rules, isCheckAll, callback) {
var required = 'required';
var params = Array.prototype.slice.call(arguments);
this.$el = $el;
this._rules = [
{// 用户名
username: required,
rule: /^[\u4e00-\u9fa5\w]{6,12}$/,
message: '不能包含敏感字符'
}, {// 密码
password: required,
rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
message: '只支持数字字母下划线,且不为纯数字或字母'
}, {// 重复密码
password2: required,
rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
message: '只支持数字字母下划线,且不为纯数字或字母',
equalTo: 'password'
}, {// 手机
mobile: required,
rule: /^1[34578]\d{9}$/,
message: '请输入有效的手机号码'
}, {// 验证码
code : required,
rule: /^\d{6}$/,
message: '请输入6位数字验证码'
}, {// 邮箱
email : required,
rule: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
message: '请输入正确的邮箱'
}
];
this.isCheckAll = false;
this.callback = callback;
// 合并参数
this._rules = this._rules.concat(params[1]);
if(params[2]) {
if(typeof params[2] == 'function') {
this.callback = params[2];
}else {// 提交表单时是否开启全部验证
this.isCheckAll = params[2];
}
}
// 用于存储合去重后的参数
this.rules = [];
}
Validator.prototype._getKey = function (obj) {
var k = '';
for(var key in obj) {
if(obj.hasOwnProperty(key)) {
if( key !== 'rule' && key !== 'message' && key !== 'equalTo') {
k = key;
}
}
}
return k;
};
/**
* 数组对象重复数据进行合并,后面的覆盖前面的
*/
Validator.prototype.filterRules = function (arrObj) {
var _this = this,
h = {},
res = [],
arrObject = this._rules;
$.each(arrObject, function (i, item) {
var k = _this._getKey(item);
try {
if(!h[k] && h[k] !== 0) {
h[k] = i;
res.push(item);
}else {
res[h[k]] = $.extend(res[h[k]], item);
}
}catch(e) {
throw new Error('不是必填')
}
});
this.rules = res;
};
Validator.prototype.check = function () {
var _this = this;
$.each(_this.rules, function (i, item) {
var key = _this._getKey(item),
reg = item.rule,
equalTo = item.equalTo,
errMsg = item.message;
_this.$el.find('[name='+key+']')
.on('blur', function () {
var $this = $(this),
errorMsg = '',
val = $this.val(),
ranges = reg.toString().match(/(\d*,\d*)/),
range = '',
min = 0,
max = 0,
placeholderTxt = $(this).attr("placeholder") ? $(this).attr("placeholder") : '信息';
// 定义错误提示信息
if(val && val != 'undefined') { // 值不为空
if(ranges) { // 边界限定
range = ranges[0];
min = range.split(',')[0] ? range.split(',')[0].trim() : 0;
max = range.split(',')[1] ? range.split(',')[1].trim() : 0;
if(val.length < min || val.length > max) { // 处理边界限定的情况
if(min && max) {
errorMsg = '<span class="error-msg">请输入'+min+'-'+max+'位'+placeholderTxt+'</span>';
}else if(min) {
errorMsg = '<span class="error-msg">最少输入'+min+'位'+placeholderTxt+'</span>';
}else if(max) {
errorMsg = '<span class="error-msg">最多输入'+max+'位'+placeholderTxt+'</span>';
}
}else { // 边界正确但匹配错误
errorMsg = '<span class="error-msg">'+errMsg+'</span>';
}
}else { // 没有边界限定
errorMsg = '<span class="error-msg">'+errMsg+'</span>';
}
if(equalTo) {
var equalToVal = _this.$el.find('[name='+equalTo+']').val();
if(val !== equalToVal) {
errorMsg = '<span class="error-msg">两次输入不一致,请重新输入</span>';
}
}
} else { // 值为空
errorMsg = '<span class="error-msg">请输入'+placeholderTxt+'</span>'
}
if($('.error-msg').length > 0) return;
// 验证输入,显示提示信息
if(!reg.test(val) || (equalTo && val !== equalToVal)) {
if($this.siblings('.error-msg').length == 0) {
$this.after(errorMsg)
.siblings('.error-msg')
.hide()
.fadeIn();
}
}else {
$this.siblings('.error-msg').remove();
}
})
.on('focus', function () {
$(this).siblings('.error-msg').remove();
})
});
};
Validator.prototype.checkAll = function () {
var _this = this;
if(_this.isCheckAll) {
_this.$el.find('[type=submit]')
.click(function () {
_this.$el.find('[name]').trigger('blur');
if($('.error-msg').length > 0) {
console.log('有错误信息');
return false;
}else {
console.log('提交成功');
_this.callback();
}
});
return false;
}
};
Validator.prototype.init = function () {
this.filterRules();
this.check();
this.checkAll();
};
$.fn.validator = function (rules, isCheckAll, callback) {
var validate = new Validator(this, rules, isCheckAll, callback);
return validate.init();
};
})(window, jQuery, undefined);
你可以这样使用:
var rules = [
{// 用户名
username: 'required',
rule: /^[\u4e00-\u9fa5\d]{6,12}$/,
message: '只支持数字loo2222'
},
{// 密码
password: 'required',
rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
message: 'mimmimmia'
},
{// 重复密码
password2: 'required',
rule: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z_@]{6,20}$/,
message: '只支持数字字母下划线,不能为纯数字或字母2222',
equalTo: 'password'
},
{// 座机
telephone : 'required',
rule: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/,
message: '请输入正确的座机'
}
];
$('form').validator(rules, true)
【表单验证】基于jQuery的高度灵活的表单验证(无UI)的更多相关文章
- 基于jQuery会员中心安全修改表单代码
基于jQuery会员中心安全修改表单代码.这是一款登录密码,交易密码,手机号码,实名认证,电子邮箱,安全设置表单,会员表单等设置代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: ...
- {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...
- Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询
Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...
- 10款基于jquery的web前端特效及源码下载
1.jQuery时间轴插件:jQuery Timelinr 这是一款可用于展示历史和计划的时间轴插件,尤其比较适合一些网站展示发展历程.大事件等场景.该插件基于jQuery,可以滑动切换.水平和垂直滚 ...
- 基于jQuery和CSS3炫酷图片3D旋转幻灯片特效
在线预览 源码下载 iPresenter是一款效果非常炫酷的jQuery和CSS3 3D旋转幻灯片特效插件.你可以使用它来制作产品展示.图片画廊或者各种幻灯片和轮播图特效.这款幻灯片插件的特点有: ...
- Django day08 多表操作 (三) 基于对象的跨表查询 基于双下划线的多表查询
一: 基于对象的跨表查询 1. 一对一 正向: 反向: 2. 一对多 正向: 反向: 3.多对多 正向: 反向: 4.*****基于对象的多表查询 二: 基于双下划线的多表查询 1. 连表查询 一对一 ...
- 基于jQuery的Validate表单验证
表单验证可以说在前端开发工作中是无处不在的~ 有数据,有登录,有表单, 都需要前端验证~~ 而我工作中用到最多的就是基于基于jQuery的Validate表单验证~ 就向下面这样~ 因为今天有个朋 ...
- 基于Jquery Validate 的表单验证
基于Jquery Validate 的表单验证 jquery.validate.js是jquery下的一个验证插件,运用此插件我们可以很便捷的对表单元素进行格式验证. 在讲述基于Jquery Vali ...
- 一款基于jQuery的带Tooltip表单验证的注册表单
今天给大家分享一款基于jQuery的注册表单,这款注册表单的特点是确认提交注册信息时,表单会自动验证所填写的信息,如果信息填写有误,即会在相应的字段内以Tooltip提示框的形式显示错误信息.这款jQ ...
随机推荐
- 第4章 类与对象 UML简介
- mybatis框架入门程序:演示通过mybatis实现数据库的插入操作中实现返回结果的获取
1.mybatis实现数据库的插入操作可以查看https://www.cnblogs.com/wyhluckdog/p/10149895.html这篇博文,这里面的插入操作没有返回结果,所以这篇博文就 ...
- ThinkCMF 增加 区域(省、市、区)管理模块
区域管理模块是系统最常使用的一个模块. 可以直接在系统后台管理,前.后台调用. 调用方式: 区域模块使用说明: 1.将目录下的sp_region.sql导入数据库(如果数据库表前缀不是“sp_”,修改 ...
- MySQL中触发器
触发器是与某个事件相关的特殊存储过程,与存储过程不同的是,存储过程需要用 call 调用而出发器不需要使用call调用调用. 也就是自己预先定义好了,当某个事件发生时,就会自动出发触发器进行相关的操作 ...
- fabric实现文本聚焦、可编辑
var canvas = new fabric.Canvas('c'); var tex = new fabric.IText('click',{left:100,top:400});canvas.a ...
- mongo学习-TTL索引 过期数据
在mongo中我们可以设置文档的过期时间,超过时间,文档会自动删除.(2.x版本中 固定结合也支持,但是到了3.x中 固定集合这个索引不好用) 用法: 1.创建一个db:db.createColle ...
- mvc api odata查询选项之 $inlinecount $format 选项(转)
出处:http://www.it165.net/pro/html/201505/40236.html 网上百度“odata 语法”会出来很多结果,其中有一项是比较一致的,那就是odata支持一下几种语 ...
- ACTIVITI 5.14事件监听器的BUG
在ACTIVITI 5.14中,测试内部子流程时发现事件定义的事件监听器不能触发. <activiti:executionListener event="start" del ...
- Linux驱动框架之misc类设备驱动框架
1.何为misc设备 (1)misc中文名就是杂项设备\杂散设备,因为现在的硬件设备多种多样,有好些设备不好对他们进行一个单独的分类,所以就将这些设备全部归属于 杂散设备,也就是misc设备,例如像a ...
- Swift:使用CAShapeLayer打造一个ProgresssBar
ProgressBar是一个很小却在很多地方都会用到的东西.也许是网络连接,也许APP本身有很多东西需要加载的.默认的只有一个旋转的菊花,对于打造一款个性的APP这显然是不够的.这里就使用CAShap ...