抽时间写了一个带有自动校验功能的Html5用户注册Demo。使用到Handlebars模板技术和手机验证码校验。
以下是效果截图:
1.页面代码:usersRegister.hbs
XML/HTML Code复制内容到剪贴板 <!DOCTYPEhtml> <> <> <> <htmllang="en"> <> <head> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"> <metahttp-equiv="X-UA-Compatible"content="IE=edge"/> <title>用户注册</title> <!--[ifltIE9]> <scriptsrc="/assets/scripts/html5shiv.js"></script> <![endif]--> <linkhref="/assets/styles/jquery.idealforms.min.css"rel="stylesheet"media="screen"/> <styletype="text/css"> body{ font:normal15px/1.5Arial,Helvetica,FreeSans,sans-serif; color:#222; overflow-y:scroll; padding:60px000; } .main{ width:560px; height:480px; margin:-50pxauto; } #my-form{ width:560px; height:450px; margin:0auto; border:1pxsolid#ccc; padding:3em; border-radius:3px; box-shadow:002pxrgba(0,0,0,.2); } </style> <scripttype="text/javascript"src="/assets/scripts/jquery-1.8.2.min.js"></script> <scripttype="text/javascript"src="/assets/scripts/jquery.idealforms.js"></script> </head> <body> <> <divclass="main"> <divstyle="height:5px;text-align:center;font-size:25px">欢迎您注册!</div> <> <formid="my-form"class="myform"> <div> <label>用户名:</label><inputid="username"name="username"type="text"/> </div> <div> <> <label>密码:</label><inputid="pass"name="password"type="text"/> </div> <div> <label>邮箱:</label><inputid="email"name="email" data-ideal="requiredemail"type="email"/> </div> <div> <label>电话:</label><inputid="telephone"type="text"name="phone"data-ideal="phone"/> </div> <div> <label>供应商V码:</label><inputid="vCode"type="text"name="vCode"data-ideal="vCode"/> </div> <div> <label>真实姓名:</label><inputid="trueName"type="text"name="trueName"data-ideal="trueName"/> </div> <div> <label>手机验证码:</label><inputid="telCode"type="text"name="telCode"data-ideal="telCode"/> </div> <divstyle="margin-bottom:5px;"> <buttonid="getTelCode"type="button"style="margin-left:160px;margin-right:auto;">获取手机校验码</button> <hrstyle="margin-top:5px;margin-bottom:5px;"/> </div> <!--<div> <label>性别:</label> <selectid="sex"name="sex"> <optionvalue="男">男</option> <optionvalue="女">女</option> </select> </div> <div> <label>昵称:</label><inputid="nickName"type="text"name="nickName"data-ideal="nickName"/> </div> <div> <label>年龄:</label><inputid="age"type="text"name="age"data-ideal="age"/> </div>--> <!--<div> <label>地址:</label><inputtype="text"name="address"data-ideal="address"/> </div> <div> <label>QQ:</label><inputtype="text"name="qq"data-ideal="qq"/> </div> <div> <label>邮编:</label><inputtype="text"name="zip"data-ideal="zip"/> </div> <div> <label>传真:</label><inputtype="text"name="fax"data-ideal="fax"/> </div> <div> <label>身份证:</label><inputtype="text"name="creditID"data-ideal="creditID"/> </div> <div> <label>出生日期:</label><inputname="date"class="datepicker" data-ideal="date"type="text"placeholder="月/日/年"/> </div> <div> <label>上传头像:</label><inputid="file"name="file"multiple type="file"/> </div> <div> <label>个人主页:</label><inputname="website"data-ideal="url" type="text"/> </div> <div> <label>备注:</label> <textareaid="comments"name="comments"></textarea> </div> --> <!--<divid="languages"> <label>语言:</label><label><inputtype="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><inputtype="radio" name="radio"checked/>1</label><label><inputtype="radio" name="radio"/>2</label><label><inputtype="radio"name="radio"/>3</label> <label><inputtype="radio"name="radio"/>4</label> </div> <div> <label>国籍:</label><selectid="states"name="states"> <optionvalue="default">–选择国籍–</option> <optionvalue="AL">阿拉伯</option> <optionvalue="AK">中国</option> <optionvalue="AZ">美国</option> <optionvalue="AR">法国</option> <optionvalue="CA">英国</option> <optionvalue="CO">德国</option> <optionvalue="CT">西班牙</option> <optionvalue="DE">俄罗斯</option> </select> </div>--> <divstyle="margin-top:10px;margin-left:100px;margin-right:100px;"> <buttontype="button"id="submit"class="submit">提交</button> <buttonid="reset"type="button">重置</button> </div> </form> <> </div> <scripttype="text/javascript"> varoptions={ onFail:function(){ alert($myform.getInvalid().length+'invalidfields.') }, inputs:{ 'password':{ filters:'requiredpass' }, 'username':{ filters:'requiredusername' }, 'email':{ filters:'requiredemail' }, 'phone':{ filters:'requiredphone' }, 'trueName':{ filters:'required' }, 'vCode':{ filters:'required' }, 'telCode':{ filters:'required' } /* 'age':{ filters:'requireddigits', data:{ min:16, max:70 } }, 'file':{ filters:'extension', data:{ extension:['jpg'] } }, 'comments':{ filters:'minmax', data:{ min:50, max:200 } }, 'states':{ filters:'exclude', data:{ exclude:['default'] }, errors:{ exclude:'选择国籍.' } }, 'langs[]':{ filters:'minmax', data:{ min:2, max:3 }, errors:{ min:'Checkatleast<strong>2</strong>options.', max:'Nomorethan<strong>3</strong>optionsallowed.' } } */ } }; $('#getTelCode').click(function(){ vartelephone=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(){ varusername=document.getElementById("username").value;//用户名 varpassword=document.getElementById("pass").value;//密码 varemail=document.getElementById("email").value;//邮箱 vartelephone=document.getElementById("telephone").value;//手机号码 varvCode=document.getElementById("vCode").value;//公司V码 vartelCode=document.getElementById("telCode").value;//手机校验码 vartrueName=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 varcurWwwPath=window.document.location.href; //获取主机地址之后的目录,如:uimcardprj/share/meun.jsp varpathName=window.document.location.pathname; varpos=curWwwPath.indexOf(pathName); //获取主机地址,如:http://localhost:8083 varlocalhostPaht=curWwwPath.substring(0,pos); //获取带"/"的项目名,如:/uimcardprj varprojectName=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>'
以下是整个代码文件:
XML/HTML Code复制内容到剪贴板 /*-------------------------------------------------------------------------- jq-idealforms2.1 *Author:CedricRuiz *License:GPLorMIT *Demo:http://elclanrs.github.com/jq-idealforms/ * --------------------------------------------------------------------------*/ ;(function($,window,document,undefined){ 'usestrict'; //GlobalIdealFormsnamespace $.idealforms={} $.idealforms.filters={} $.idealforms.errors={} $.idealforms.flags={} $.idealforms.ajaxRequests={} /*--------------------------------------------------------------------------*/ /** *@namespaceAchestforvariousUtils */ varUtils={ /** *Getwidthofwidestelementinthecollection. *@memberOfUtils *@param{jQueryobject}$elms *@returns{number} */ getMaxWidth:function($elms){ varmaxWidth=0 $elms.each(function(){ varwidth=$(this).outerWidth() if(width>maxWidth){ maxWidth=width } }) returnmaxWidth }, /** *HackywayofgettingLESSvariables *@memberOfUtils *@param{string}nameThenameoftheLESSclass. *@param{string}propThecsspropertywherethedataisstored. *@returns{number,string} */ getLessVar:function(name,prop){ varvalue=$('<pclass="'+name+'"></p>').hide().appendTo('body').css(prop) $('.'+name).remove() return(/^d+/.test(value)?parseInt(value,10):value) }, /** *LikeES5Object.keys */ getKeys:function(obj){ varkeys=[] for(varkeyinobj){ if(obj.hasOwnProperty(key)){ keys.push(key) } } returnkeys }, //Getlenghtofanobject getObjSize:function(obj){ varsize=0,key; for(keyinobj){ if(obj.hasOwnProperty(key)){ size++; } } returnsize; }, isFunction:function(obj){ returntypeofobj==='function' }, isRegex:function(obj){ returnobjinstanceofRegExp }, isString:function(obj){ returntypeofobj==='string' }, getByNameOrId:function(str){ var$el=$('[name="'+str+'"]').length ?$('[name="'+str+'"]')//byname :$('#'+str)//byid return$el.length ?$el :$.error('Thefield"'+str+'"doesn'texist.') }, getFieldsFromArray:function(fields){ varf=[] for(vari=0,l=fields.length;i<l;i++){ f.push(Utils.getByNameOrId(fields[i]).get(0)) } return$(f) }, convertToArray:function(obj){ returnObject.prototype.toString.call(obj)==='[objectArray]' ?obj:[obj] }, /** *DeterminetypeofanyIdealFormselement *@param$inputjQuery$inputobject */ 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'|| /hd/.test(type)&&'heading'|| /hr/.test(type)&&'separator'|| /hidden/.test(type)&&'hidden' ) }, /** *Generatesaninput *@paramname`name`attributeoftheinput *@paramtype`type`or`tagName`oftheinput */ makeInput:function(name,value,type,list,placeholder){ varmarkup,items=[],item,i,len functionsplitValue(str){ varitem,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='<textareaid="'+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('<optionvalue="'+value+'">'+item+'</option>') } markup= '<selectid="'+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>'+ '<inputtype="'+type+'"name="'+name+'"value="'+value+'"/>'+ item+ '</label>' ) } markup=items.join('') } returnmarkup } } /** *CustomtabsforIdealForms */ $.fn.idealTabs=function(container){ var //Elements $contents=this, $containercontainer=container, $wrapper=$('<ulclass="ideal-tabs-wrap"/>'), $tabs=(function(){ vartabs=[] $contents.each(function(){ varname=$(this).attr('name') varhtml= '<liclass="ideal-tabs-tab">'+ '<span>'+name+'</span>'+ '<iclass="ideal-tabs-tab-counterideal-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){ varre=newRegExp(name,'i') var$tab=$tabs.filter(function(){ returnre.test($(this).text()) }) return$tab.index() } }, /** *Publicmethods */ Methods={ /** *Switchtab */ 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) } } //Attachmethods for(varminMethods) $contents[m]=Methods[m] //Init $tabs.first() .addClass('ideal-tabs-tab-active') .end() .click(function(){ varname=$(this).text() $contents.switchTab(name) }) //InsertinDOM&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()//Startfresh return$contents } /** *Acustom<select>menujQueryplugin *@example`$('select').idealSelect()` */ $.fn.idealSelect=function(){ returnthis.each(function(){ var $select=$(this), $options=$select.find('option') /** *Generatemarkupandreturnelementsofcustomselect *@memberOf$.fn.toCustomSelect *@returns{object}Allelementsofthenewselectreplacement */ varidealSelect=(function(){ var $wrap=$('<ulclass="ideal-select'+$select.attr('name')+'"/>'), $menu=$( '<li><spanclass="ideal-select-title">'+ $options.filter(':selected').text()+ '</span></li>' ), items=(function(){ varitems=[] $options.each(function(){ var$this=$(this) items.push('<liclass="ideal-select-item">'+$this.text()+'</li>') }) returnitems }()) $menu.append('<ulclass="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') } }()) /** *@namespaceMethodsofcustomselect *@memberOf$.fn.toCustomSelect */ varActions={ getSelectedIdx:function(){ returnidealSelect.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() } }, //Fixloosingfocuswhenscrolling //andselectingitemwithkeyboard 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-openideal-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(){ //relativepositiontothesubmenu varelPos=$selected.position().top+itemHeight returndir==='down' ?elPos<=menuHeight :elPos>0 }()) if(!isInView){ itemHeight=(dir==='down') ?itemHeight//godown :-itemHeight//goup 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') /** *@namespaceKeypressed */ 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<$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)&&//notallowmodifierkeys(ctrl,cmd,meta,super...) newRegExp('^'+letter,'i').test($(this).text())//findfirstmatch }), nMatches=$matches.length, counter=idealSelect.select.data('counter')+1||0, curKey=idealSelect.select.data('key')||key, newIdx=$matches.eq(counter).index() if(!nMatches)//Nomatches returnfalse //Ifmorematcheswithsameletter if(curKey===key){ if(counter<nMatches){ idealSelect.select.data('counter',counter) } else{ idealSelect.select.data('counter',0) newIdx=$matches.eq(0).index() } } //Ifnewletter 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']() } } /** *@namespaceHoldsalleventsofcustomselectfor"menumode"and"listmode" *@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() } } //Resetevents vardisableEvents=function(){ idealSelect.select.removeClass('ideal-select-menuideal-select-list') $select.off('.menu.list') idealSelect.items.off('.menu.list') idealSelect.select.off('.menu.list') idealSelect.title.off('.menu.list') } //Menumode 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']) }) //Listmode 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){ //Preventdefaultkeydownevent //toavoidbugswithIdealSelectevents if(e.which!==9)e.preventDefault() }) //Reset idealSelect.select.on('reset',function(){ Actions.change(0) }) idealSelect.select.trigger('menu')//Defaultto"menumode" }) } /* *idealRadioCheck:jQueryplguinforcheckboxandradioreplacement *Usage:$('input[type=checkbox],input[type=radio]').idealRadioCheck() */ $.fn.idealRadioCheck=function(){ returnthis.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','')//FixclickinglabeliniOS $this.css({position:'absolute',left:'-9999px'})//hidebyshiftingleft //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($){ //BrowsersupportsHTML5multiplefile? varmultipleSupport=typeof$('<input/>')[0].multiple!=='undefined', isIE=/msie/i.test(navigator.userAgent) $.fn.idealFile=function(){ returnthis.each(function(){ var$file=$(this).addClass('ideal-file'),//theoriginalfileinput //labelthatwillbeusedforIEhack $wrap=$('<divclass="ideal-file-wrap">'), $input=$('<inputtype="text"class="ideal-file-filename"/>'), //Buttonthatwillbeusedinnon-IEbrowsers $button=$('<buttontype="button"class="ideal-file-upload">Open</button>'), //HackforIE $label=$('<labelclass="ideal-file-upload"for="'+$file[0].id+'">Open</label>') //Hidebyshiftingtotheleftsowe //canstilltriggerevents $file.css({ position:'absolute', left:'-9999px' }) $wrap.append($input,(isIE?$label:$button)).insertAfter($file) //Preventfocus $file.attr('tabIndex',-1) $button.attr('tabIndex',-1) $button.click(function(){ $file.focus().click()//Opendialog }) $file.change(function(){ varfiles=[],fileArr,filename //Ifmultipleissupportedthenextract //allfilenamesfromthefilearray if(multipleSupport){ fileArr=$file[0].files for(vari=0,len=fileArr.length;i<len;i++){ files.push(fileArr[i].name) } filename=files.join(',') //Ifnotsupportedthenjusttakethevalue //andremovethepathtojustshowthefilename }else{ filename=$file.val().split('').pop() } $input.val(filename)//Setthevalue .attr('title',filename)//Showfilenameintitletootlip }) $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')} }elseif(e.which===8||e.which===46){//Backspace&Del //Onsomebrowsersthevalueisread-only //withthistrickweremovetheoldinputandadd //acleanclonewithalltheoriginaleventsattached $file.replaceWith($file=$file.val('').clone(true)) $file.trigger('change') $input.val('') }elseif(e.which===9){//TAB return }else{//Allotherkeys returnfalse } } }) }) } }(jQuery)) /** *@namespaceErrors *@localeen */ $.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:'MustbeavalidUSzipcode.<em>(e.g.33245or33245-0003)</em>', url:'MustbeavalidURL.<em>(e.g.www.google.com)</em>', minChar:'Mustbeatleast<strong>{0}</strong>characterslong.', minOption:'Checkatleast<strong>{0}</strong>options.', maxChar:'Nomorethan<strong>{0}</strong>characterslong.', maxOption:'Nomorethan<strong>{0}</strong>optionsallowed.', range:'Mustbeanumberbetween{0}and{1}.', date:'Mustbeavaliddate.<em>(e.g.{0})</em>', dob:'Mustbeavaliddateofbirth.', exclude:'"{0}"isnotavailable.', excludeOption:'{0}', equalto:'Mustbethesamevalueas<strong>"{0}"</strong>', extension:'File(s)musthaveavalidextension.<em>(e.g."{0}")</em>', ajaxSuccess:'<strong>{0}</strong>isnotavailable.', ajaxError:'Servererror...' } /** *Getalldefaultfilters *@returnsobject */ 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) returnvalue.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) returnvalue.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]) returnval>=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',//defaultformat delimiter=/[^mdy]/.exec(userFormat)[0], theFormat=userFormat.split(delimiter), theDate=value.split(delimiter), isDate=function(date,format){ varm,d,y for(vari=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<=(newDate(y,m,0)).getDate() ) } this.error=$.idealforms.errors.date.replace('{0}',userFormat) returnisDate(theDate,theFormat) } }, dob:{ regex:function(input,value){ var userFormat= input.userOptions.data&&input.userOptions.data.dob ?input.userOptions.data.dob :'mm/dd/yyyy',//defaultformat //Simulateadateinput dateInput={ input:input.input, userOptions:{ data:{date:userFormat} } }, //Useinternaldatefiltertovalidatethedate isDate=filters.date.regex(dateInput,value), //DOB theYear=/d{4}/.exec(value), maxYear=newDate().getFullYear(),//Currentyear minYear=maxYear-100 this.error=$.idealforms.errors.dob returnisDate&&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){returnfalse} 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<len;i++){ valid=re.test(files[i].name); } this.error=$.idealforms.errors.extension.replace('{0}',extensions.join('","')) returnvalid } }, 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 //Sendinputnameas$_POST[name] vardata={} data[name]=$.trim(value) //Ajaxoptionsdefinedbytheuser 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')//toupdatecounter $field.removeClass('ajax') //Runcustomsuccesscallback 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') //Runcustomerrorcallback 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') //Runrequestandsaveittobeabletoabortit //sorequestsdon'tbubble $.idealforms.ajaxRequests[name]=$.ajax(ajaxOps) } } } returnfilters } $.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('validinvalid') }, novalidclass:function(i){ i.parents('.ideal-field').removeClass('valid') }, noinvalidclass:function(i){ i.parents('.ideal-field').removeClass('invalid') } } /* *IdealFormsplugin */ var_defaults={ inputs:{}, customFilters:{}, customFlags:{}, globalFlags:'', onSuccess:function(e){alert('Thankyou...')}, 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') //Setlocalizedfilters $.extend($.idealforms.filters,getFilters()) self._init() } //Plugin $.fn.idealforms=function(options){ returnthis.each(function(){ if(!$.data(this,'idealforms')){ $.data(this,'idealforms',newIdealForms(this,options)) } }) } //GetLESSvariables varLessVars={ fieldWidth:Utils.getLessVar('ideal-field-width','width') } /* *PrivateMethods */ $.extend(IdealForms.prototype,{ _init:function(){ varself=this varo=self.opts varformElements=self._getFormElements() self.$form.css('visibility','visible') .addClass('ideal-form') .attr('novalidate','novalidate')//disableHTML5validation //Domarkup formElements.inputs .add(formElements.headings) .add(formElements.separators) .each(function(){self._doMarkup($(this))}) //Generatetabs if(self.$tabs.length){ var$tabContainer=$('<divclass="ideal-wrapideal-tabsideal-full-width"/>') self.$form.prepend($tabContainer) self.$tabs.idealTabs($tabContainer) } //Alwaysshowdatepickerbelowtheinput if(jQuery.ui){ $.datepicker._checkOffset=function(a,b,c){returnb} } //Addinputsspecifiedbydata-ideal //tothelistofuserinputs 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() } //Formevents self.$form.on({ keydown:function(e){ //Preventsubmitwhenpressingenter //butexcludetextareas 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()//Startfresh }, _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(){ returnthis.$form.find('[name="'+Utils.getKeys(this.opts.inputs).join('"],[name="')+'"]') }, _getTab:function(nameOrIdx){ varself=this varisNumber=!isNaN(nameOrIdx) if(isNumber){ returnself.$tabs.eq(nameOrIdx) } returnself.$tabs.filter(function(){ varre=newRegExp(nameOrIdx,'i') returnre.test($(this).data('ideal-tabs-content-name')) }) }, _getCurrentTabIdx:function(){ returnthis.$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() //Autocompletecausessomeproblems... formElements.inputs.attr('autocomplete','off') //Showtabstocalculatedimensions if(self.$tabs.length){self.$tabs.show()} //Adjustlabels varlabels=formElements.labels labels.removeAttr('style').width(Utils.getMaxWidth(labels)) //Adjustheadingsandseparators 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() //Donecalculatinghidetabs 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(){ //HacktofixIE9notresizing var$this=$(this) varw=$this.outerWidth()//cachefirst! setTimeout(function(){ $this.datepicker('widget').css('width',w) },1) }, onClose:function(){$(this).removeClass('open')} }) }) //Adjustwidth $datepicker.on('focuskeyup',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) //Validationelements var$field=$('<spanclass="ideal-field"/>') var$error=$('<spanclass="ideal-error"/>') var$valid=$('<iclass="ideal-iconideal-icon-valid"/>') var$invalid=$('<iclass="ideal-iconideal-icon-invalid"/>') .click(function(){ $(this).parent().find('input:first,textarea,select').focus() }) //Basicmarkup $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(){ //Checkifinputisalreadywrappedsowedon't //wrapradiosandchecksmorethanonce 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('<spanclass="ideal-heading"/>') }, separator:function(){ $element.closest('div').addClass('ideal-full-width') $element.wrapAll('<divclass="ideal-separator"/>') } } //Generatemarkupforcurrentelementtype idealElements[elementType]?idealElements[elementType]():$.noop() $error.add($valid).add($invalid).hide()//Startfresh }, /**Validatesaninputandshowsorhideserrorandicon *@memberOfActions *@param{object}$inputjQueryobject *@param{string}eTheJavaScriptevent */ _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={ //Ifisradioorcheckvalidateallinputsrelatedbyname input:isRadioCheck?self.$form.find('[name="'+name+'"]'):$input, userOptions:userOptions } //Validationelements 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') functionresetError(){ $field.removeClass('validinvalid').removeData('ideal-isvalid') $error.add($invalid).add($valid).hide() } functionshowOrHideError(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')) } } //Preventvalidationwhentypingbutnotintroducinganynewcharacters //ThisismainlytopreventmultipleAJAXrequests varoldValue=$input.data('ideal-value')||0 $input.data('ideal-value',value) if(e.type==='keyup'&&value===oldValue){returnfalse} //Validate if(userFilters){ $.each(userFilters,function(i,filter){ vartheFilter=$.idealforms.filters[filter] varcustomError=userOptions.errors&&userOptions.errors[filter] varerror='' //Iffieldisemptyandnotrequired if(!value&&filter!=='required'){ resetError() returnfalse } if(theFilter){ //Abortandresetajaxifthere'sarequestpending if(e.type==='keyup'&&ajaxRequest){ ajaxRequest.abort() $field.removeClass('ajax') } //AJAX if(filter==='ajax'){ showOrHideError(error,false)//setinvalidtillresponsecomesback $error.hide() if(e.type==='keyup'){ theFilter.regex(inputData,value,showOrHideError)//runstheajaxcallback }else{ varajaxError=$input.data('ideal-ajax-error') if(ajaxError){ showOrHideError(ajaxError,$input.data('ideal-ajax-resp')||false) } } } //Allotherfilters else{ varvalid=Utils.isRegex(theFilter.regex)&&theFilter.regex.test(value)|| Utils.isFunction(theFilter.regex)&&theFilter.regex(inputData,value) error=customError||theFilter.error//assignerroraftercallingregex() showOrHideError(error,valid) if(!valid){returnfalse} } } }) } //Resetiftherearenofilters else{ resetError() } //Flags varflags=(function(){ varf=userOptions.flags&&userOptions.flags.split('')||[] if(o.globalFlags){ $.each(o.globalFlags.split(''),function(i,v){f.push(v)}) } returnf }()) if(flags.length){ $.each(flags,function(i,f){ vartheFlag=$.idealforms.flags[f] if(theFlag){theFlag($input,e.type)} }) } //Updatecounter if(self.$tabs.length){ self._updateTabsCounter(self._getCurrentTabIdx()) } }, _attachEvents:function(){ varself=this self._getUserInputs().on('keyupchangefocusblur',function(e){ var$this=$(this) var$field=$this.parents('.ideal-field') varisFile=$this.is('input[type=file]') //Triggeronchangeiftype=filecuzcustomfile //disablesfocusonoriginalfileinput(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()<maxWidth) :this.$form.toggleClass('stack',$(window).width()<this.opts.responsiveAt) varisStack=this.$form.is('.stack') $emptyLabel.toggle(!isStack) $customSelect.trigger(isStack?'list':'menu') //HidedatePicker var$datePicker=this.$form.find('input.hasDatepicker') if($datePicker.length){$datePicker.datepicker('hide')} } }) /* *PublicMethods */ $.extend(IdealForms.prototype,{ getInvalid:function(){ returnthis.$form.find('.ideal-field').filter(function(){ return$(this).data('ideal-isvalid')===false }) }, getInvalidInTab:function(nameOrIdx){ returnthis._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() } returnthis }, 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() returnthis }, switchTab:function(nameOrIdx){ this.$tabs.switchTab(nameOrIdx) returnthis }, nextTab:function(){ this.$tabs.nextTab() returnthis }, prevTab:function(){ this.$tabs.prevTab() returnthis }, firstTab:function(){ this.$tabs.firstTab() returnthis }, lastTab:function(){ this.$tabs.lastTab() returnthis }, fresh:function(){ this._getUserInputs().change().parents('.ideal-field') .removeClass('validinvalid') returnthis }, freshFields:function(fields){ fields=Utils.convertToArray(fields) $.each(fields,function(i){ var$input=Utils.getByNameOrId(fields[i]) $input.change().parents('.ideal-field').removeClass('validinvalid') }) returnthis }, reload:function(){ this._adjust() this._attachEvents() returnthis }, reset:function(){ varformElements=this._getFormElements() formElements.text.val('')//textinputs formElements.radiocheck.removeAttr('checked')//radio&check //Selectandcustomselect formElements.select.find('option').first().prop('selected',true) this.$form.find('.ideal-select').trigger('reset') if(this.$tabs.length){this.firstTab()} this.focusFirst().fresh() returnthis }, 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) returnthis }, 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}) }) returnthis }, setOptions:function(options){ $.extend(true,this.opts,options) this.reload().fresh() returnthis }, setFieldOptions:function(name,options){ $.extend(true,this.opts.inputs[name],options) this.reload().freshFields([name]) returnthis }, addFields:function(fields){ fields=Utils.convertToArray(fields) varself=this //SavenamesofallinputsinArray //tousemethodsthattakenamesie.fresh() varallNames=[] //AddaninputtotheDOM functionadd(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=$('<div>'+ '<label>'+label+':</label>'+ Utils.makeInput(name,value,type,list,placeholder)+ '</div>') var$input=$field.find('input,select,textarea,:button') //Addinputswithfilterstothelist //ofuserinputstovalidate if(userOptions.filters){self.opts.inputs[name]=userOptions} self._doMarkup($input) //InsertinDOM if(ops.addAfter){ $field.insertAfter( $(Utils.getByNameOrId(ops.addAfter)).parents('.ideal-wrap') ) }elseif(ops.addBefore){ $field.insertBefore( $(Utils.getByNameOrId(ops.addBefore)) .parents('.ideal-wrap') ) }elseif(ops.appendToTab){ $field.insertAfter( self._getTab(ops.appendToTab).find('.ideal-wrap:last-child') ) }else{ $field.insertAfter(self.$form.find('.ideal-wrap').last()) } //Addcurrentfieldnametolistofnames allNames.push(name) } //Runthrougheachinput $.each(fields,function(i,ops){add(ops)}) self.reload() self.freshFields(allNames) self._responsive() returnthis }, removeFields:function(fields){ fields=Utils.convertToArray(fields) var$fields=Utils.getFieldsFromArray(fields) $fields.parents('.ideal-wrap').remove() this.reload() returnthis } }) }(jQuery,window,document))
以上所述是本文的全部内容希望对大家有所帮助!