抽时间写了一个带有自动校验功能的html5用户注册demo。使用到handlebars模板技术和手机验证码校验。
以下是效果截图:
1.页面代码:ursregister.hbs
xml/html code
复制内容到剪贴板
<!doctypehtml> <!–[ifie8]><htmllang=”en”class=”ie8″><![endif]–> <!–[ifie9]><htmllang=”en”class=”ie9″><![endif]–> <!–[if(gtie9)|!(ie)]><!–> <htmllang=“en”> <!–<![endif]–> <head> <metahttp-equiv=“content-type”content=“text/html;chart=utf-8”> <metahttp-equiv=“x-ua-compatible”content=“ie=edge”/> <title>用户注册</title> <!–[ifltie9]> <scriptsrc=“/asts/scripts/html5shiv.js”></script> <![endif]–> <linkhref=“/asts/styles/jquery.idealforms.min.css”rel=“stylesheet”media=“screen”/> <styletype=“text/css”> body{ font:normal15px/1.5arial,helvetica,freesans,sans-rif; 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=“/asts/scripts/jquery-1.8.2.min.js”></script> <scripttype=“text/javascript”src=“/asts/scripts/jquery.idealforms.js”></script> </head> <body> <!–style=”background-image:url(static/image/bg.jpg)–> <divclass=“main”> <divstyle=“height:5px;text-align:center;font-size:25px”>欢迎您注册!</div> <!–beginform–> <formid=“my-form”class=“myform”> <div> <label>用户名:</label><inputid=“urname”name=“urname”type=“text”/> </div> <div> <!–<label>密码:</label><inputid=”pass”name=”password”type=”password”/>–> <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> <lectid=“x”name=“x”> <optionvalue=“男”>男</option> <optionvalue=“女”>女</option> </lect> </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=“chine”/>中文</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><lectid=“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> </lect> </div>—> <divstyle=“margin-top:10px;margin-left:100px;margin-right:100px;”> <buttontype=“button”id=“submit”class=“submit”>提交</button> <buttonid=“ret”type=“button”>重置</button> </div> </form> <!–endform–> </div> <scripttype=“text/javascript”> varoptions={ onfail:function(){ alert($myform.getinvalid().length+‘invalidfields.’) }, inputs:{ ‘password’:{ filters:‘requiredpass’ }, ‘urname’:{ filters:‘requiredurname’ }, ’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(“手机号码不能为空!”); } el{ $.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(){ varurname=document.getelementbyid(“urname”).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/ursregister?urname=“+urname+”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); } }); }); $(‘#ret’).click(function(){ $myform.ret().fresh().focusfirst(); }); </script> </body> </html>2.jq输入校验:jquery.idealforms.js
该js校验初始版本来自cedric ruiz,我略有修改。
部分校验的规则如下:
required: ‘此处是必填的.’
number: ‘必须是数字.’,
digits: ‘必须是唯一的数字.’
name: ‘必须至少有3个字符长,并且只能包含字母.’
urname: ‘用户名最短5位,最长30位,请使用英文字母、数字、中文和下划线. 用户名首字符必须为字母、数字、中文,不能为全数字.中文最长21个字.’
pass: ‘密码的位数必须的在6-15位之间,并且至少包含一个数字,一个大写字母和一个小写字母.’
strongpass: ‘必须至少为8个字符长,至少包含一个大写字母和一个小写字母和一个数字或特殊字符.’
email: ‘必须是一个有效的email地址. <em>(例:
phone: ‘必须是一个有效的手机号码. <em>(例: 18723101212)</em>’
以下是整个代码文件:
xml/html code
复制内容到剪贴板
/*————————————————————————– jq-idealforms2.1 *author:cedricruiz *licen:gplormit *demo:http://elclanrs.github.com/jq-idealforms/ * ————————————————————————–*/ ;(function($,window,document,undefined){ ‘ustrict’; //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)?parint(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] }, /** *determinetypeofanyidealformlement *@param$inputjquery$inputobject */ getidealtype:function($el){ vartype=$el.attr(‘type’)||$el[0].tagname.tolowerca() return( /(text|password|email|number|arch|url|tel|textarea)/.test(type)&&‘text’|| /file/.test(type)&&‘file’|| /lect/.test(type)&&‘lect’|| /(radio|checkbox)/.test(type)&&‘radiocheck’|| /(button|submit|ret)/.test(type)&&‘button’|| /h\d/.test(type)&&‘heading’|| /hr/.test(type)&&‘parator’|| /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] }el{ item=value=str } return{item:item,value:value} } //text&file if(/^(text|password|email|number|arch|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>‘ } //lect if(/lect/.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= ‘<lectid=”‘+name+'”name=“‘+name+'”>‘+ items.join(”)+ ‘</lect>‘ } //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.sw吐槽是什么意思啊itchtab(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) }) //inrtindom&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<lect>menujqueryplugin *@example`$(‘lect’).ideallect()` */ $.fn.ideallect=function(){ returnthis.each(function(){ var $lect=$(this), $options=$lect.find(‘option’) /** *generatemarkupandreturnelementsofcustomlect *@memberof$.fn.tocustomlect *@returns{object}allelementsofthenewlectreplacement */ varideallect=(function(){ var $wrap=$(‘<ulclass=“ideal-lect‘+$lect.attr(‘name’)+'”/>‘), $menu=$( ‘<li><spanclass=“ideal-lect-title”>‘+ $options.filter(‘:lected’).text()+ ‘</span></li>‘ ), items=(function(){ varitems=[] $options.each(function(){ var$this=$(this) items.push(‘<liclass=“ideal-lect-item”>‘+$this.text()+‘</li>‘) }) returnitems }()) $menu.append(‘<ulclass=“ideal-lect-sub”>‘+items.join(”)+‘</ul>‘) $wrap.append($menu) return{ lect:$wrap, title:$menu.find(‘.ideal-lect-title’), sub:$menu.find(‘.ideal-lect-sub’), items:$menu.find(‘.ideal-lect-item’) } }()) /** *@namespacemethodsofcustomlect *@memberof$.fn.tocustomlect */ varactions={ getlectedidx:function(){ returnideallect.items .filter(‘.ideal-lect-item-lected’).index() }, /** *@private */ init:(function(){ $lect.css({ position:‘absolute’, left:‘-9999px’ }) ideallect.sub.hide() ideallect.lect.inrtafter($lect) ideallect.lect.css( ‘min-width’, utils.getmaxwidth(ideallect.items) ) ideallect.items .eq($options.filter(‘:lected’).index()) .addclass(‘ideal-lect-item-lected’) }()), nowindowscroll:function(e){ if(e.which===40||e.which===38||e.which===13){ e.preventdefault() } }, //fixloosingfocuswhenscrolling //andlectingitemwithkeyboard focushack:function(){ ttimeout(function(){ $lect.trigger(‘focus’) },1) }, focus:function(){ ideallect.lect.addclass(‘ideal-lect-focus’) $(document).on(‘keydown.noscroll’,actions.nowindowscroll) }, blur:function(){ ideallect.lect .removeclass(‘ideal-lect-openideal-lect-focus’) $(document).off(‘.noscroll’) }, scrollintoview:function(dir){ var $lected=ideallect.items.filter(‘.ideal-lect-item-lected’), itemheight=ideallect.items.outerheight(), menuheight=ideallect.sub.outerheight(), isinview=(function(){ //relativepositiontothesubmenu varelpos=$lected.position().top+itemheight returndir===‘down’ ?elpos<=menuheight :elpos>0 }()) if(!isinview){ itemheight=(dir===‘down’) ?itemheight//godown :-itemheight//goup ideallect.sub .scrolltop(ideallect.sub.scrolltop()+itemheight) } }, scrolltoitem:function(){ varidx=actions.getlectedidx(), height=ideallect.items.outerheight(), nitems=ideallect.items.length, allheight=height*nitems, curheight=height*(nitems–idx) ideallect.sub.scrolltop(allheight–curheight) }, showmenu:function(){ ideallect.sub.fadein(‘fast’) ideallect.lect.addclass(‘ideal-lect-open’) actions.lect(actions.getlectedidx()) actions.scrolltoitem() }, hidemenu:function(){ ideallect.sub.hide() ideallect.lect.removeclass(‘ideal-lect-open’) }, lect:function(idx){ ideallect.items .removeclass(‘ideal-lect-item-lected’) ideallect.items .eq(idx).addclass(‘ideal-lect-item-lected’) }, change:function(idx){ vartext=ideallect.items.eq(idx).text() actions.lect(idx) ideallect.title.text(text) $options.eq(idx).prop(‘lected’,true) $lect.trigger(‘change’) }, keydown:function(key){ var idx=actions.getlectedidx(), ismenu=ideallect.lect.is(‘.ideal-lect-menu’), isopen=ideallect.lect.is(‘.ideal-lect-open’) /** *@namespacekeypresd */ 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.lect(idx+1) :actions.change(idx+1) } actions.scrollintoview(‘down’) }, 38:function(){//up if(idx>0){ isopen ?actions.lect(idx–1) :actions.change(idx–1) } actions.scrollintoview(‘up’) }, ‘default’:function(){//letter var letter=string.fromcharcode(key), $matches=ideallect.items .filter(function(){ return/^\w+$/i.test(letter)&&//notallowmodifierkeys(ctrl,cmd,meta,super…) newregexp(‘^’+letter,‘i’).test($(this).text())//findfirstmatch }), nmatches=$matches.length, counter=ideallect.lect.data(‘counter’)+1||0, curkey=ideallect.lect.data(‘key’)||key, newidx=$matches.eq(counter).index() if(!nmatches)//nomatches returnfal //ifmorematcheswithsameletter if(curkey===key){ if(counter<nmatches){ ideallect.lect.data(‘counter’,counter) } el{ ideallect.lect.data(‘counter’,0) newidx=$matches.eq(0).index() } } //ifnewletter el{ ideallect.lect.data(‘counter’,0) newidx=$matches.eq(0).index() } if(isopen) actions.lect(newidx) el actions.change(newidx) ideallect.lect.data(‘key’,key) actions.scrolltoitem() actions.focushack() } } keys[key] ?keys[key]() :keys[‘default’]() } } /** *@namespaceholdsalleventsofcustomlectfor“menumode”and“listmode” *@memberof$.fn.tocustomlect */ 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() $lect.trigger(‘focus’) }, ‘hideoutside.menu’:function(){ $lect.off(‘blur.menu’) $(document).on(‘moudown.ideal’,function(evt){ if(!$(evt.target).clost(ideallect.lect).length){ $(document).off(‘moudown.ideal’) $lect.on(‘blur.menu’,events[‘blur.menu’]) }el{ actions.focushack() } }) }, ‘moudown.list’:function(){ actions.focushack() } } //retevents vardisableevents=function(){ ideallect.lect.removeclass(‘ideal-lect-menuideal-lect-list’) $lect.off(‘.menu.list’) ideallect.items.off(‘.menu.list’) ideallect.lect.off(‘.menu.list’) ideallect.title.off(‘.menu.list’) } //menumode ideallect.lect.on(‘menu’,function(){ disableevents() ideallect.lect.addclass(‘ideal-lect-menu’) actions.hidemenu() $lect.on({ ‘blur.menu’:events[‘blur.menu’], ‘focus.menu’:events.focus, ‘keydown.menu’:events.keydown }) ideallect.lect.on(‘moudown.menu’,events[‘hideoutside.menu’]) ideallect.items.on(‘click.menu’,events[‘clickitem.menu’]) ideallect.title.on(‘click.menu’,events[‘clicktitle.menu’]) }) //listmode ideallect.lect.on(‘list’,function(){ disableevents() ideallect.lect.addclass(‘ideal-lect-list’) actions.showmenu() $lect.on({ ‘blur.list’:events[‘blur.list’], ‘focus.list’:events.focus, ‘keydown.list’:events.keydown }) ideallect.lect.on(‘moudown.list’,events[‘moudown.list’]) ideallect.items.on(‘moudown.list’,events[‘clickitem.list’]) }) $lect.keydown(function(e){ //preventdefaultkeydownevent //toavoidbugswithideallectevents if(e.which!==9)e.preventdefault() }) //ret ideallect.lect.on(‘ret’,function(){ actions.change(0) }) ideallect.lect.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.inrtafter($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($){ //browrsupportshtml5multiplefile? varmultiplesupport=typeof$(‘<input/>‘)[0].multiple!==‘undefined’, isie=/msie/i.test(navigator.uragent) $.fn.idealfile=function(){ returnthis.each(function(){ var$file=$(this).addclass(‘ideal-file’),//theoriginalfileinput //labelthatwillbeudforiehack $wrap=$(‘<divclass=“ideal-file-wrap”>‘), $input=$(‘<inputtype=“text”class=“ideal-file-filename”/>‘), //buttonthatwillbeudinnon-iebrowrs $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)).inrtafter($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 }el{ filename=$file.val().split(‘\\’).pop() } $input.val(filename)//tthevalue .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’)} }elif(e.which===8||e.which===46){//backspace&del //onsomebrowrsthevalueisread-only //withthistrickweremovetheoldinputandadd //acleanclonewithalltheoriginaleventsattached $file.replacewith($file=$file.val(”).clone(true)) $file.trigger(‘change’) $input.val(”) }elif(e.which===9){//tab return }el{//allotherkeys returnfal } } }) }) } }(jquery)) /** *@namespaceerrors *@localeen */ $.idealforms.errors={ required:‘此处是必填的.’, number:‘必须是数字.’, digits:‘必须是唯一的数字.’, name:‘必须至少有3个字符长,并且只能包含字母.’, urname:‘用户名最短5位,最长30位,请使用英文字母、数字、中文和下划线.用户名首字符必须为字母、数字、中文,不能为全数字.中文最长21个字.’, pass:‘密码的位数必须的在6-15位之间,并且至少包含一个数字,一个大写字母和一个小写字母.’, strongpass:‘必须至少为8个字符长,至少包含一个大写字母和一个小写字母和一个数字或特殊字符.’, email:‘必须是一个有效的email地址.<em>(例:ur@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:‘rvererror…’ } /** *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 }, urname:{ regex:/^[a-z](?=[\w.]{4,30}$)\w*\.?\w*$/i, error:$.idealforms.errors.urname }, 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.uroptions.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.uroptions.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.uroptions.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 urformat= input.uroptions.data&&input.uroptions.data.date ?input.uroptions.data.date :‘mm/dd/yyyy’,//defaultformat delimiter=/[^mdy]/.exec(urformat)[0], theformat=urformat.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}’,urformat) returnisdate(thedate,theformat) } }, dob:{ regex:function(input,value){ var urformat= input.uroptions.data&&input.uroptions.data.dob ?input.uroptions.data.dob :‘mm/dd/yyyy’,//defaultformat //simulateadateinput dateinput={ input:input.input, uroptions:{ data:{date:urformat} } }, //uinternaldatefiltertovalidatethedate 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.uroptions.data.exclude, isoption=$input.is(‘[type=“checkbox”],[type=“radio”],lect’) 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.uroptions.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){returnfal} 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.uroptions.data.extension, re=newregexp(‘\\.’+extensions.join(‘|’)+’$’,‘i’), valid=fal 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){ varlf=this var$inputinput=input.input varuroptions=input.uroptions varname=$input.attr(‘name’) var$field=$input.parents(‘.ideal-field’) varvalid=fal varcustomerrors=uroptions.errors&&uroptions.errors.ajax lf.error={} lf.error.success=customerrors&&customerrors.success ?customerrors.success :$.idealforms.errors.ajaxsuccess.replace(‘{0}’,value) lf.error.fail=customerrors&&customerrors.error ?customerrors.error :$.idealforms.errors.ajaxerror //ndinputnameas$_post[name] vardata={} data[name]=$.trim(value) //ajaxoptionsdefinedbytheur varurajaxops=input.uroptions.data.ajax varajaxops={ type:‘post’, datatype:‘json’, data:data, success:function(resp,text,xhr){ console.log(resp) showorhideerror(lf.error.success,true) $input.data({ ‘ideal-ajax-resp’:resp, ‘ideal-ajax-error’:lf.error.success }) $input.trigger(‘change’)//toupdatecounter $field.removeclass(‘ajax’) //runcustomsuccesscallback if(urajaxops._success){ urajaxops._success(resp,text,xhr) } }, error:function(xhr,text,error){ if(text!==‘abort’){ showorhideerror(lf.error.fail,fal) $input.data(‘ideal-ajax-error’,lf.error.fail) $field.removeclass(‘ajax’) //runcustomerrorcallback if(urajaxops._error){ urajaxops._error(xhr,text,error) } } } } $.extend(ajaxops,urajaxops) //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){ varlf=this lf.$form=$(element) lf.opts=$.extend({},_defaults,options) lf.$tabs=lf.$form.find(‘ction’) //tlocalizedfilters $.extend($.idealforms.filters,getfilters()) lf._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(){ varlf=this varo=lf.opts varformelements=lf._getformelements() lf.$form.css(‘visibility’,‘visible’) .addclass(‘ideal-form’) .attr(‘novalidate’,‘novalidate’)//disablehtml5validation //domarkup formelements.inputs .add(formelements.headings) .add(formelements.parators) .each(function(){lf._domarkup($(this))}) //generatetabs if(lf.$tabs.length){ var$tabcontainer=$(‘<divclass=“ideal-wrapideal-tabsideal-full-width”/>‘) lf.$form.prepend($tabcontainer) lf.$tabs.idealtabs($tabcontainer) } //alwaysshowdatepickerbelowtheinput if(jquery.ui){ $.datepicker._checkofft=function(a,b,c){returnb} } //addinputsspecifiedbydata-ideal //tothelistofurinputs lf.$form.find(‘[data-ideal]’).each(function(){ varurinput=o.inputs[this.name] o.inputs[this.name]=urinput||{filters:$(this).data(‘ideal’)} }) //responsive if(o.responsiveat){ $(window).resize(function(){lf._responsive()}) lf._responsive() } //formevents lf.$form.on({ keydown:function(e){ //preventsubmitwhenpressingenter //butexcludetextareas if(e.which===13&&e.target.nodename!==‘textarea’){ e.preventdefault() } }, submit:function(e){ if(!lf.isvalid()){ e.preventdefault() o.onfail() lf.focusfirstinvalid() }el{ o.onsuccess(e) } } }) lf._adjust() lf._attachevents() lf.fresh()//startfresh }, _getformelements:function(){ return{ inputs:this.$form.find(‘input,lect,textarea,:button’), labels:this.$form.find(‘div>label:first-child’), text:this.$form.find(‘input:not([type=“checkbox”],[type=“radio”],[type=“submit”]),textarea’), lect:this.$form.find(‘lect’), 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’), parators:this.$form.find(‘hr’), hidden:this.$form.find(‘input:hidden’) } }, _geturinputs:function(){ returnthis.$form.find(‘[name=“‘+utils.getkeys(this.opts.inputs).join(‘”],[name=“‘)+'”]’) }, _gettab:function(nameoridx){ varlf=this varisnumber=!isnan(nameoridx) if(isnumber){ returnlf.$tabs.eq(nameoridx) } returnlf.$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(){ varlf=this lf.$tabs.each(function(i){ varinvalid=lf.getinvalidintab(i).length lf.$tabs.updatecounter(i,invalid) }) }, _adjust:function(){ varlf=this varo=lf.opts varformelements=lf._getformelements() varcurtab=lf._getcurrenttabidx() //autocompletecaussomeproblems… formelements.inputs.attr(‘autocomplete’,‘off’) //showtabstocalculatedimensions if(lf.$tabs.length){lf.$tabs.show()} //adjustlabels varlabels=formelements.labels labels.removeattr(‘style’).width(utils.getmaxwidth(labels)) //adjustheadingsandparators if(lf.$tabs.length){ this.$tabs.each(function(){ $(this).find(‘.ideal-heading:first’).addclass(‘first-child’) }) }el{ lf.$form.find(‘.ideal-heading:first’).addclass(‘first-child’) } lf._tdatepicker() //donecalculatinghidetabs if(lf.$tabs.length){ lf.$tabs.hide() lf.switchtab(curtab) } }, _tdatepicker:function(){ varo=this.opts var$datepicker=this.$form.find(‘input.datepicker’) if(jquery.ui&&$datepicker.length){ $datepicker.each(function(){ varurinput=o.inputs[this.name] vardata=urinput&&urinput.data&&urinput.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! ttimeout(function(){ $this.datepicker(‘widget’).css(‘width’,w) },1) }, onclo: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,lect’).focus() }) //basicmarkup $element.clost(‘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().andlf().wrapall($field.addclass(‘ideal-radiocheck’)) $element.parents(‘.ideal-field’).append($valid,$invalid).after($error) } if(!/radiocheck/.test(o.disablecustom)){ $element.idealradiocheck() } }, lect:function(){ idealelements._defaultinput() if(!/lect/.test(o.disablecustom)){ $element.ideallect() } }, 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.clost(‘div’).addclass(‘ideal-hidden’) }, heading:function(){ $element.clost(‘div’).addclass(‘ideal-full-width’) $element.parent().children().wrapall(‘<spanclass=“ideal-heading”/>‘) }, parator:function(){ $element.clost(‘div’).addclass(‘ideal-full-width’) $element.wrapall(‘<divclass=“ideal-parator”/>‘) } } //generatemarkupforcurrentelementtype idealelements[elementtype]?idealelements[elementtype]():$.noop() $error.add($valid).add($invalid).hide()//startfresh }, /**validatesaninputandshowsorhiderrorandicon *@memberofactions *@param{object}$inputjqueryobject *@param{string}ethejavascriptevent */ _validate:function($input,e){ varlf=this varo=this.opts varuroptions=o.inputs[$input.attr(‘name’)] varurfilters=uroptions.filters&&uroptions.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?lf.$form.find(‘[name=“‘+name+‘”]’):$input, uroptions:uroptions } //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’) functionreterror(){ $field.removeclass(‘validinvalid’).removedata(‘ideal-isvalid’) $error.add($invalid).add($valid).hide() } functionshoworhideerror(error,valid){ reterror() 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){returnfal} //validate if(urfilters){ $.each(urfilters,function(i,filter){ varthefilter=$.idealforms.filters[filter] varcustomerror=uroptions.errors&&uroptions.errors[filter] varerror=” //iffieldimptyandnotrequired if(!value&&filter!==‘required’){ reterror() returnfal } if(thefilter){ //abortandretajaxifthere’sarequestpending if(e.type===‘keyup’&&ajaxrequest){ ajaxrequest.abort() $field.removeclass(‘ajax’) } //ajax if(filter===‘ajax’){ showorhideerror(error,fal)//tinvalidtillresponcomesback $error.hide() if(e.type===‘keyup’){ thefilter.regex(inputdata,value,showorhideerror)//runstheajaxcallback }el{ varajaxerror=$input.data(‘ideal-ajax-error’) if(ajaxerror){ showorhideerror(ajaxerror,$input.data(‘ideal-ajax-resp’)||fal) } } } //allotherfilters el{ 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){returnfal} } } }) } //retiftherearenofilters el{ reterror() } //flags varflags=(function(){ varf=uroptions.flags&&uroptions.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(lf.$tabs.length){ lf._updatetabscounter(lf._getcurrenttabidx()) } }, _attachevents:function(){ varlf=this lf._geturinputs().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’) } lf._validate($this,e) }) }, _responsive:function(){ varformelements=this._getformelements() varmaxwidth=lessvars.fieldwidth+formelements.labels.outerwidth() var$emptylabel=formelements.labels.filter(function(){ return$(this).html()===‘‘ }) var$customlect=this.$form.find(‘.ideal-lect’) 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) $customlect.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’)===fal }) }, getinvalidintab:function(nameoridx){ returnthis._gettab(nameoridx).find(‘.ideal-field’).filter(function(){ return$(this).data(‘ideal-isvalid’)===fal }) }, 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,lect,textarea’).focus() }el{ this.$form.find(‘.ideal-field:first’) .find(‘input:first,lect,textarea’).focus() } returnthis }, focusfirstinvalid:function(){ var$first=this.getinvalid().first().find(‘input:first,lect,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._geturinputs().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 }, ret:function(){ varformelements=this._getformelements() formelements.text.val(”)//textinputs formelements.radiocheck.removeattr(‘checked’)//radio&check //lectandcustomlect formelements.lect.find(‘option’).first().prop(‘lected’,true) this.$form.find(‘.ideal-lect’).trigger(‘ret’) if(this.$tabs.length){this.firsttab()} this.focusfirst().fresh() returnthis }, retfields: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===‘lect’){ $input.find(‘option’).first().prop(‘lected’,true) $input.next(‘.ideal-lect’).trigger(‘ret’) } $input.change() }) this.freshfields(fields) returnthis }, togglefields:function(fields){ fields=utils.converttoarray(fields) varlf=this var$fields=utils.getfieldsfromarray(fields) $fields.each(function(){ var$this=$(this) varname=$this.attr(‘name’)||$this.attr(‘id’) varinput=lf.opts.inputs[name] varfilters=input&&input.filters vardatafilters=$this.data(‘ideal-filters’)||” $this.data(‘ideal-filters’,filters) $this.clost(‘.ideal-wrap’).toggle() lf.tfieldoptions(name,{filters:datafilters}) }) returnthis }, toptions:function(options){ $.extend(true,this.opts,options) this.reload().fresh() returnthis }, tfieldoptions:function(name,options){ $.extend(true,this.opts.inputs[name],options) this.reload().freshfields([name]) returnthis }, addfields:function(fields){ fields=utils.converttoarray(fields) varlf=this //savenamesofallinputsinarray //toumethodsthattakenamesie.fresh() varallnames=[] //addaninputtothedom functionadd(ops){ varname=ops.name varuroptions={ 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,lect,textarea,:button’) //addinputswithfilterstothelist //ofurinputstovalidate if(uroptions.filters){lf.opts.inputs[name]=uroptions} lf._domarkup($input) //inrtindom if(ops.addafter){ $field.inrtafter( $(utils.getbynameorid(ops.addafter)).parents(‘.ideal-wrap’) ) }elif(ops.addbefore){ $field.inrtbefore( $(utils.getbynameorid(ops.addbefore)) .parents(‘.ideal-wrap’) ) }elif(ops.appendtotab){ $field.inrtafter( lf._gettab(ops.appendtotab).find(‘.ideal-wrap:last-child’) ) }el{ $field.inrtafter(lf.$form.find(‘.ideal-wrap’).last()) } //addcurrentfieldnametolistofnames allnames.push(name) } //runthrougheachinput $.each(fields,function(i,ops){add(ops)}) lf.reload() lf.freshfields(allnames) lf._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))以上所述是本文的全部内容希望对大家有所帮助!