jquery plugin 之 form表单验证插件
基于h5表单验证系统、扩展了对easyui组件的支持
先上图:

提示样式用到了伪对象的 {content: attr(xxx)}函数方法,实现提示信息能动态切换。
1、关键属性说明:
type: 表单元素类型(h5的input类型:number、email等),
max: type为number、range时可用的属性,
min: type为number、range时可用的属性,
pattern: 正则表达式,
maxLength: 元素最大长度,
placeholder: 输入域的填写提示,
required: 必填
required-msg: 为空时的校验提示,
invalid-msg: 正则校验不通过的提示(对应pattern的校验规则)
2、demo - html:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>javascript test</title>
<link rel="stylesheet" type="text/css" href="css/metro/easyui.css">
<link rel="stylesheet" type="text/css" href="css/icon.css">
<link rel="stylesheet" type="text/css" href="css/demo.css">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/valid.js"></script>
<script type="text/javascript" src="js/jquery.easyui.min.js"></script>
<style>
.hidden{
display: none;
} /* 表单校验样式 */
.valid-item {
display: inline-block;
position: relative;
}
.valid-item:after {
content: attr(data-msg);
position: absolute;
top: calc(100% + 2px);
left: 0;
color: #cc0066;
font-size: 10px;
opacity: 0;
transition: opacity 0.5s ease;
text-shadow: 1px 1px 5px silver;
z-index: -1;
}
.valid-item.invalid:after {
opacity: 1;
z-index: 100;
}
</style>
</head> <body>
<div class="middle">
<h5>
<pre>
表单校验:$(form).cform('valid');
</pre>
<pre>
表单提交:$(form).cform('submit',fn);
</pre>
</h5> <form class="easyui-cform" action="index.do" method="post">
<h5>第一种纯容器模式:根据type生成对应的表单元素</h5>
<span class="valid-item" name="name" invalid-msg="字母、数字,以字母开头且最少3位" type="text" maxLength="4"
value="sr" required pattern="^[a-zA-Z_][a-zA-Z0-9_@\.]{2,16}$" placeholder="字母、数字">
<!-- <input id="name" type="text" name="name" value="sc" required pattern="^[a-zA-Z_][a-zA-Z0-9_]{2,16}$" placeholder="字母、数字" class="ignore"/> -->
</span>
<br>
<br>
<h5>第二种非纯容器模式:子节点已经包含表单元素,将不再生成新的表单元素,子节点按h5的表单属性配置</h5>
<span class="valid-item" required-msg="必填项">
<select name="sex" required style="width: 170px;">
<option value="">--select--</option>
<option value="1">man</option>
<option value="2">women</option>
</select>
</span>
<h5>非纯容器模式:easyui-numberbox组件解析</h5>
<span class="valid-item" required-msg="数字必填项">
<input class="easyui-numberbox" name="phone" required style="width: 170px;">
</span>
<h5>非纯容器模式:easyui-combobox组件解析</h5>
<span class="valid-item" name="country" required-msg="必填项">
<input id="cc" class="easyui-combobox" required data-options="
valueField: 'label',
textField: 'value',
data: [{
label: '',
value: 'select'
},{
label: 'java',
value: 'Java'
},{
label: 'perl',
value: 'Perl'
},{
label: 'ruby',
value: 'Ruby'
}
]" />
</span>
<input type="submit" value="submit">
</form>
</div>
</body>
</html>
3、valid.js:
function easyuiInvalidProcess(item, value) {
item.parentNode.classList.add('invalid');
var $pnode = $(item.parentNode),
requiredMsg = $pnode.attr('required-msg') || $.fn.cform.defaults.required,
invalidMsg = $pnode.attr('invalid-msg') || $.fn.cform.defaults.invalid;
if (value) {
item.parentNode.classList.remove('invalid');
$pnode.attr('data-msg', '');
} else $pnode.attr('data-msg', requiredMsg);
}
(function($) {
function _initItem(form) { /* 初始化校验容器 */
var ctns = $('.valid-item', form).not('.hasparsed');
ctns.each(function(index, item) {
var $item = $(item),
props = {
id: $item.prop('id') ? $item.prop('id') + '_input' : undefined,
name: $item.attr('name'),
value: $item.attr('value'),
type: $item.attr('type') || 'text',
max: $item.attr('max'),
min: $item.attr('min'),
pattern: $item.attr('pattern'),
maxLength: $item.attr('maxLength'),
placeholder: $item.attr('placeholder'),
required: $item.attr('required') || $item.attr('required')
},
propstr = ' ';
$.each(props, function(key, value) {
if (value) propstr += key + '=' + value + ' ';
});
var itemChilds = $item.children(),
noChild = itemChilds.length == 0;
if (noChild) { /* 校验容器如果没有子节点则生成type对应的表单元素 */
var $input = $('<input ' + propstr + '/>');
$(this).append($input);
item.removeAttribute('name');
} else {
itemChilds.each(function(n, child) {
var isEasyui = $(child).prop('class').indexOf('easyui-') >=
0;
if (isEasyui) { /* easyui组件初始化 */
$.each(props, function(key, value) {
if (value) $(child).attr(key, value);
});
$(child).addClass('ignore');
item.removeAttribute('name');
var options = $(child).data('options') || '';
if (options) {
options +=
',onChange:function(val,oval){ easyuiInvalidProcess(this, val); }';
} else {
options +=
'onChange:function(val,oval){ easyuiInvalidProcess(this, val); }';
}
$(child).attr('data-options', options);
/* 解决报错:An invalid form control with name='' is not focusable */
$(child).removeAttr('required');
}
});
}
ctns.addClass('hasparsed');
});
}
function itemInvalidProcess(item) {
item.setCustomValidity(' ');
item.parentNode.classList.add('invalid');
var $pnode = $(item.parentNode),
requiredMsg = $pnode.attr('required-msg') || $.fn.cform.defaults.required,
invalidMsg = $pnode.attr('invalid-msg') || $.fn.cform.defaults.invalid;
if (item.validity.valueMissing) $pnode.attr('data-msg', requiredMsg);
else $pnode.attr('data-msg', invalidMsg);
}
function _initValid(form, op) { /* 初始化form及表单元素 */
if (form) {
bindEvent(form);
_initItem(form);
var inputs = $(':input', form).not('.ignore');
inputs.map(function(index, item) {
var $input = $(item);
item.addEventListener('invalid', function() {
itemInvalidProcess(this);
});
item.addEventListener('input', function() {
this.setCustomValidity('');
this.parentNode.classList.remove('invalid');
if (!this.validity.valid) { /* this.validity h5表单元素的校验结果对象 */
itemInvalidProcess(this);
}
});
});
form.addEventListener('submit', function() { /* 校验通过时执行 */
console.log(123);
});
};
}
function bindEvent(form) { /* 关掉浏览器默认行为 */
var $form = $(form);
$form.data('submit', form.submit);
form.submit = function(event) {
var valid = validCheck(form);
if (valid) $form.data('submit').call(form);
};
$form.on("invalid", "form", function(event) {
event.preventDefault();
});
$form.on("click", "input[type=submit]", function(event) {
var valid = validCheck(form);
if (!valid) event.preventDefault();
});
}
function validCheck(form) { /* 检查校验是否通过 */
var inputs = $(':input', form),
valid = true;
inputs.map(function(index, item) {
var iCls = $(item).prop('class');
if (item.type != "submit" && !item.checkValidity() && iCls.indexOf(
'ignore') < 0) {
valid = false;
} else if (iCls.indexOf('textbox-value') >= 0) {
/* 扩展easyui组件支持 */
var domCtn = $('[textboxname="' + $(item).attr('name') + '"]'),
clist = domCtn[0].classList;
$.each(clist, function(n, cls) {
try {
var pName = cls.replace('easyui-', ''),
value = domCtn[pName]('getValue');
if (value) {
} else valid = false;
easyuiInvalidProcess(domCtn[0], value);
} catch (e) {}
});
}
});
return valid;
}
$.fn.cform = function(options, param) {
/* 判断是否为对外调用API */
if (typeof options == 'string') {
return $.fn.cform.methods[options](this, param);
}
/* 初始化组件 */
var op = $.extend({}, $.fn.cform.defaults, options);
return this.each(function() {
_initValid(this, op)
});
}
$.fn.cform.methods = {
valid: function(form, param) {
var $inputs = $(':input', form) || [];
for (var i = 0; i < $inputs.length; i++) {
var input = $inputs[i];
if (input.type != "submit" && !input.validity.valid) {
input.checkValidity();
return false;
}
}
return true;
},
submit: function(form, fn) {
return form.each(function() {
var url = form.prop('action'),
dataType = 'json';
var valid = validCheck(form);
if (valid) {
try {
var param = $(form).serializeJson();
$.post(url, param, function(data) {
try {
if (typeof fn == 'function') fn(data);
} catch (e) {}
}, dataType);
} catch (e) {}
}
});
}
}
$.fn.cform.defaults = {
required: 'field required !',
invalid: 'field invalid !'
}
})(jQuery)
4、easyui-parser改动处:
$.parser = {
auto: true,
onComplete: function(_1) {},
plugins: ["draggable", "droppable", "resizable", "pagination",
"tooltip", "linkbutton", "menu", "menubutton", "splitbutton",
"cform", /* 为了让组件自动解析 */
"switchbutton", "progressbar", "tree", "textbox", "filebox",
"combo", "combobox", "combotree", "combogrid", "numberbox",
"validatebox", "searchbox", "spinner", "numberspinner",
"timespinner", "datetimespinner", "calendar", "datebox",
"datetimebox", "slider", "layout", "panel", "datagrid",
"propertygrid", "treegrid", "datalist", "tabs", "accordion",
"window", "dialog", "form"
],
jquery plugin 之 form表单验证插件的更多相关文章
- jQuery html5Validate基于HTML5表单验证插件
更新于2016-02-25 前面提到的新版目前线上已经可以访问: http://mp.gtimg.cn/old_mp/assets/js/common/ui/Validate.js demo体验狠狠地 ...
- [php基础]PHP Form表单验证:PHP form validator使用说明
在PHP网站开发建设中,用户注册.留言是必不可少的功能,用户提交的信息数据都是通过Form表单提交,为了保证数据的完整性.安全性,PHP Form表单验证是过滤数据的首要环节,PHP对表单提交数据的验 ...
- jQuery Form 表单提交插件----Form 简介,官方文档,官方下载地址
一.jQuery Form简介 jQuery Form插件是一个优秀的Ajax表单插件,可以非常容易地.无侵入地升级HTML表单以支持Ajax.jQuery Form有两个核心方法 -- ajaxF ...
- jQuery Validate 表单验证插件----通过name属性来关联字段来验证,改变默认的提示信息,将校验规则写到 js 代码中
一.下载依赖包 网盘下载:https://yunpan.cn/cryvgGGAQ3DSW 访问密码 f224 二. 添加一个另外一个插件jquery.validate.messages_cn.js. ...
- jQuery Validate 表单验证插件----Validate简介,官方文档,官方下载地址
一. jQuery Validate 插件的介绍 jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆 ...
- jquery validate表单验证插件-推荐
1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家. 1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素 3.鼠标离开后的正确.错误提示及鼠标移入时的帮 ...
- 表单验证插件之jquery.validate.js
提到表单验证的插件,第一个想到的就是jquery.validate.js,所以小生想在这里稍微详细地说一下这款插件的具体使用方法,便于理解,我直接附上整段demo的代码(没怎么调样式,主要是看js): ...
- jQuery学习之:Validation表单验证插件
http://polaris.blog.51cto.com/1146394/258781/ 最近由于公司决定使用AJAX + Struts2来重构项目,让我仔细研究一下这两个,然后集中给同事讲讲,让每 ...
- jquery validate表单验证插件
1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家. 1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素 3.鼠标离开后的正确.错误提示及鼠标移入时的帮 ...
随机推荐
- FP ABPPMGR表 其它常用存储过程
SAP_MATERIAL_SO:处理材料订单缺少BOM,ROUTING信息 1. 增加这部分订单的BOM信息 2. 增加这部分订单材料的ROUTING信息 3. 如果是 ...
- Java Timer
Java Timer 定时类,主要用来执行定时任务 Timer管理所有要执行的定时任务 TimerTask封装好的定时任务 常见的用法 MyTask myTask = new MyTask(); Ti ...
- 安卓GreenDao框架一些进阶用法整理(转)
大致分为以下几个方面: 一些查询指令整理 使用SQL语句进行特殊查询 检测表字段是否存在 数据库升级 数据库表字段赋初始值 一.查询指令整理 1.链式执行的指令 return mDaoSession. ...
- Winform开发框架之简易工作流设计(转自 伍华聪博客)
Winform开发框架之简易工作流设计 一讲到工作流,很多人第一反应就是这个东西很深奥,有时候又觉得离我们较为遥远,确实完善的工作流设计很多方面,而正是由于需要兼顾很多方面,一般通用的工作流都难做到尽 ...
- Netty实践二(心跳检测)
我们使用Socket通信一般经常会处理多个服务器之间的心跳检测,一般来讲,我们去维护服务器集群,肯定要有一台或几台服务器主机(Master),然后还应该有N台(Slave),那么我们的主机肯定要时时刻 ...
- 【Linux 进程】fork函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...
- Django的rest_framework的序列化组件之序列化多表字段的方法
首先,因为我们安装了restframework,所以我们需要在django的settings中引入restframework INSTALLED_APPS = [ 'django.contrib.ad ...
- git中 vi/vim的命令
一.vi & vim 有两种工作模式: 1.命令模式:接受.执行 vi操作命令的模式,打开文件后的默认模式: 2.编辑模式:对打开的文件内容进行 增.删.改 操作的模式: 在编辑模式下按下ES ...
- npoi设置数据有效性
npoi设置数据有效性 public void SetDataValidate(ISheet sheet, int firstCol, int lastCol) { CellRangeAddressL ...
- HTML 转 PDF 之 wkhtmltopdf 工具精讲
术语定义 文档对象 “文档对象”是指PDF文档中的文档对象,共有三种类型的“文档对象”,他们分别是“页面对象”,“封面对象”和“目录对象”. 页面对象 “页面对象”是指以页面的形式在PDF文档中呈现的 ...