h5 php登录注册页面验证,Html5实现用户注册自动校验功能实例代码

/*--------------------------------------------------------------------------

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

*/

varUtils= {

/**

* Get width of widest element in the collection.

* @memberOf Utils

* @param {jQuery object} $elms

* @returns {number}

*/

getMaxWidth: function( $elms ) {

varmaxWidth=0

$elms.each(function() {

varwidth= $(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 ) {

varvalue= $('

').hide().appendTo('body').css( prop )

$('.' + name).remove()

return ( /^\d+/.test( value ) ? parseInt( value, 10 ) : value )

},

/**

* Like ES5 Object.keys

*/

getKeys: function( obj ) {

varkeys= []

for(var key in obj) {

if ( obj.hasOwnProperty( key ) ) {

keys.push( key )

}

}

return keys

},

// Get lenght of an object

getObjSize: function( obj ) {

varsize=0, key;

for ( key in obj ) {

if ( obj.hasOwnProperty( key ) ) {

size++;

}

}

return size;

},

isFunction: function( obj ) {

return typeofobj=== 'function'

},

isRegex: function( obj ) {

return obj instanceof RegExp

},

isString: function( obj ) {

return typeofobj=== '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 ) {

varf= []

for ( vari=0,l=fields.length; 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 ) {

vartype= $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='

'type="'+ type +'"'+

'id="'+ name +'"'+

'name="'+ name +'"'+

'value="'+ value +'"'+

(placeholder && 'placeholder="'+ placeholder +'"') +

'/>'

// Textarea

if ( /textarea/.test( type ) ) {

markup=''

}

// Select

if ( /select/.test( type ) ) {

items= []

for (i=0,len=list.length; i

item=splitValue( list[ i ] ).item

value=splitValue( list[ i ] ).value

items.push(''+ item +'')

}

markup=

''+

items.join('') +

''

}

// Radiocheck

if ( /(radio|checkbox)/.test( type ) ) {

items= []

for (i=0,len=list.length; i

item=splitValue( list[ i ] ).item

value=splitValue( list[ i ] ).value

items.push(

''+

''+

item +

''

)

}

markup=items.join('')

}

return markup

}

}

/**

* Custom tabs for Ideal Forms

*/

$.fn.idealTabs=function(container) {

var

// Elements

$contents=this,

$containercontainer= container,

$wrapper= $(''),

$tabs= (function () {

vartabs= []

$contents.each(function () {

varname= $(this).attr('name')

varhtml=

'

'+

'' + name + ''+

'0'+

''

tabs.push(html)

})

return $(tabs.join(''))

}()),

Actions= {

getCurIdx: function () {

return $tabs

.filter('.ideal-tabs-tab-active')

.index()

},

getTabIdxByName: function (name) {

varre=newRegExp(name, 'i')

var $tab= $tabs.filter(function () {

return re.test($(this).text())

})

return $tab.index()

}

},

/**

* Public methods

*/

Methods= {

/**

* Switch tab

*/

switchTab: function (nameOrIdx) {

varidx=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 () {

varidx=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) {

varidx= !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 () {

varname= $(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 custommenu 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

*/

varidealSelect= (function () {

var

$wrap= $(''),

$menu= $(

'

' +

$options.filter(':selected').text() +

''

),

items= (function () {

varitems= []

$options.each(function () {

var $this= $(this)

items.push('' + $this.text() + '')

})

return items

}())

$menu.append('' + items.join('') + '')

$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

*/

varActions= {

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

varelPos= $selected.position().top + itemHeight

returndir=== '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 () {

varidx=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) {

vartext=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

*/

varkeys= {

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

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

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

*/

varevents= {

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

vardisableEvents=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.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?

varmultipleSupport=typeof$('')[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= $(''),

$input= $(''),

// Button that will be used in non-IE browsers

$button= $('Open'),

// Hack for IE

$label= $('Open')

// 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() {

varfiles= [], fileArr, filename

// If multiple is supported then extract

// all filenames from the file array

if ( multipleSupport ) {

fileArr= $file[0].files

for ( vari=0,len=fileArr.length; 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地址.(例: user@gmail.com)',

phone: '必须是一个有效的手机号码.(例: 18723101212)',

zip: 'Must be a valid US zip code.(e.g. 33245 or 33245-0003)',

url: 'Must be a valid URL.(e.g. www.google.com)',

minChar: 'Must be at least{0}characters long.',

minOption: 'Check at least{0}options.',

maxChar: 'No more than{0}characters long.',

maxOption: 'No more than{0}options allowed.',

range: 'Must be a number between {0} and {1}.',

date: 'Must be a valid date.(e.g. {0})',

dob: 'Must be a valid date of birth.',

exclude: '"{0}" is not available.',

excludeOption: '{0}',

equalto: 'Must be the same value as"{0}"',

extension: 'File(s) must have a valid extension.(e.g. "{0}")',

ajaxSuccess: '{0}is not available.',

ajaxError: 'Server error...'

}

/**

* Get all default filters

* @returns object

*/

vargetFilters=function() {

varfilters= {

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]))\\d{8}$/,

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: /^\d{5}$|^\d{5}-\d{4}$/,

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 $inputinput= 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 $inputinput= 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 ) {

varrange=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 ( vari=0,len=format.length; 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= /\d{4}/.exec( value ),

maxYear=newDate().getFullYear(), // Current year

minYear=maxYear- 100

this.error= $.idealforms.errors.dob

return isDate && theYear>= minYear && theYear<= maxYear

}

},

exclude: {

regex: function( input, value ) {

var $inputinput= 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 ),

$inputinput= 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 ) {

varfiles=input.input[0].files || [{ name: value }],

extensions=input.userOptions.data.extension,

re=newRegExp( '\\.'+ extensions.join('|') +'$', 'i' ),

valid=false

for ( vari=0,len=files.length; i

valid=re.test( files[i].name );

}

this.error= $.idealforms.errors.extension.replace( '{0}', extensions.join('", "') )

return valid

}

},

ajax: {

regex: function( input, value, showOrHideError ) {

varself=this

var $inputinput= input.input

varuserOptions=input.userOptions

varname= $input.attr('name')

var $field= $input.parents('.ideal-field')

varvalid=false

varcustomErrors=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]

vardata= {}

data[ name ] = $.trim( value )

// Ajax options defined by the user

varuserAjaxOps=input.userOptions.data.ajax

varajaxOps= {

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

varIdealForms=function( element, options ) {

varself=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

varLessVars= {

fieldWidth: Utils.getLessVar( 'ideal-field-width', 'width' )

}

/*

* Private Methods

*/

$.extend( IdealForms.prototype, {

_init: function() {

varself=this

varo=self.opts

varformElements=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= $('')

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() {

varuserInput=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 ) {

varself=this

varisNumber= !isNaN( nameOrIdx )

if ( isNumber ) {

return self.$tabs.eq( nameOrIdx )

}

return self.$tabs.filter(function() {

varre=newRegExp( 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() {

varself=this

self.$tabs.each(function( i ) {

varinvalid=self.getInvalidInTab( i ).length

self.$tabs.updateCounter( i, invalid )

})

},

_adjust: function() {

varself=this

varo=self.opts

varformElements=self._getFormElements()

varcurTab=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

varlabels=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() {

varo=this.opts

var $datepicker=this.$form.find('input.datepicker')

if ( jQuery.ui && $datepicker.length ) {

$datepicker.each(function() {

varuserInput=o.inputs[ this.name ]

vardata=userInput&& userInput.data && userInput.data.date

varformat=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)

varw= $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() {

vart= $(this),w=t.outerWidth()

t.datepicker('widget').css( 'width', w )

})

$datepicker.parent().siblings('.ideal-error').addClass('hidden')

}

},

_doMarkup: function( $element ) {

varo=this.opts

varelementType=Utils.getIdealType( $element )

// Validation elements

var $field= $('')

var $error= $('')

var $valid= $('')

var $invalid= $('')

.click(function(){

$(this).parent().find('input:first, textarea, select').focus()

})

// Basic markup

$element.closest('div').addClass('ideal-wrap')

.children('label:first-child').addClass('ideal-label')

varidealElements= {

_defaultInput: function() {

$element.wrapAll( $field ).after( $valid, $invalid )

.parent().after( $error )

},

text: function() { idealElements._defaultInput() },

radiocheck: function() {

// Check if input is already wrapped so we don't

// wrap radios and checks more than once

varisWrapped= $element.parents('.ideal-field').length

if ( !isWrapped ) {

$element.parent().nextAll().andSelf().wrapAll( $field.addClass('ideal-radiocheck') )

$element.parents('.ideal-field').append( $valid, $invalid ).after( $error )

}

if ( !/radiocheck/.test( o.disableCustom ) ) {

$element.idealRadioCheck()

}

},

select: function() {

idealElements._defaultInput()

if ( !/select/.test( o.disableCustom ) ) {

$element.idealSelect()

}

},

file: function() {

idealElements._defaultInput()

if ( !/file/.test( o.disableCustom ) ) {

$element.idealFile()

}

},

button: function() {

if ( !/button/.test( o.disableCustom ) ) {

$element.addClass('ideal-button')

}

},

hidden: function() {

$element.closest('div').addClass('ideal-hidden')

},

heading: function() {

$element.closest('div').addClass('ideal-full-width')

$element.parent().children().wrapAll('')

},

separator: function() {

$element.closest('div').addClass('ideal-full-width')

$element.wrapAll('')

}

}

// Generate markup for current element type

idealElements[ elementType ] ? idealElements[ elementType ]() : $.noop()

$error.add( $valid ).add( $invalid ).hide() // Start fresh

},

/** Validates an input and shows or hides error and icon

* @memberOf Actions

* @param {object} $input jQuery object

* @param {string} e The JavaScript event

*/

_validate: function( $input, e ) {

varself=this

varo=this.opts

varuserOptions= o.inputs[ $input.attr('name') ]

varuserFilters=userOptions.filters && userOptions.filters.split(/\s/)

varname= $input.attr('name')

varvalue= $input.val()

varajaxRequest= $.idealforms.ajaxRequests[ name ]

varisRadioCheck= $input.is('[type="checkbox"], [type="radio"]')

varinputData= {

// If is radio or check validate all inputs related by name

input: isRadioCheck ? self.$form.find('[name="' + name + '"]') : $input,

userOptions: userOptions

}

// Validation elements

var $field= $input.parents('.ideal-field')

var $error= $field.siblings('.ideal-error')

var $invalid=isRadioCheck

? $input.parent().siblings('.ideal-icon-invalid')

: $input.siblings('.ideal-icon-invalid')

var $valid=isRadioCheck

? $input.parent().siblings('.ideal-icon-valid')

: $input.siblings('.ideal-icon-valid')

function resetError() {

$field.removeClass('valid invalid').removeData('ideal-isvalid')

$error.add( $invalid ).add( $valid ).hide()

}

function showOrHideError( error, valid ) {

resetError()

valid ? $valid.show() : $invalid.show()

$field.addClass( valid ? 'valid' : 'invalid' )

$field.data( 'ideal-isvalid', valid )

if ( !valid ) {

$error.html( error ).toggle( $field.is('.ideal-field-focus') )

}

}

// Prevent validation when typing but not introducing any new characters

// This is mainly to prevent multiple AJAX requests

varoldValue= $input.data('ideal-value') || 0

$input.data( 'ideal-value', value )

if (e.type=== 'keyup' &&value=== oldValue ) { return false }

// Validate

if ( userFilters ) {

$.each( userFilters, function( i, filter ) {

vartheFilter= $.idealforms.filters[ filter ]

varcustomError=userOptions.errors && userOptions.errors[ filter ]

varerror=''

// If field is empty and not required

if ( !value && filter !== 'required' ) {

resetError()

return false

}

if ( theFilter ) {

// Abort and reset ajax if there's a request pending

if (e.type=== 'keyup' && ajaxRequest ) {

ajaxRequest.abort()

$field.removeClass('ajax')

}

// AJAX

if (filter=== 'ajax' ) {

showOrHideError( error, false ) // set invalid till response comes back

$error.hide()

if (e.type=== 'keyup' ) {

theFilter.regex( inputData, value, showOrHideError ) // runs the ajax callback

} else {

varajaxError= $input.data('ideal-ajax-error')

if ( ajaxError ) {

showOrHideError( ajaxError, $input.data('ideal-ajax-resp') || false )

}

}

}

// All other filters

else {

varvalid=Utils.isRegex( theFilter.regex ) && theFilter.regex.test( value ) ||

Utils.isFunction( theFilter.regex ) && theFilter.regex( inputData, value )

error=customError|| theFilter.error // assign error after calling regex()

showOrHideError( error, valid )

if ( !valid ) { return false }

}

}

})

}

// Reset if there are no filters

else {

resetError()

}

// Flags

varflags= (function(){

varf=userOptions.flags && userOptions.flags.split(' ') || []

if ( o.globalFlags ) {

$.each( o.globalFlags.split(' '), function( i,v ) { f.push(v) })

}

return f

}())

if ( flags.length ) {

$.each(flags, function( i,f ) {

vartheFlag= $.idealforms.flags[f]

if ( theFlag ) { theFlag( $input, e.type ) }

})

}

// Update counter

if ( self.$tabs.length ) {

self._updateTabsCounter( self._getCurrentTabIdx() )

}

},

_attachEvents: function() {

varself=this

self._getUserInputs().on('keyup change focus blur', function(e) {

var $this= $(this)

var $field= $this.parents('.ideal-field')

varisFile= $this.is('input[type=file]')

// Trigger on change iftype=filecuz custom file

// disables focus on original file input (tabIndex= -1)

if (e.type=== 'focus' || isFile &&e.type=== 'change' ) {

$field.addClass('ideal-field-focus')

}

if (e.type=== 'blur' ) {

$field.removeClass('ideal-field-focus')

}

self._validate( $this, e )

})

},

_responsive: function() {

varformElements=this._getFormElements()

varmaxWidth=LessVars.fieldWidth + formElements.labels.outerWidth()

var $emptyLabel=formElements.labels.filter(function() {

return $(this).html() === ' '

})

var $customSelect=this.$form.find('.ideal-select')

this.opts.responsiveAt=== 'auto'

? this.$form.toggleClass( 'stack', this.$form.width()

: this.$form.toggleClass( 'stack', $(window).width()

varisStack=this.$form.is('.stack')

$emptyLabel.toggle( !isStack )

$customSelect.trigger( isStack ? 'list' : 'menu' )

// Hide datePicker

var $datePicker=this.$form.find('input.hasDatepicker')

if ( $datePicker.length ) { $datePicker.datepicker('hide') }

}

})

/*

* Public Methods

*/

$.extend( IdealForms.prototype, {

getInvalid: function() {

return this.$form.find('.ideal-field').filter(function() {

return $(this).data('ideal-isvalid') === false

})

},

getInvalidInTab: function( nameOrIdx ) {

return this._getTab( nameOrIdx ).find('.ideal-field').filter(function() {

return $(this).data('ideal-isvalid') === false

})

},

isValid: function() {

return !this.getInvalid().length

},

isValidField: function( field ) {

var $input=Utils.getByNameOrId( field )

return $input.parents('.ideal-field').data('ideal-isvalid') === true

},

focusFirst: function() {

if ( this.$tabs.length ) {

this.$tabs.filter(':visible')

.find('.ideal-field:first')

.find('input:first, select, textarea').focus()

} else {

this.$form.find('.ideal-field:first')

.find('input:first, select, textarea').focus()

}

return this

},

focusFirstInvalid: function() {

var $first=this.getInvalid().first().find('input:first, select, textarea')

vartabName= $first.parents('.ideal-tabs-content').data('ideal-tabs-content-name')

if ( this.$tabs.length ) {

this.switchTab( tabName )

}

$first.focus()

return this

},

switchTab: function( nameOrIdx ) {

this.$tabs.switchTab( nameOrIdx )

return this

},

nextTab: function() {

this.$tabs.nextTab()

return this

},

prevTab: function() {

this.$tabs.prevTab()

return this

},

firstTab: function() {

this.$tabs.firstTab()

return this

},

lastTab: function() {

this.$tabs.lastTab()

return this

},

fresh: function() {

this._getUserInputs().change().parents('.ideal-field')

.removeClass('valid invalid')

return this

},

freshFields: function( fields ) {

fields=Utils.convertToArray( fields )

$.each( fields, function( i ) {

var $input=Utils.getByNameOrId( fields[ i ] )

$input.change().parents('.ideal-field').removeClass('valid invalid')

})

return this

},

reload: function() {

this._adjust()

this._attachEvents()

return this

},

reset: function() {

varformElements=this._getFormElements()

formElements.text.val('') // text inputs

formElements.radiocheck.removeAttr('checked') // radio & check

// Select and custom select

formElements.select.find('option').first().prop( 'selected', true )

this.$form.find('.ideal-select').trigger('reset')

if ( this.$tabs.length ) { this.firstTab() }

this.focusFirst().fresh()

return this

},

resetFields: function( fields ) {

fields=Utils.convertToArray( fields )

varformElements=this._getFormElements()

$.each( fields, function( i, v ) {

var $input=Utils.getByNameOrId( v )

vartype=Utils.getIdealType( $input )

if (type=== 'text' ||type=== 'file' ) {

$input.val('')

}

if (type=== 'radiocheck' ) {

$input.removeAttr('checked') // radio & check

}

if (type=== 'select' ) {

$input.find('option').first().prop( 'selected', true )

$input.next('.ideal-select').trigger('reset')

}

$input.change()

})

this.freshFields( fields )

return this

},

toggleFields: function( fields ) {

fields=Utils.convertToArray( fields )

varself=this

var $fields=Utils.getFieldsFromArray( fields )

$fields.each(function() {

var $this= $(this)

varname= $this.attr('name') || $this.attr('id')

varinput=self.opts.inputs[ name ]

varfilters=input&& input.filters

vardataFilters= $this.data('ideal-filters') || ''

$this.data( 'ideal-filters', filters )

$this.closest('.ideal-wrap').toggle()

self.setFieldOptions( name, { filters: dataFilters } )

})

return this

},

setOptions: function( options ) {

$.extend( true, this.opts, options )

this.reload().fresh()

return this

},

setFieldOptions: function( name, options ) {

$.extend( true, this.opts.inputs[ name ], options )

this.reload().freshFields([ name ])

return this

},

addFields: function( fields ) {

fields=Utils.convertToArray( fields )

varself=this

// Save names of all inputs in Array

// to use methods that take names ie. fresh()

varallNames= []

// Add an input to the DOM

function add( ops ) {

varname=ops.name

varuserOptions= {

filters: ops.filters || '',

data: ops.data || {},

errors: ops.errors || {},

flags: ops.flags || ''

}

varlabel=ops.label || ''

vartype=ops.type

varlist=ops.list || []

varplaceholder=ops.placeholder || ''

varvalue=ops.value || ''

var $field= $('

'+

''+ label +':'+

Utils.makeInput( name, value, type, list, placeholder ) +

'

')

var $input= $field.find('input, select, textarea, :button')

// Add inputs with filters to the list

// of user inputs to validate

if ( userOptions.filters ) { self.opts.inputs[ name ] = userOptions }

self._doMarkup( $input )

// Insert in DOM

if ( ops.addAfter ) {

$field.insertAfter(

$( Utils.getByNameOrId( ops.addAfter ) ).parents('.ideal-wrap')

)

} else if ( ops.addBefore ) {

$field.insertBefore(

$(Utils.getByNameOrId( ops.addBefore ))

.parents('.ideal-wrap')

)

} else if ( ops.appendToTab ) {

$field.insertAfter(

self._getTab( ops.appendToTab ).find('.ideal-wrap:last-child')

)

} else {

$field.insertAfter( self.$form.find('.ideal-wrap').last() )

}

// Add current field name to list of names

allNames.push( name )

}

// Run through each input

$.each( fields, function( i, ops ) { add( ops ) })

self.reload()

self.freshFields( allNames )

self._responsive()

return this

},

removeFields: function( fields ) {

fields=Utils.convertToArray( fields )

var $fields=Utils.getFieldsFromArray( fields )

$fields.parents('.ideal-wrap').remove()

this.reload()

return this

}

})

}( jQuery, window, document ))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值