Html5用户注册自动校验
Posted 火雨_Nick
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Html5用户注册自动校验相关的知识,希望对你有一定的参考价值。
抽时间写了一个带有自动校验功能的html5用户注册Demo。使用到Handlebars模板技术和手机验证码校验。
以下是效果截图:
1.页面代码:usersRegister.hbs
<!DOCTYPE html>
<!--[if IE 8 ]> <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9 ]> <html lang="en" class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html lang="en">
<!--<![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>用户注册</title>
<!--[if lt IE 9]>
<script src="/assets/scripts/html5shiv.js"></script>
<![endif]-->
<link href="/assets/styles/jquery.idealforms.min.css" rel="stylesheet" media="screen" />
<style type="text/css">
body
font: normal 15px/1.5 Arial, Helvetica, Free Sans, sans-serif;
color: #222;
overflow-y: scroll;
padding: 60px 0 0 0;
.main
width: 560px;
height: 480px;
margin: -50px auto;
#my-form
width: 560px;
height: 450px;
margin: 0 auto;
border: 1px solid #ccc;
padding: 3em;
border-radius: 3px;
box-shadow: 0 0 2px rgba(0, 0, 0, .2);
</style>
<script type="text/javascript" src="/assets/scripts/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="/assets/scripts/jquery.idealforms.js"></script>
</head>
<body>
<!-- style="background-image: url(static/image/bg.jpg) -->
<div class="main" >
<div style="height:5px;text-align:center;font-size:25px"> 欢迎您注册!</div>
<!-- Begin Form -->
<form id="my-form" class="myform">
<div>
<label>用户名:</label><input id="username" name="username" type="text" />
</div>
<div>
<!-- <label>密码:</label><input id="pass" name="password" type="password" /> -->
<label>密码:</label><input id="pass" name="password" type="text" />
</div>
<div>
<label>邮箱:</label><input id="email" name="email"
data-ideal="required email" type="email" />
</div>
<div>
<label>电话:</label><input id="telephone" type="text" name="phone" data-ideal="phone" />
</div>
<div>
<label>供应商V码:</label><input id="vCode" type="text" name="vCode" data-ideal="vCode" />
</div>
<div>
<label>真实姓名:</label><input id="trueName" type="text" name="trueName" data-ideal="trueName" />
</div>
<div>
<label>手机验证码:</label><input id="telCode" type="text" name="telCode" data-ideal="telCode" />
</div>
<div style="margin-bottom:5px;">
<button id="getTelCode" type="button" style="margin-left:160px; margin-right:auto;" >获取手机校验码</button>
<hr style="margin-top:5px; margin-bottom:5px;" />
</div>
<!--<div>
<label>性别:</label>
<select id="sex" name="sex">
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
<div>
<label>昵称:</label><input id="nickName" type="text" name="nickName" data-ideal="nickName" />
</div>
<div>
<label>年龄:</label><input id="age" type="text" name="age" data-ideal="age" />
</div>-->
<!-- <div>
<label>地址:</label><input type="text" name="address" data-ideal="address" />
</div>
<div>
<label>QQ:</label><input type="text" name="qq" data-ideal="qq" />
</div>
<div>
<label>邮编:</label><input type="text" name="zip" data-ideal="zip" />
</div>
<div>
<label>传真:</label><input type="text" name="fax" data-ideal="fax" />
</div>
<div>
<label>身份证:</label><input type="text" name="creditID" data-ideal="creditID" />
</div>
<div>
<label>出生日期:</label><input name="date" class="datepicker"
data-ideal="date" type="text" placeholder="月/日/年" />
</div>
<div>
<label>上传头像:</label><input id="file" name="file" multiple
type="file" />
</div>
<div>
<label>个人主页:</label><input name="website" data-ideal="url"
type="text" />
</div>
<div>
<label>备注:</label>
<textarea id="comments" name="comments"></textarea>
</div>
-->
<!-- <div id="languages">
<label>语言:</label> <label><input type="checkbox"
name="langs[]" value="English" />英文</label> <label><input
type="checkbox" name="langs[]" value="Chinese" />中文</label> <label><input
type="checkbox" name="langs[]" value="Spanish" />西班牙文</label> <label><input
type="checkbox" name="langs[]" value="French" />法文</label>
</div>
<div>
<label>精通几门:</label> <label><input type="radio"
name="radio" checked />1</label> <label><input type="radio"
name="radio" />2</label> <label><input type="radio" name="radio" />3</label>
<label><input type="radio" name="radio" />4</label>
</div>
<div>
<label>国籍:</label> <select id="states" name="states">
<option value="default">– 选择国籍 –</option>
<option value="AL">阿拉伯</option>
<option value="AK">中国</option>
<option value="AZ">美国</option>
<option value="AR">法国</option>
<option value="CA">英国</option>
<option value="CO">德国</option>
<option value="CT">西班牙</option>
<option value="DE">俄罗斯</option>
</select>
</div> -->
<div style="margin-top:10px; margin-left:100px;margin-right:100px;">
<button type="button" id="submit" class="submit">提交</button>
<button id="reset" type="button" >重置</button>
</div>
</form>
<!-- End Form -->
</div>
<script type="text/javascript">
var options =
onFail : function()
alert($myform.getInvalid().length + ' invalid fields.')
,
inputs :
'password' :
filters : 'required pass'
,
'username' :
filters : 'required username'
,
'email' :
filters : 'required email'
,
'phone' :
filters : 'required phone'
,
'trueName' :
filters : 'required'
,
'vCode' :
filters : 'required'
,
'telCode' :
filters : 'required'
/*
'age' :
filters : 'required digits',
data :
min : 16,
max : 70
,
'file' :
filters : 'extension',
data :
extension : [ 'jpg' ]
,
'comments' :
filters : 'min max',
data :
min : 50,
max : 200
,
'states' :
filters : 'exclude',
data :
exclude : [ 'default' ]
,
errors :
exclude : '选择国籍.'
,
'langs[]' :
filters : 'min max',
data :
min : 2,
max : 3
,
errors :
min : 'Check at least <strong>2</strong> options.',
max : 'No more than <strong>3</strong> options allowed.'
*/
;
$('#getTelCode').click(function()
var telephone = document.getElementById("telephone").value; //手机号码
if (telephone == null || telephone == "")
alert("手机号码不能为空!");
else
$.ajax(
type : "GET",
dataType : "json",
url : "../api/getTelCode?telephone="+ telephone,
success : function(msg)
,
error : function(e)
alert("获取手机校验码失败!" + e);
);
);
var $myform = $('#my-form').idealforms(options).data('idealforms');
$('#submit').click(function()
var username = document.getElementById("username").value; //用户名
var password = document.getElementById("pass").value; //密码
var email = document.getElementById("email").value; //邮箱
var telephone = document.getElementById("telephone").value; //手机号码
var vCode = document.getElementById("vCode").value; //公司V码
var telCode = document.getElementById("telCode").value; //手机校验码
var trueName = document.getElementById("trueName").value; //真实姓名
$.ajax(
type : "GET",
url : "../api/usersRegister?username="+ username +"&password="+ password +"&email="+ email +"&telephone="+ telephone +"&vCode="+ vCode +"&telCode="+ telCode +"&trueName="+ trueName,
success : function(msg)
//获取当前网址,如: http://localhost:8083/uimcardprj/share/meun.jsp
var curWwwPath = window.document.location.href;
//获取主机地址之后的目录,如: uimcardprj/share/meun.jsp
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
//获取主机地址,如: http://localhost:8083
var localhostPaht = curWwwPath.substring(0, pos);
//获取带"/"的项目名,如:/uimcardprj
var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
window.location.href = projectName + "/login";
alert("注册成功!");
,
error : function(e)
alert("注册失败!" + e);
);
);
$('#reset').click(function()
$myform.reset().fresh().focusFirst();
);
</script>
</body>
</html>
2.jq输入校验:jquery.idealforms.js
该js校验初始版本来自Cedric Ruiz,我略有修改。
部分校验的规则如下:
required: '此处是必填的.', number: '必须是数字.', digits: '必须是唯一的数字.', name: '必须至少有3个字符长,并且只能包含字母.', username: '用户名最短5位,最长30位,请使用英文字母、数字、中文和下划线. 用户名首字符必须为字母、数字、中文,不能为全数字.中文最长21个字.', pass: '密码的位数必须的在6-15位之间,并且至少包含一个数字,一个大写字母和一个小写字母.', strongpass: '必须至少为8个字符长,至少包含一个大写字母和一个小写字母和一个数字或特殊字符.', email: '必须是一个有效的email地址. <em>(例: user@gmail.com)</em>', phone: '必须是一个有效的手机号码. <em>(例: 18723101212)</em>'以下是整个代码文件:
/*--------------------------------------------------------------------------
jq-idealforms 2.1
* Author: Cedric Ruiz
* License: GPL or MIT
* Demo: http://elclanrs.github.com/jq-idealforms/
*
--------------------------------------------------------------------------*/
;(function ( $, window, document, undefined )
'use strict';
// Global Ideal Forms namespace
$.idealforms =
$.idealforms.filters =
$.idealforms.errors =
$.idealforms.flags =
$.idealforms.ajaxRequests =
/*--------------------------------------------------------------------------*/
/**
* @namespace A chest for various Utils
*/
var Utils =
/**
* Get width of widest element in the collection.
* @memberOf Utils
* @param jQuery object $elms
* @returns number
*/
getMaxWidth: function( $elms )
var maxWidth = 0
$elms.each(function()
var width = $(this).outerWidth()
if ( width > maxWidth )
maxWidth = width
)
return maxWidth
,
/**
* Hacky way of getting LESS variables
* @memberOf Utils
* @param string name The name of the LESS class.
* @param string prop The css property where the data is stored.
* @returns number, string
*/
getLessVar: function( name, prop )
var value = $('<p class="' + name + '"></p>').hide().appendTo('body').css( prop )
$('.' + name).remove()
return ( /^\\d+/.test( value ) ? parseInt( value, 10 ) : value )
,
/**
* Like ES5 Object.keys
*/
getKeys: function( obj )
var keys = []
for(var key in obj)
if ( obj.hasOwnProperty( key ) )
keys.push( key )
return keys
,
// Get lenght of an object
getObjSize: function( obj )
var size = 0, key;
for ( key in obj )
if ( obj.hasOwnProperty( key ) )
size++;
return size;
,
isFunction: function( obj )
return typeof obj === 'function'
,
isRegex: function( obj )
return obj instanceof RegExp
,
isString: function( obj )
return typeof obj === 'string'
,
getByNameOrId: function( str )
var $el = $('[name="'+ str +'"]').length
? $('[name="'+ str +'"]') // by name
: $('#'+ str) // by id
return $el.length
? $el
: $.error('The field "'+ str + '" doesn\\'t exist.')
,
getFieldsFromArray: function( fields )
var f = []
for ( var i = 0, l = fields.length; i < l; i++ )
f.push( Utils.getByNameOrId( fields[i] ).get(0) )
return $( f )
,
convertToArray: function( obj )
return Object.prototype.toString.call( obj ) === '[object Array]'
? obj : [ obj ]
,
/**
* Determine type of any Ideal Forms element
* @param $input jQuery $input object
*/
getIdealType: function( $el )
var type = $el.attr('type') || $el[0].tagName.toLowerCase()
return (
/(text|password|email|number|search|url|tel|textarea)/.test( type ) && 'text' ||
/file/.test( type ) && 'file' ||
/select/.test( type ) && 'select' ||
/(radio|checkbox)/.test( type ) && 'radiocheck' ||
/(button|submit|reset)/.test( type ) && 'button' ||
/h\\d/.test( type ) && 'heading' ||
/hr/.test( type ) && 'separator' ||
/hidden/.test( type ) && 'hidden'
)
,
/**
* Generates an input
* @param name `name` attribute of the input
* @param type `type` or `tagName` of the input
*/
makeInput: function( name, value, type, list, placeholder )
var markup, items = [], item, i, len
function splitValue( str )
var item, value, arr
if ( /::/.test( str ) )
arr = str.split('::')
item = arr[ 0 ]
value = arr[ 1 ]
else
item = value = str
return item: item, value: value
// Text & file
if ( /^(text|password|email|number|search|url|tel|file|hidden)$/.test(type) )
markup = '<input '+
'type="'+ type +'" '+
'id="'+ name +'" '+
'name="'+ name +'" '+
'value="'+ value +'" '+
(placeholder && 'placeholder="'+ placeholder +'"') +
'/>'
// Textarea
if ( /textarea/.test( type ) )
markup = '<textarea id="'+ name +'" name="'+ name +'" value="'+ value +'"></textarea>'
// Select
if ( /select/.test( type ) )
items = []
for ( i = 0, len = list.length; i < len; i++ )
item = splitValue( list[ i ] ).item
value = splitValue( list[ i ] ).value
items.push('<option value="'+ value +'">'+ item +'</option>')
markup =
'<select id="'+ name +'" name="'+ name +'">'+
items.join('') +
'</select>'
// Radiocheck
if ( /(radio|checkbox)/.test( type ) )
items = []
for ( i = 0, len = list.length; i < len; i++ )
item = splitValue( list[ i ] ).item
value = splitValue( list[ i ] ).value
items.push(
'<label>'+
'<input type="'+ type +'" name="'+ name +'" value="'+ value +'" />'+
item +
'</label>'
)
markup = items.join('')
return markup
/**
* Custom tabs for Ideal Forms
*/
$.fn.idealTabs = function (container)
var
// Elements
$contents = this,
$container = container,
$wrapper = $('<ul class="ideal-tabs-wrap"/>'),
$tabs = (function ()
var tabs = []
$contents.each(function ()
var name = $(this).attr('name')
var html =
'<li class="ideal-tabs-tab">'+
'<span>' + name + '</span>'+
'<i class="ideal-tabs-tab-counter ideal-tabs-tab-counter-zero">0</i>'+
'</li>'
tabs.push(html)
)
return $(tabs.join(''))
()),
Actions =
getCurIdx: function ()
return $tabs
.filter('.ideal-tabs-tab-active')
.index()
,
getTabIdxByName: function (name)
var re = new RegExp(name, 'i')
var $tab = $tabs.filter(function ()
return re.test($(this).text())
)
return $tab.index()
,
/**
* Public methods
*/
Methods =
/**
* Switch tab
*/
switchTab: function (nameOrIdx)
var idx = Utils.isString(nameOrIdx)
? Actions.getTabIdxByName(nameOrIdx)
: nameOrIdx
$tabs.removeClass('ideal-tabs-tab-active')
$tabs.eq(idx).addClass('ideal-tabs-tab-active')
$contents.hide().eq(idx).show()
,
nextTab: function ()
var idx = Actions.getCurIdx() + 1
idx > $tabs.length - 1
? Methods.firstTab()
: Methods.switchTab(idx)
,
prevTab: function ()
Methods.switchTab(Actions.getCurIdx() - 1)
,
firstTab: function ()
Methods.switchTab(0)
,
lastTab: function ()
Methods.switchTab($tabs.length - 1)
,
updateCounter: function (nameOrIdx, text)
var idx = !isNaN(nameOrIdx) ? nameOrIdx : Actions.getTabIdxByName(name),
$counter = $tabs.eq(idx).find('.ideal-tabs-tab-counter')
$counter.removeClass('ideal-tabs-tab-counter-zero')
if (!text)
$counter.addClass('ideal-tabs-tab-counter-zero')
$counter.html(text)
// Attach methods
for (var m in Methods)
$contents[m] = Methods[m]
// Init
$tabs.first()
.addClass('ideal-tabs-tab-active')
.end()
.click(function ()
var name = $(this).text()
$contents.switchTab(name)
)
// Insert in DOM & Events
$wrapper.append($tabs).appendTo($container)
$contents.addClass('ideal-tabs-content')
$contents.each(function ()
var $this = $(this), name = $(this).attr('name')
$this.data('ideal-tabs-content-name', name)
.removeAttr('name')
)
$contents.hide().first().show() // Start fresh
return $contents
/**
* A custom <select> menu jQuery plugin
* @example `$('select').idealSelect()`
*/
$.fn.idealSelect = function ()
return this.each(function ()
var
$select = $(this),
$options = $select.find('option')
/**
* Generate markup and return elements of custom select
* @memberOf $.fn.toCustomSelect
* @returns object All elements of the new select replacement
*/
var idealSelect = (function ()
var
$wrap = $('<ul class="ideal-select '+ $select.attr('name') +'"/>'),
$menu = $(
'<li><span class="ideal-select-title">' +
$options.filter(':selected').text() +
'</span></li>'
),
items = (function ()
var items = []
$options.each(function ()
var $this = $(this)
items.push('<li class="ideal-select-item">' + $this.text() + '</li>')
)
return items
())
$menu.append('<ul class="ideal-select-sub">' + items.join('') + '</ul>')
$wrap.append($menu)
return
select: $wrap,
title: $menu.find('.ideal-select-title'),
sub: $menu.find('.ideal-select-sub'),
items: $menu.find('.ideal-select-item')
())
/**
* @namespace Methods of custom select
* @memberOf $.fn.toCustomSelect
*/
var Actions =
getSelectedIdx: function ()
return idealSelect.items
.filter('.ideal-select-item-selected').index()
,
/**
* @private
*/
init: (function ()
$select.css(
position: 'absolute',
left: '-9999px'
)
idealSelect.sub.hide()
idealSelect.select.insertAfter($select)
idealSelect.select.css(
'min-width',
Utils.getMaxWidth(idealSelect.items)
)
idealSelect.items
.eq($options.filter(':selected').index())
.addClass('ideal-select-item-selected')
()),
noWindowScroll: function (e)
if (e.which === 40 || e.which === 38 || e.which === 13)
e.preventDefault()
,
// Fix loosing focus when scrolling
// and selecting item with keyboard
focusHack: function ()
setTimeout(function ()
$select.trigger('focus')
, 1)
,
focus: function ()
idealSelect.select.addClass('ideal-select-focus')
$(document).on('keydown.noscroll', Actions.noWindowScroll)
,
blur: function ()
idealSelect.select
.removeClass('ideal-select-open ideal-select-focus')
$(document).off('.noscroll')
,
scrollIntoView: function (dir)
var
$selected = idealSelect.items.filter('.ideal-select-item-selected'),
itemHeight = idealSelect.items.outerHeight(),
menuHeight = idealSelect.sub.outerHeight(),
isInView = (function ()
// relative position to the submenu
var elPos = $selected.position().top + itemHeight
return dir === 'down'
? elPos <= menuHeight
: elPos > 0
())
if (!isInView)
itemHeight = (dir === 'down')
? itemHeight // go down
: -itemHeight // go up
idealSelect.sub
.scrollTop(idealSelect.sub.scrollTop() + itemHeight)
,
scrollToItem: function ()
var idx = Actions.getSelectedIdx(),
height = idealSelect.items.outerHeight(),
nItems = idealSelect.items.length,
allHeight = height * nItems,
curHeight = height * (nItems - idx)
idealSelect.sub.scrollTop(allHeight - curHeight)
,
showMenu: function ()
idealSelect.sub.fadeIn('fast')
idealSelect.select.addClass('ideal-select-open')
Actions.select(Actions.getSelectedIdx())
Actions.scrollToItem()
,
hideMenu: function ()
idealSelect.sub.hide()
idealSelect.select.removeClass('ideal-select-open')
,
select: function (idx)
idealSelect.items
.removeClass('ideal-select-item-selected')
idealSelect.items
.eq(idx).addClass('ideal-select-item-selected')
,
change: function (idx)
var text = idealSelect.items.eq(idx).text()
Actions.select(idx)
idealSelect.title.text(text)
$options.eq(idx).prop('selected', true)
$select.trigger('change')
,
keydown: function (key)
var
idx = Actions.getSelectedIdx(),
isMenu = idealSelect.select.is('.ideal-select-menu'),
isOpen = idealSelect.select.is('.ideal-select-open')
/**
* @namespace Key pressed
*/
var keys =
9: function () // TAB
if (isMenu)
Actions.blur()
Actions.hideMenu()
,
13: function () // ENTER
if (isMenu)
isOpen
? Actions.hideMenu()
: Actions.showMenu()
Actions.change(idx)
,
27: function () // ESC
if (isMenu) Actions.hideMenu()
,
40: function () // DOWN
if (idx < $options.length - 1)
isOpen
? Actions.select(idx + 1)
: Actions.change(idx + 1)
Actions.scrollIntoView('down')
,
38: function () // UP
if (idx > 0)
isOpen
? Actions.select(idx - 1)
: Actions.change(idx - 1)
Actions.scrollIntoView('up')
,
'default': function () // Letter
var
letter = String.fromCharCode(key),
$matches = idealSelect.items
.filter(function ()
return /^\\w+$/i.test( letter ) && // not allow modifier keys ( ctrl, cmd, meta, super... )
new RegExp('^' + letter, 'i').test( $(this).text() ) // find first match
),
nMatches = $matches.length,
counter = idealSelect.select.data('counter') + 1 || 0,
curKey = idealSelect.select.data('key') || key,
newIdx = $matches.eq(counter).index()
if (!nMatches) // No matches
return false
// If more matches with same letter
if (curKey === key)
if (counter < nMatches)
idealSelect.select.data('counter', counter)
else
idealSelect.select.data('counter', 0)
newIdx = $matches.eq(0).index()
// If new letter
else
idealSelect.select.data('counter', 0)
newIdx = $matches.eq(0).index()
if (isOpen)
Actions.select(newIdx)
else
Actions.change(newIdx)
idealSelect.select.data('key', key)
Actions.scrollToItem()
Actions.focusHack()
keys[key]
? keys[key]()
: keys['default']()
/**
* @namespace Holds all events of custom select for "menu mode" and "list mode"
* @memberOf $.fn.toCustomSelect
*/
var events =
focus: Actions.focus,
'blur.menu': function ()
Actions.blur()
Actions.hideMenu()
,
'blur.list': function ()
Actions.blur()
,
keydown: function (e)
Actions.keydown(e.which)
,
'clickItem.menu': function ()
Actions.change($(this).index())
Actions.hideMenu()
,
'clickItem.list': function ()
Actions.change($(this).index())
,
'clickTitle.menu': function ()
Actions.focus()
Actions.showMenu()
$select.trigger('focus')
,
'hideOutside.menu': function ()
$select.off('blur.menu')
$(document).on('mousedown.ideal', function (evt)
if (!$(evt.target).closest(idealSelect.select).length)
$(document).off('mousedown.ideal')
$select.on('blur.menu', events['blur.menu'])
else
Actions.focusHack()
)
,
'mousedown.list': function ()
Actions.focusHack()
// Reset events
var disableEvents = function ()
idealSelect.select.removeClass('ideal-select-menu ideal-select-list')
$select.off('.menu .list')
idealSelect.items.off('.menu .list')
idealSelect.select.off('.menu .list')
idealSelect.title.off('.menu .list')
// Menu mode
idealSelect.select.on('menu', function ()
disableEvents()
idealSelect.select.addClass('ideal-select-menu')
Actions.hideMenu()
$select.on(
'blur.menu': events['blur.menu'],
'focus.menu': events.focus,
'keydown.menu': events.keydown
)
idealSelect.select.on('mousedown.menu', events['hideOutside.menu'])
idealSelect.items.on('click.menu', events['clickItem.menu'])
idealSelect.title.on('click.menu', events['clickTitle.menu'])
)
// List mode
idealSelect.select.on('list', function ()
disableEvents()
idealSelect.select.addClass('ideal-select-list')
Actions.showMenu()
$select.on(
'blur.list': events['blur.list'],
'focus.list': events.focus,
'keydown.list': events.keydown
)
idealSelect.select.on('mousedown.list', events['mousedown.list'])
idealSelect.items.on('mousedown.list', events['clickItem.list'])
)
$select.keydown(function (e)
// Prevent default keydown event
// to avoid bugs with Ideal Select events
if (e.which !== 9) e.preventDefault()
)
// Reset
idealSelect.select.on('reset', function()
Actions.change(0)
)
idealSelect.select.trigger('menu') // Default to "menu mode"
)
/*
* idealRadioCheck: jQuery plguin for checkbox and radio replacement
* Usage: $('input[type=checkbox], input[type=radio]').idealRadioCheck()
*/
$.fn.idealRadioCheck = function()
return this.each(function()
var $this = $(this)
var $span = $('<span/>')
$span.addClass( 'ideal-'+ ( $this.is(':checkbox') ? 'check' : 'radio' ) )
$this.is(':checked') && $span.addClass('checked') // init
$span.insertAfter( $this )
$this.parent('label').addClass('ideal-radiocheck-label')
.attr('onclick', '') // Fix clicking label in ios
$this.css( position: 'absolute', left: '-9999px' ) // hide by shifting left
// Events
$this.on(
change: function()
var $this = $(this)
if ( $this.is('input[type="radio"]') )
$this.parent().siblings('label').find('.ideal-radio').removeClass('checked')
$span.toggleClass( 'checked', $this.is(':checked') )
,
focus: function() $span.addClass('focus') ,
blur: function() $span.removeClass('focus') ,
click: function() $(this).trigger('focus')
)
)
;(function( $ )
// Browser supports HTML5 multiple file?
var multipleSupport = typeof $('<input/>')[0].multiple !== 'undefined',
isIE = /msie/i.test( navigator.userAgent )
$.fn.idealFile = function()
return this.each(function()
var $file = $(this).addClass('ideal-file'), // the original file input
// label that will be used for IE hack
$wrap = $('<div class="ideal-file-wrap">'),
$input = $('<input type="text" class="ideal-file-filename" />'),
// Button that will be used in non-IE browsers
$button = $('<button type="button" class="ideal-file-upload">Open</button>'),
// Hack for IE
$label = $('<label class="ideal-file-upload" for="'+ $file[0].id +'">Open</label>')
// Hide by shifting to the left so we
// can still trigger events
$file.css(
position: 'absolute',
left: '-9999px'
)
$wrap.append( $input, ( isIE ? $label : $button ) ).insertAfter( $file )
// Prevent focus
$file.attr('tabIndex', -1)
$button.attr('tabIndex', -1)
$button.click(function ()
$file.focus().click() // Open dialog
)
$file.change(function()
var files = [], fileArr, filename
// If multiple is supported then extract
// all filenames from the file array
if ( multipleSupport )
fileArr = $file[0].files
for ( var i = 0, len = fileArr.length; i < len; i++ )
files.push( fileArr[i].name )
filename = files.join(', ')
// If not supported then just take the value
// and remove the path to just show the filename
else
filename = $file.val().split('\\\\').pop()
$input.val( filename ) // Set the value
.attr( 'title', filename ) // Show filename in title tootlip
)
$input.on(
focus: function () $file.trigger('change') ,
blur: function () $file.trigger('blur') ,
keydown: function( e )
if ( e.which === 13 ) // Enter
if ( !isIE ) $file.trigger('click')
else if ( e.which === 8 || e.which === 46 ) // Backspace & Del
// On some browsers the value is read-only
// with this trick we remove the old input and add
// a clean clone with all the original events attached
$file.replaceWith( $file = $file.val('').clone( true ) )
$file.trigger('change')
$input.val('')
else if ( e.which === 9 ) // TAB
return
else // All other keys
return false
)
)
( jQuery ))
/**
* @namespace Errors
* @locale en
*/
$.idealforms.errors =
required: '此处是必填的.',
number: '必须是数字.',
digits: '必须是唯一的数字.',
name: '必须至少有3个字符长,并且只能包含字母.',
username: '用户名最短5位,最长30位,请使用英文字母、数字、中文和下划线.用户名首字符必须为字母、数字、中文,不能为全数字.中文最长21个字.',
pass: '密码的位数必须的在6-15位之间,并且至少包含一个数字,一个大写字母和一个小写字母.',
strongpass: '必须至少为8个字符长,至少包含一个大写字母和一个小写字母和一个数字或特殊字符.',
email: '必须是一个有效的email地址. <em>(例: user@gmail.com)</em>',
phone: '必须是一个有效的手机号码. <em>(例: 18723101212)</em>',
zip: 'Must be a valid US zip code. <em>(e.g. 33245 or 33245-0003)</em>',
url: 'Must be a valid URL. <em>(e.g. www.google.com)</em>',
minChar: 'Must be at least <strong>0</strong> characters long.',
minOption: 'Check at least <strong>0</strong> options.',
maxChar: 'No more than <strong>0</strong> characters long.',
maxOption: 'No more than <strong>0</strong> options allowed.',
range: 'Must be a number between 0 and 1.',
date: 'Must be a valid date. <em>(e.g. 0)</em>',
dob: 'Must be a valid date of birth.',
exclude: '"0" is not available.',
excludeOption: '0',
equalto: 'Must be the same value as <strong>"0"</strong>',
extension: 'File(s) must have a valid extension. <em>(e.g. "0")</em>',
ajaxSuccess: '<strong>0</strong> is not available.',
ajaxError: 'Server error...'
/**
* Get all default filters
* @returns object
*/
var getFilters = function()
var filters =
required:
regex: /.+/,
error: $.idealforms.errors.required
,
number:
regex: function( i, v ) return !isNaN(v) ,
error: $.idealforms.errors.number
,
digits:
regex: /^\\d+$/,
error: $.idealforms.errors.digits
,
name:
regex: /^[A-Za-z]3,$/,
error: $.idealforms.errors.name
,
username:
regex: /^[a-z](?=[\\w.]4,30$)\\w*\\.?\\w*$/i,
error: $.idealforms.errors.username
,
pass:
regex: /(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).6,/,
error: $.idealforms.errors.pass
,
strongpass:
regex: /(?=^.8,$)((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$/,
error: $.idealforms.errors.strongpass
,
email:
regex: /^([a-zA-Z0-9]*[-_.]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\\\.][A-Za-z]2,3([\\\\.][A-Za-z]2)?$/,
error: $.idealforms.errors.email
,
phone:
//regex: /^((13[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\\\d8$/,
regex: /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]8$/,
error: $.idealforms.errors.phone
,
zip:
regex: /^\\d5$|^\\d5-\\d4$/,
error: $.idealforms.errors.zip
,
url:
regex: /^(?:(ftp|http|https):\\/\\/)?(?:[\\w\\-]+\\.)+[a-z]2,6([\\:\\/?#].*)?$/i,
error: $.idealforms.errors.url
,
min:
regex: function( input, value )
var $input = input.input,
min = input.userOptions.data.min,
isRadioCheck = $input.is('[type="checkbox"], [type="radio"]')
if ( isRadioCheck )
this.error = $.idealforms.errors.minOption.replace( '0', min )
return $input.filter(':checked').length >= min
this.error = $.idealforms.errors.minChar.replace( '0', min )
return value.length >= min
,
max:
regex: function( input, value )
var $input = input.input,
max = input.userOptions.data.max,
isRadioCheck = $input.is('[type="checkbox"], [type="radio"]')
if ( isRadioCheck )
this.error = $.idealforms.errors.maxOption.replace( '0', max )
return $input.filter(':checked').length <= max
this.error = $.idealforms.errors.maxChar.replace( '0', max )
return value.length <= max
,
range:
regex: function( input, value )
var range = input.userOptions.data.range,
val = +value
this.error = $.idealforms.errors.range
.replace( '0', range[0] )
.replace( '1', range[1] )
return val >= range[0] && val <= range[1]
,
date:
regex: function( input, value )
var
userFormat =
input.userOptions.data && input.userOptions.data.date
? input.userOptions.data.date
: 'mm/dd/yyyy', // default format
delimiter = /[^mdy]/.exec( userFormat )[0],
theFormat = userFormat.split(delimiter),
theDate = value.split(delimiter),
isDate = function( date, format )
var m, d, y
for ( var i = 0, len = format.length; i < len; i++ )
if ( /m/.test( format[i]) ) m = date[i]
if ( /d/.test( format[i]) ) d = date[i]
if ( /y/.test( format[i]) ) y = date[i]
return (
m > 0 && m < 13 &&
y && y.length === 4 &&
d > 0 && d <= ( new Date( y, m, 0 ) ).getDate()
)
this.error = $.idealforms.errors.date.replace( '0', userFormat )
return isDate( theDate, theFormat )
,
dob:
regex: function( input, value )
var
userFormat =
input.userOptions.data && input.userOptions.data.dob
? input.userOptions.data.dob
: 'mm/dd/yyyy', // default format
// Simulate a date input
dateInput =
input: input.input,
userOptions:
data: date: userFormat
,
// Use internal date filter to validate the date
isDate = filters.date.regex( dateInput, value ),
// DOB
theYear = /\\d4/.exec( value ),
maxYear = new Date().getFullYear(), // Current year
minYear = maxYear - 100
this.error = $.idealforms.errors.dob
return isDate && theYear >= minYear && theYear <= maxYear
,
exclude:
regex: function( input, value )
var $input = input.input,
exclude = input.userOptions.data.exclude,
isOption = $input.is('[type="checkbox"], [type="radio"], select')
this.error = isOption
? $.idealforms.errors.excludeOption.replace( '0', value )
: this.error = $.idealforms.errors.exclude.replace( '0', value )
return $.inArray( value, exclude ) === -1
,
equalto:
regex: function( input, value )
var $equals = $( input.userOptions.data.equalto ),
$input = input.input,
name = $equals.attr('name') || $equals.attr('id'),
isValid = $equals.parents('.ideal-field')
.filter(function() return $(this).data('ideal-isvalid') === true )
.length
if ( !isValid ) return false
this.error = $.idealforms.errors.equalto.replace( '0', name )
return $input.val() === $equals.val()
,
extension:
regex: function( input, value )
var files = input.input[0].files || [ name: value ],
extensions = input.userOptions.data.extension,
re = new RegExp( '\\\\.'+ extensions.join('|') +'$', 'i' ),
valid = false
for ( var i = 0, len = files.length; i < len; i++ )
valid = re.test( files[i].name );
this.error = $.idealforms.errors.extension.replace( '0', extensions.join('", "') )
return valid
,
ajax:
regex: function( input, value, showOrHideError )
var self = this
var $input = input.input
var userOptions = input.userOptions
var name = $input.attr('name')
var $field = $input.parents('.ideal-field')
var valid = false
var customErrors = userOptions.errors && userOptions.errors.ajax
self.error =
self.error.success = customErrors && customErrors.success
? customErrors.success
: $.idealforms.errors.ajaxSuccess.replace( '0', value )
self.error.fail = customErrors && customErrors.error
? customErrors.error
: $.idealforms.errors.ajaxError
// Send input name as $_POST[name]
var data =
data[ name ] = $.trim( value )
// Ajax options defined by the user
var userAjaxOps = input.userOptions.data.ajax
var ajaxOps =
type: 'post',
dataType: 'json',
data: data,
success: function( resp, text, xhr )
console.log(resp)
showOrHideError( self.error.success, true )
$input.data(
'ideal-ajax-resp': resp,
'ideal-ajax-error': self.error.success
)
$input.trigger('change') // to update counter
$field.removeClass('ajax')
// Run custom success callback
if( userAjaxOps._success )
userAjaxOps._success( resp, text, xhr )
,
error: function( xhr, text, error )
if ( text !== 'abort' )
showOrHideError( self.error.fail, false )
$input.data( 'ideal-ajax-error', self.error.fail )
$field.removeClass('ajax')
// Run custom error callback
if ( userAjaxOps._error )
userAjaxOps._error( xhr, text, error )
$.extend( ajaxOps, userAjaxOps )
// Init
$input.removeData('ideal-ajax-error')
$input.removeData('ideal-ajax-resp')
$field.addClass('ajax')
// Run request and save it to be able to abort it
// so requests don't bubble
$.idealforms.ajaxRequests[ name ] = $.ajax( ajaxOps )
return filters
$.idealforms.flags =
noerror: function (i)
i.parent().siblings('.ideal-error').hide()
,
noicons: function (i)
i.siblings('.ideal-icon-valid, .ideal-icon-invalid').hide()
,
novalidicon: function (i)
i.siblings('.ideal-icon-valid').hide()
,
noinvalidicon: function (i)
i.siblings('.ideal-icon-invalid').hide()
,
noclass: function (i)
i.parents('.ideal-field').removeClass('valid invalid')
,
novalidclass: function (i)
i.parents('.ideal-field').removeClass('valid')
,
noinvalidclass: function (i)
i.parents('.ideal-field').removeClass('invalid')
/*
* Ideal Forms plugin
*/
var _defaults =
inputs: ,
customFilters: ,
customFlags: ,
globalFlags: '',
onSuccess: function(e) alert('Thank you...') ,
onFail: function() alert('Invalid!') ,
responsiveAt: 'auto',
disableCustom: ''
// Constructor
var IdealForms = function( element, options )
var self = this
self.$form = $( element )
self.opts = $.extend( , _defaults, options )
self.$tabs = self.$form.find('section')
// Set localized filters
$.extend( $.idealforms.filters, getFilters() )
self._init()
// Plugin
$.fn.idealforms = function( options )
return this.each(function()
if ( !$.data( this, 'idealforms' ) )
$.data( this, 'idealforms', new IdealForms( this, options ) )
)
// Get LESS variables
var LessVars =
fieldWidth: Utils.getLessVar( 'ideal-field-width', 'width' )
/*
* Private Methods
*/
$.extend( IdealForms.prototype,
_init: function()
var self = this
var o = self.opts
var formElements = self._getFormElements()
self.$form.css( 'visibility', 'visible' )
.addClass('ideal-form')
.attr( 'novalidate', 'novalidate' ) // disable HTML5 validation
// Do markup
formElements.inputs
.add( formElements.headings )
.add( formElements.separators )
.each(function() self._doMarkup( $(this) ) )
// Generate tabs
if ( self.$tabs.length )
var $tabContainer = $('<div class="ideal-wrap ideal-tabs ideal-full-width"/>')
self.$form.prepend( $tabContainer )
self.$tabs.idealTabs( $tabContainer )
// Always show datepicker below the input
if ( jQuery.ui )
$.datepicker._checkOffset = function( a,b,c ) return b
// Add inputs specified by data-ideal
// to the list of user inputs
self.$form.find('[data-ideal]').each(function()
var userInput = o.inputs[ this.name ]
o.inputs[ this.name ] = userInput || filters: $(this).data('ideal')
)
// Responsive
if ( o.responsiveAt )
$(window).resize(function() self._responsive() )
self._responsive()
// Form events
self.$form.on(
keydown: function( e )
// Prevent submit when pressing enter
// but exclude textareas
if ( e.which === 13 && e.target.nodeName !== 'TEXTAREA' )
e.preventDefault()
,
submit: function( e )
if ( !self.isValid() )
e.preventDefault()
o.onFail()
self.focusFirstInvalid()
else
o.onSuccess( e )
)
self._adjust()
self._attachEvents()
self.fresh() // Start fresh
,
_getFormElements: function()
return
inputs: this.$form.find('input, select, textarea, :button'),
labels: this.$form.find('div > label:first-child'),
text: this.$form.find('input:not([type="checkbox"], [type="radio"], [type="submit"]), textarea'),
select: this.$form.find('select'),
radiocheck: this.$form.find('input[type="radio"], input[type="checkbox"]'),
buttons: this.$form.find(':button'),
file: this.$form.find('input[type="file"]'),
headings: this.$form.find('h1, h2, h3, h4, h5, h6'),
separators: this.$form.find('hr'),
hidden: this.$form.find('input:hidden')
,
_getUserInputs: function()
return this.$form.find('[name="'+ Utils.getKeys( this.opts.inputs ).join('"], [name="') +'"]')
,
_getTab: function( nameOrIdx )
var self = this
var isNumber = !isNaN( nameOrIdx )
if ( isNumber )
return self.$tabs.eq( nameOrIdx )
return self.$tabs.filter(function()
var re = new RegExp( nameOrIdx, 'i' )
return re.test( $(this).data('ideal-tabs-content-name') )
)
,
_getCurrentTabIdx: function()
return this.$tabs.index( this.$form.find('.ideal-tabs-content:visible') )
,
_updateTabsCounter: function()
var self = this
self.$tabs.each(function( i )
var invalid = self.getInvalidInTab( i ).length
self.$tabs.updateCounter( i, invalid )
)
,
_adjust: function()
var self = this
var o = self.opts
var formElements = self._getFormElements()
var curTab = self._getCurrentTabIdx()
// Autocomplete causes some problems...
formElements.inputs.attr('autocomplete', 'off')
// Show tabs to calculate dimensions
if ( self.$tabs.length ) self.$tabs.show()
// Adjust labels
var labels = formElements.labels
labels.removeAttr('style').width( Utils.getMaxWidth( labels ) )
// Adjust headings and separators
if ( self.$tabs.length )
this.$tabs.each(function()
$( this ).find('.ideal-heading:first').addClass('first-child')
)
else
self.$form.find('.ideal-heading:first').addClass('first-child')
self._setDatepicker()
// Done calculating hide tabs
if ( self.$tabs.length )
self.$tabs.hide()
self.switchTab( curTab )
,
_setDatepicker: function()
var o = this.opts
var $datepicker = this.$form.find('input.datepicker')
if ( jQuery.ui && $datepicker.length )
$datepicker.each(function()
var userInput = o.inputs[ this.name ]
var data = userInput && userInput.data && userInput.data.date
var format = data ? data.replace( 'yyyy', 'yy' ) : 'mm/dd/yy'
$(this).datepicker(
dateFormat: format,
beforeShow: function( input )
$( input ).addClass('open')
,
onChangeMonthYear: function()
// Hack to fix IE9 not resizing
var $this = $(this)
var w = $this.outerWidth() // cache first!
setTimeout(function()
$this.datepicker('widget').css( 'width', w )
, 1)
,
onClose: function() $(this).removeClass('open')
)
)
// Adjust width
$datepicker.on('focus keyup', function()
var t = $(this), w = t.outerWidth()
t.datepicker('widget').css( 'width', w )
)
$datepicker.parent().siblings('.ideal-error').addClass('hidden')
,
_doMarkup: function( $element )
var o = this.opts
var elementType = Utils.getIdealType( $element )
// Validation elements
var $field = $('<span class="ideal-fiel以上是关于Html5用户注册自动校验的主要内容,如果未能解决你的问题,请参考以下文章