Home > Web Front-end > H5 Tutorial > Detailed example of H5 completing automatic verification of user registration

Detailed example of H5 completing automatic verification of user registration

Y2J
Release: 2017-05-24 13:27:07
Original
2577 people have browsed it

Html5implementationuser registrationautomatic verification function example code

05-24 10:49:46 Author: php Chinese website

I took the time to write an Html5 user registration with automatic verification function Demo. Use Handlebarstemplate technology and mobile phoneverification code for verification.

The following is a screenshot of the effect:

1. Page code: usersRegister.hbs

XML/HTML CodeCopy the content to the clipboard
  1. >     

  2.      

  3.      

  4.      

  5. <html lang="en">     

  6.      

  7. <head>     

  8.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">     

  9.     <meta http-equiv="X-UA-Compatible" content="IE=edge" />     

  10.     <title>用户注册title>     

  11.          

  12.     <div class="main" >     

  13.         <div style="height:5px;text-align:center;font-size:25px"> 欢迎您注册!div>     

  14.              

  15.         <form id="my-form" class="myform">     

  16.             <div>     

  17.                 <label>用户名:label><input id="username" name="username" type="text" />     

  18.             div>     

  19.             <div>     

  20.                      

  21.                 <label>密码:label><input id="pass" name="password" type="text" />     

  22.             div>     

  23.             <div>     

  24.                 <label>邮箱:label><input id="email" name="email"     

  25.                                          data-ideal="required email" type="email" />     

  26.             div>     

  27.             <div>     

  28.                 <label>电话:label><input id="telephone" type="text" name="phone" data-ideal="phone" />     

  29.             div>     

  30.             <div>     

  31.                 <label>供应商V码:label><input id="vCode" type="text" name="vCode" data-ideal="vCode" />     

  32.             div>     

  33.             <div>     

  34.                 <label>真实姓名:label><input id="trueName" type="text" name="trueName" data-ideal="trueName" />     

  35.             div>     

  36.             <div>     

  37.                 <label>手机验证码:label><input id="telCode" type="text" name="telCode" data-ideal="telCode" />     

  38.                                                                                                                                                                             "margin-bottom:5px;">                              

    <
  39. button

    id="getTelCode" type="button" style="margin-left

    :160px;
  40. margin-right
  41. :auto; "

    >Get mobile verification codebutton>                                                            margin-top:5px; margin-bottom:5px ;"/>                                                                             --<div>​​​​​​​​​​< ;label>Gender:label

  42. >
  43.                                            

    id="sex" name="sex ">                                                           option

    >
  44.                                                              ​​​​
  45. select>                    
  46. div>                                             
  47.                 <label>昵称:label><input id="nickName" type="text" name="nickName" data-ideal="nickName" />     

  48.             div>     

  49.             <div>     

  50.            nbsp;     <label>年龄:label><input id="age" type="text" name="age" data-ideal="age" />     

  51.             div>-->     

  52.                  

  53.     div>     

  54. <script type="text/javascript">     

  55.     var options = {     

  56.         onFail : function() {     

  57.             alert($myform.getInvalid().length + ' invalid fields.')     

  58.         },     

  59.         inputs : {     

  60.             'password' : {     

  61.                 filters : 'required pass'     

  62.             },     

  63.             'username' : {     

  64.                 filters : 'required username'     

  65.             },     

  66.             'email' : {     

  67.                 filters : 'required email'     

  68.             },     

  69.             'phone' : {     

  70.                 filters : 'required phone'     

  71.             },     

  72.             'trueName' : {     

  73.                 filters : 'required'     

  74.             },     

  75.             'vCode' : {     

  76.                 filters : 'required'     

  77.             },     

  78.             'telCode' : {     

  79.                 filters : 'required'     

  80.             }     

  81.             /*     

  82.             'age' : {     

  83.                 filters : 'required digits',     

  84.                 data : {     

  85.                    min : 16,     

  86.                    max : 70     

  87.                 }     

  88.             },     

  89.             'file' : {     

  90.                 filters : 'extension',     

  91.                 data : {     

  92.                     extension : [ 'jpg' ]     

  93.                 }     

  94.             },     

  95.             'comments' : {     

  96.                 filters : 'min max',     

  97.                 data : {     

  98.                     min : 50,     

  99.                     max : 200     

  100.                 }     

  101.             },     

  102.             'states' : {     

  103.                 filters : 'exclude',     

  104.                 data : {     

  105.                     exclude : [ 'default' ]     

  106.                 },     

  107.                 errors : {     

  108.                     exclude : '选择国籍.'     

  109.                 }     

  110.             },     

  111.             'langs[]' : {     

  112.                 filters : 'min max',     

  113.                 data : {     

  114.                     min : 2,     

  115.                     max : 3     

  116.                 },     

  117.                 errors : {     

  118.                     min : 'Check at least <strong>2strong> options.',     

  119.                     max : 'No more than <strong>3strong> options allowed.'     

  120.                 }     

  121.             }     

  122.             */     

  123.         }     

  124.     };     

  125.     $('#getTelCode').click(function() {     

  126.         var telephone = document.getElementById("telephone").value;   //手机号码     

  127.         if (telephone == null || telephone == ""){     

  128.             alert("手机号码不能为空!");     

  129.         }     

  130.         else{     

  131.             $.ajax({     

  132.                 type : "GET",     

  133.                 dataType : "json",     

  134.                 url : "../api/getTelCode?telephone="+ telephone,     

  135.                 success : function(msg) {     

  136.                 },     

  137.                 error : function(e) {     

  138.                     alert("获取手机校验码失败!" + e);     

  139.                                                                      ;

  140. var $

    myform
  141. = $('#my-form').idealforms(options).data( 'idealforms');
  142. $('#submit').click(function() {
  143. Username
  144. var

    password
  145. =
  146. document

    .getElementById("pass").value; //Password

  147. var email = document .getElementById("email").value; //Email

  148. var telephone = document.getElementById("telephone").value; //Mobile phone number

  149. var vCode = document.getElementById("vCode").value; //Company V code                                                                                                                                                                                                                                          ​

    =
  150. document
  151. .getElementById("trueName"). value; //Real name

    "../api/usersRegister?username

    =
  152. "+ username +"
  153. password="+ password +"email

    =
  154. "+email +"
  155. telephone="+telephone +"vCode

    =
  156. "+vCode +"
  157. telCode =" + telCode +"trueName

    ="+ trueName,
  158. :8083/uimcardprj/share/meun.
  159. jsp
  160.                                                                                  / Get the directory after the host address, such as: uimcardprj/share/meun.jsp

  161. var

    pathName = window.document.location.pathname; "

  162.             var localhostPaht = curWwwPath

    .sub
  163. string
  164. (0, pos);                                                                

    pathName

    .
  165. substr
  166. ing(0, pathName. substr(1).indexOf('/') + 1);

    alert("Registration successful!"); ​​​​​​​​

  167. }
  168. });
  169. }); $('#reset').click(function() {

  170. $myform.reset().fresh().focusFirst(); });

  171. < ;/
  172. script

    >
  173.                                                                                                       
  174. >

    ​​​​

  175. 2.jq input verification: jquery.idealforms.js

  176. The initial version of this js verification comes from Cedric Ruiz, I modified it slightly.

  177. The rules for partial verification are as follows:
  178. required: 'This is required.'

  179. number: 'Must be a number.',
  180. digits: 'Must be a unique number.'

  181. name: ' It must be at least 3 characters long and can only contain letters.'
  182. username: 'The minimum username is 5 characters and the maximum is 30 characters. Please use English letters, numbers, Chinese and underscores. The first character of the username must be a letter, Numbers and Chinese characters cannot be full numbers. The maximum length of Chinese characters is 21 characters. '

  183. pass: 'The password must be between 6-15 digits and contain at least one number, one uppercase letter and one lowercase letter. '
  184. strongpass: 'Must be at least 8 characters long, contain at least one uppercase letter and one lowercase letter and a number or

    special character
  185. .'
  186. email: 'Must be a valid email address. (Example: '">user@gmail.com)'phone: 'must be a valid mobile phone number. (Example: 18723101212)' The following is the entire code file:

  187. XML/HTML CodeCopy content to clipboard

    1. /*--------------------------------------------------------------------------    

    2.   jq-idealforms 2.1    

    3.   * Author: Cedric Ruiz    

    4.   * License: GPL or MIT    

    5.   * Demo: http://elclanrs.github.com/jq-idealforms/    

    6.   *    

    7. --------------------------------------------------------------------------*/     

    8. ;(function ( $, window, document, undefined ) {     

    9.   'use strict';     

    10.   // Global Ideal Forms namespace     

    11.   $.idealforms = {}     

    12.   $.idealforms.filters = {}     

    13.   $.idealforms.errors = {}     

    14.   $.idealforms.flags = {}     

    15.   $.idealforms.ajaxRequests = {}     

    16. /*--------------------------------------------------------------------------*/     

    17. /**    

    18.  * @namespace A chest for various Utils    

    19.  */     

    20. var Utils = {     

    21.   /**    

    22.    * Get width of widest element in the collection.    

    23.    * @memberOf Utils    

    24.    * @param {jQuery object} $elms    

    25.    * @returns {number}    

    26.    */     

    27.   getMaxWidth: function( $elms ) {     

    28.     var maxWidth = 0     

    29.     $elms.each(function() {     

    30.       var width = $(this).outerWidth()     

    31.       if ( width > maxWidth ) {     

    32.         maxWidth = width     

    33.       }     

    34.     })     

    35.     return maxWidth     

    36.   },     

    37.   /**    

    38.    * Hacky way of getting LESS variables    

    39.    * @memberOf Utils    

    40.    * @param {string} name The name of the LESS class.    

    41.    * @param {string} prop The css property where the data is stored.    

    42.    * @returns {number, string}    

    43.    */     

    44.   getLessVar: function( name, prop ) {     

    45.     var value = $('<p class="' + name + '">p>').hide().appendTo('body').css( prop )     

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

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

    48.   },     

    49.   /**    

    50.    * Like ES5 Object.keys    

    51.    */     

    52.   getKeys: function( obj ) {     

    53.     var keys = []     

    54.     for(var key in obj) {     

    55.       if ( obj.hasOwnProperty( key ) ) {     

    56.         keys.push( key )     

    57.       }     

    58.     }     

    59.     return keys     

    60.   },     

    61.   // Get lenght of an object     

    62.   getObjSize: function( obj ) {     

    63.     var size = 0, key;     

    64.     for ( key in obj ) {     

    65.       if ( obj.hasOwnProperty( key ) ) {     

    66.         size++;     

    67.       }     

    68.     }     

    69.     return size;     

    70.   },     

    71.   isFunction: function( obj ) {     

    72.     return typeof obj === nbsp;'function'     

    73.   },     

    74.   isRegex: function( obj ) {     

    75.     return obj instanceof RegExp     

    76.   },     

    77.   isString: function( obj ) {     

    78.     return typeof obj === 'string'     

    79.   },     

    80.   getByNameOrId: function( str ) {     

    81.     var $el = $('[name="'+ str +'"]').length     

    82.       ? $('[name="'+ str +'"]') // by name     

    83.       : $('#'+ str) // by id     

    84.     return $el.length     

    85.       ? $el     

    86.       : $.error('The field "'+ str + '" doesn't exist.')     

    87.   },     

    88.   getFieldsFromArray: function( fields ) {     

    89.     var f = []     

    90.     for ( var i = 0l = fields.length; i < l; i++ ) {     

    91.       f.push( Utils.getByNameOrId( fields[i] ).get(0) )     

    92.     }     

    93.     return $( f )     

    94.   },     

    95.   convertToArray: function( obj ) {     

    96.     return Object.prototype.toString.call( obj ) === '[object Array]'     

    97.       ? obj : [ obj ]     

    98.   },     

    99.   /**    

    100.    * Determine type of any Ideal Forms element    

    101.    * @param $input jQuery $input object    

    102.    */     

    103.   getIdealType: function( $el ) {     

    104.     var type = $el.attr('type') || $el[0].tagName.toLowerCase()     

    105.     return (     

    106.       /(text|password|email|number|search|url|tel|textarea)/.test( type ) && 'text' ||     

    107.       /file/.test( type ) && 'file' ||     

    108.       /select/.test( type ) && 'select' ||     

    109.       /(radio|checkbox)/.test( type ) && 'radiocheck' ||     

    110.       /(button|submit|reset)/.test( type ) && 'button' ||     

    111.       /hd/.test( type ) && 'heading' ||     

    112.       /hr/.test( type ) && 'separator' ||     

    113.       /hidden/.test( type ) && 'hidden'     

    114.     )     

    115.   },     

    116.   /**    

    117.    * Generates an input    

    118.    * @param name `name` attribute of the input    

    119.    * @param type `type` or `tagName` of the input    

    120.    */     

    121.   makeInput: function( name, value, type, list, placeholder ) {     

    122.     var markup, items = [], item, i, len     

    123.     function splitValue( str ) {     

    124.       var item, value, arr     

    125.       if ( /::/.test( str ) ) {     

    126.         arr = str.split('::')     

    127.         item = arr[ 0 ]     

    128.         value = arr[ 1 ]     

    129.       } else {     

    130.         item = value = str     

    131.       }     

    132.       return { item: item, value: value }     

    133.     }     

    134.     // Text & file     

    135.     if ( /^(text|password|email|number|search|url|tel|file|hidden)$/.test(type) )     

    136.       markup = '+     

    137.         'type="'+ type +'" '+     

    138.         'id="'+ name +'" '+     

    139.         'name="'+ name +'" '+     

    140.         'value="'+ value +'" '+     

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

    142.         '/>'     

    143.     // Textarea     

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

    145.       markup = '+ name +'" name="'+ name +'" value="'+ value +'">textarea>'     

    146.     }     

    147.     // Select     

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

    149.       items = []     

    150.       for ( i = 0len = list.length; i < len; i++ ) {     

    151.         item = splitValue( list[ i ] ).item     

    152.         value = splitValue( list[ i ] ).value     

    153.         items.push('<option value="'+ value +'">'+ item +'option>')     

    154.       }     

    155.       markup =     

    156.         '+ name +'" name="'+ name +'">'+     

    157.           items.join('') +     

    158.         'select>'     

    159.     }     

    160.     // Radiocheck     

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

    162.       items = []     

    163.       for ( i = 0len = list.length; i < len; i++ ) {     

    164.         item = splitValue( list[ i ] ).item     

    165.         value = splitValue( list[ i ] ).value     

    166.         items.push(     

    167.           '<label>'+     

    168.             '<input type="'+ type +'" name="'+ name +'" value="'+ value +'" />'+     

    169.             item +     

    170.           'label>'     

    171.         )     

    172.       }     

    173.       markup = items.join('')     

    174.     }     

    175.     return markup     

    176.   }     

    177. }     

    178. /**    

    179.  * Custom tabs for Ideal Forms    

    180.  */     

    181. $.fn.idealTabs = function (container) {     

    182.   var     

    183.   // Elements     

    184.   $contents = this,     

    185.   $containercontainer = container,     

    186.   $wrapper = $('<ul class="ideal-tabs-wrap"/>'),     

    187.   $tabs = (function () {     

    188.     var tabs = []     

    189.     $contents.each(function () {     

    190.       var name = $(this).attr('name')     

    191.       var html =     

    192.         ''+     

    193.           '<span>' + name + 'span>'+     

    194.           '<i class="ideal-tabs-tab-counter ideal-tabs-tab-counter-zero">0i>'+     

    195.         'li>'     

    196.       tabs.push(html)     

    197.     })     

    198.     return $(tabs.join(''))     

    199.   }()),     

    200.   Actions = {     

    201.     getCurIdx: function () {     

    202.       return $tabs     

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

    204.         .index()     

    205.     },     

    206.     getTabIdxByName: function (name) {     

    207.       var re = new RegExp(name, 'i')     

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

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

    210.       })     

    211.       return $tab.index()     

    212.     }     

    213.   },     

    214.   /**    

    215.    * Public methods    

    216.    */     

    217.   Methods = {     

    218.     /**    

    219.      * Switch tab    

    220.      */     

    221.     switchTab: function (nameOrIdx) {     

    222.       var idx = Utils.isString(nameOrIdx)     

    223.         ? Actions.getTabIdxByName(nameOrIdx)     

    224.         : nameOrIdx     

    225.       $tabs.removeClass('ideal-tabs-tab-active')     

    226.       $tabs.eq(idx).addClass('ideal-tabs-tab-active')     

    227.       $contents.hide().eq(idx).show()     

    228.     },     

    229.     nextTab: function () {     

    230.       var idx = Actions.getCurIdx() + 1     

    231.       idx > $tabs.length - 1     

    232.         ? Methods.firstTab()     

    233.         : Methods.switchTab(idx)     

    234.     },     

    235.     prevTab: function () {     

    236.       Methods.switchTab(Actions.getCurIdx() - 1)     

    237.     },     

    238.     firstTab: function () {     

    239.       Methods.switchTab(0)     

    240.     },     

    241.     lastTab: function () {     

    242.       Methods.switchTab($tabs.length - 1)     

    243.     },     

    244.     updateCounter: function (nameOrIdx, text) {     

    245.       var idx = !isNaN(nameOrIdx) ? nameOrIdx : Actions.getTabIdxByName(name),     

    246.           $counter = $tabs.eq(idx).find('.ideal-tabs-tab-counter')     

    247.       $counter.removeClass('ideal-tabs-tab-counter-zero')     

    248.       if (!text) {     

    249.         $counter.addClass('ideal-tabs-tab-counter-zero')     

    250.       }     

    251.       $counter.html(text)     

    252.     }     

    253.   }     

    254.   // Attach methods     

    255.   for (var m in Methods)     

    256.     $contents[m] = Methods[m]     

    257.   // Init     

    258.   $tabs.first()     

    259.     .addClass('ideal-tabs-tab-active')     

    260.     .end()     

    261.     .click(function () {     

    262.       var name = $(this).text()     

    263.       $contents.switchTab(name)     

    264.     })     

    265.   // Insert in DOM & Events     

    266.   $wrapper.append($tabs).appendTo($container)     

    267.   $contents.addClass('ideal-tabs-content')     

    268.   $contents.each(function () {     

    269.     var $this = $(this), name = $(this).attr('name')     

    270.     $this.data('ideal-tabs-content-name', name)     

    271.       .removeAttr('name')     

    272.   })     

    273.   $contents.hide().first().show() // Start fresh     

    274.   return $contents     

    275. }     

    276. /**    

    277.  * A custom <select> menu jQuery plugin    

    278.  * @example `$('select').idealSelect()`    

    279.  */     

    280. $.fn.idealSelect = function () {     

    281.   return this.each(function () {     

    282.     var     

    283.     $select = $(this),     

    284.     $options&nbnbsp;= $select.find('option')     

    285.     /**    

    286.      * Generate markup and return elements of custom select    

    287.      * @memberOf $.fn.toCustomSelect    

    288.      * @returns {object} All elements of the new select replacement    

    289.      */     

    290.     var idealSelect = (function () {     

    291.       var     

    292.       $wrap = $('<ul class="ideal-select '+ $select.attr('name') +'"/>'),     

    293.       $menu = $(     

    294.         '<li><span class="ideal-select-title">' +     

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

    296.         'span>li>'     

    297.       ),     

    298.       items = (function () {     

    299.         var items = []     

    300.         $options.each(function () {     

    301.           var $this = $(this)     

    302.           items.push('<li class="ideal-select-item">' + $this.text() + 'li>')     

    303.         })     

    304.         return items     

    305.       }())     

    306.       $menu.append('<ul class="ideal-select-sub">' + items.join('') + 'ul>')     

    307.       $wrap.append($menu)     

    308.       return {     

    309.         select: $wrap,     

    310.         title: $menu.find('.ideal-select-title'),     

    311.         sub: $menu.find('.ideal-select-sub'),     

    312.         items: $menu.find('.ideal-select-item')     

    313.       }     

    314.     }())     

    315.     /**    

    316.      * @namespace Methods of custom select    

    317.      * @memberOf $.fn.toCustomSelect    

    318.      */     

    319.     var Actions = {     

    320.       getSelectedIdx: function () {     

    321.         return idealSelect.items     

    322.           .filter('.ideal-select-item-selected').index()     

    323.       },     

    324.       /**    

    325.        * @private    

    326.        */     

    327.       init: (function () {     

    328.         $select.css({     

    329.           position: 'absolute',     

    330.           left: '-9999px'     

    331.         })     

    332.         idealSelect.sub.hide()     

    333.         idealSelect.select.insertAfter($select)     

    334.         idealSelect.select.css(     

    335.           'min-width',     

    336.           Utils.getMaxWidth(idealSelect.items)     

    337.         )     

    338.         idealSelect.items     

    339.           .eq($options.filter(':selected').index())     

    340.           .addClass('ideal-select-item-selected')     

    341.       }()),     

    342.       noWindowScroll: function (e) {     

    343.         if (e.which === 40 || e.which === 38 || e.which === 13) {     

    344.           e.preventDefault()     

    345.         }     

    346.       },     

    347.       // Fix loosing focus when scrolling     

    348.       // and selecting item with keyboard     

    349.       focusHack: function () {     

    350.         setTimeout(function () {     

    351.           $select.trigger('focus')     

    352.         }, 1)     

    353.       },     

    354.       focus: function () {     

    355.         idealSelect.select.addClass('ideal-select-focus')     

    356.         $(document).on('keydown.noscroll', Actions.noWindowScroll)     

    357.       },     

    358.       blur: function () {     

    359.         idealSelect.select     

    360.           .removeClass('ideal-select-open ideal-select-focus')     

    361.         $(document).off('.noscroll')     

    362.       },     

    363.       scrollIntoView: function (dir) {     

    364.         var     

    365.         $selected = idealSelect.items.filter('.ideal-select-item-selected'),     

    366.         itemHeight = idealSelect.items.outerHeight(),     

    367.         menuHeight = idealSelect.sub.outerHeight(),     

    368.         isInView = (function () {     

    369.           // relative position to the submenu     

    370.           var elPos = $selected.position().top + itemHeight     

    371.           return dir === 'down'     

    372.             ? elPos <= menuHeight     

    373.             : elPos > 0     

    374.         }())     

    375.         if (!isInView) {     

    376.           itemHeight = (dir === 'down')     

    377.             ? itemHeight // go down     

    378.             : -itemHeight // go up     

    379.           idealSelect.sub     

    380.             .scrollTop(idealSelect.sub.scrollTop() + itemHeight)     

    381.         }     

    382.       },     

    383.       scrollToItem: function () {     

    384.         var idx = Actions.getSelectedIdx(),     

    385.             height = idealSelect.items.outerHeight(),     

    386.             nItems = idealSelect.items.length,     

    387.             allHeight = height * nItems,     

    388.             curHeight = height * (nItems - idx)     

    389.         idealSelect.sub.scrollTop(allHeight - curHeight)     

    390.       },     

    391.       showMenu: function () {     

    392.         idealSelect.sub.fadeIn('fast')     

    393.         idealSelect.select.addClass('ideal-select-open')     

    394.         Actions.select(Actions.getSelectedIdx())     

    395.         Actions.scrollToItem()     

    396.       },     

    397.       hideMenu: function () {     

    398.         idealSelect.sub.hide()     

    399.         idealSelect.select.removeClass('ideal-select-open')     

    400.       },     

    401.       select: function (idx) {     

    402.         idealSelect.items     

    403.           .removeClass('ideal-select-item-selected')     

    404.         idealSelect.items     

    405.           .eq(idx).addClass('ideal-select-item-selected')     

    406.       },     

    407.       change: function (idx) {     

    408.         var text = idealSelect.items.eq(idx).text()     

    409.         Actions.select(idx)     

    410.         idealSelect.title.text(text)     

    411.         $options.eq(idx).prop('selected', true)     

    412.         $select.trigger('change')     

    413.       },     

    414.       keydown: function (key) {     

    415.         var     

    416.         idx = Actions.getSelectedIdx(),     

    417.         isMenu = idealSelect.select.is('.ideal-select-menu'),     

    418.         isOpen = idealSelect.select.is('.ideal-select-open')     

    419.         /**    

    420.          * @namespace Key pressed    

    421.          */     

    422.         var keys = {     

    423.           9: function () { // TAB     

    424.             if (isMenu) {     

    425.               Actions.blur()     

    426.               Actions.hideMenu()     

    427.             }     

    428.           },     

    429.           13: function () { // ENTER     

    430.             if (isMenu)     

    431.               isOpen     

    432.                 ? Actions.hideMenu()     

    433.                 : Actions.showMenu()     

    434.             Actions.change(idx)     

    435.           },     

    436.           27: function () { // ESC     

    437.             if (isMenu) Actions.hideMenu()     

    438.           },     

    439.           40: function () { // DOWN     

    440.             if (idx < $options.length - 1) {     

    441.               isOpen     

    442.                 ? Actions.select(idx + 1)     

    443.                 : Actions.change(idx + 1)     

    444.             }     

    445.             Actions.scrollIntoView('down')     

    446.           },     

    447.           38: function () { // UP     

    448.             if (idx > 0) {     

    449.               isOpen     

    450.                 ? Actions.select(idx - 1)     

    451.                 : Actions.change(idx - 1)     

    452.             }     

    453.             Actions.scrollIntoView('up')     

    454.           },     

    455.           'default': function () { // Letter     

    456.             var     

    457.             letter = String.fromCharCode(key),     

    458.             $matches = idealSelect.items     

    459.               .filter(function () {     

    460.                 return /^w+$/i.test( letter ) && // not allow modifier keys ( ctrl, cmd, meta, super... )     

    461.                   new RegExp('^' + letter, 'i').test( $(this).text() ) // find first match     

    462.               }),     

    463.             nMatches = $matches.length,     

    464.             counter = idealSelect.select.data('counter') + 1 || 0,     

    465.             curKey = idealSelect.select.data('key') || key,     

    466.             newIdx = $matches.eq(counter).index()     

    467.             if (!nMatches) // No matches     

    468.               return false     

    469.             // If more matches with same letter     

    470.             if (curKey === key) {     

    471.               if (counter < nMatches) {     

    472.                 idealSelect.select.data('counter', counter)     

    473.               }     

    474.               else {     

    475.                 idealSelect.select.data('counter', 0)     

    476.                 newIdx = $matches.eq(0).index()     

    477.               }     

    478.             }     

    479.             // If new letter     

    480.             else {     

    481.              &nnbsp;idealSelect.select.data('counter', 0)     

    482.               newIdx = $matches.eq(0).index()     

    483.             }     

    484.             if (isOpen)     

    485.               Actions.select(newIdx)     

    486.             else     

    487.               Actions.change(newIdx)     

    488.             idealSelect.select.data('key', key)     

    489.             Actions.scrollToItem()     

    490.             Actions.focusHack()     

    491.           }     

    492.         }     

    493.         keys[key]     

    494.           ? keys[key]()     

    495.           : keys['default']()     

    496.       }     

    497.     }     

    498.     /**    

    499.      * @namespace Holds all events of custom select for "menu mode" and "list mode"    

    500.      * @memberOf $.fn.toCustomSelect    

    501.      */     

    502.     var events = {     

    503.       focus: Actions.focus,     

    504.       'blur.menu': function () {     

    505.         Actions.blur()     

    506.         Actions.hideMenu()     

    507.       },     

    508.       'blur.list': function () {     

    509.         Actions.blur()     

    510.       },     

    511.       keydown: function (e) {     

    512.         Actions.keydown(e.which)     

    513.       },     

    514.       'clickItem.menu': function () {     

    515.         Actions.change($(this).index())     

    516.         Actions.hideMenu()     

    517.       },     

    518.       'clickItem.list': function () {     

    519.         Actions.change($(this).index())     

    520.       },     

    521.       'clickTitle.menu': function () {     

    522.         Actions.focus()     

    523.         Actions.showMenu()     

    524.         $select.trigger('focus')     

    525.       },     

    526.       'hideOutside.menu': function () {     

    527.         $select.off('blur.menu')     

    528.         $(document).on('mousedown.ideal', function (evt) {     

    529.           if (!$(evt.target).closest(idealSelect.select).length) {     

    530.             $(document).off('mousedown.ideal')     

    531.             $select.on('blur.menu', events['blur.menu'])     

    532.           } else {     

    533.             Actions.focusHack()     

    534.           }     

    535.         })     

    536.       },     

    537.       'mousedown.list': function () {     

    538.         Actions.focusHack()     

    539.       }     

    540.     }     

    541.     // Reset events     

    542.     var disableEvents = function () {     

    543.       idealSelect.select.removeClass('ideal-select-menu ideal-select-list')     

    544.       $select.off('.menu .list')     

    545.       idealSelect.items.off('.menu .list')     

    546.       idealSelect.select.off('.menu .list')     

    547.       idealSelect.title.off('.menu .list')     

    548.     }     

    549.     // Menu mode     

    550.     idealSelect.select.on('menu', function () {     

    551.       disableEvents()     

    552.       idealSelect.select.addClass('ideal-select-menu')     

    553.       Actions.hideMenu()     

    554.       $select.on({     

    555.         'blur.menu': events['blur.menu'],     

    556.         'focus.menu': events.focus,     

    557.         'keydown.menu': events.keydown     

    558.       })     

    559.       idealSelect.select.on('mousedown.menu', events['hideOutside.menu'])     

    560.       idealSelect.items.on('click.menu', events['clickItem.menu'])     

    561.       idealSelect.title.on('click.menu', events['clickTitle.menu'])     

    562.     })     

    563.     // List mode     

    564.     idealSelect.select.on('list', function () {     

    565.       disableEvents()     

    566.       idealSelect.select.addClass('ideal-select-list')     

    567.       Actions.showMenu()     

    568.       $select.on({     

    569.         'blur.list': events['blur.list'],     

    570.         'focus.list': events.focus,     

    571.         'keydown.list': events.keydown     

    572.       })     

    573.       idealSelect.select.on('mousedown.list', events['mousedown.list'])     

    574.       idealSelect.items.on('mousedown.list', events['clickItem.list'])     

    575.     })     

    576.     $select.keydown(function (e) {     

    577.       // Prevent default keydown event     

    578.       // to avoid bugs with Ideal Select events     

    579.       if (e.which !== 9) e.preventDefault()     

    580.     })     

    581.     // Reset     

    582.     idealSelect.select.on('reset', function(){     

    583.       Actions.change(0)     

    584.     })     

    585.     idealSelect.select.trigger('menu') // Default to "menu mode"     

    586.   })     

    587. }     

    588. /*    

    589.  * idealRadioCheck: jQuery plguin for checkbox and radio replacement    

    590.  * Usage: $('input[type=checkbox], input[type=radio]').idealRadioCheck()    

    591.  */     

    592. $.fn.idealRadioCheck = function() {     

    593.   return this.each(function() {     

    594.     var $this = $(this)     

    595.     var $span = $('<span/>')     

    596.     $span.addClass( 'ideal-'+ ( $this.is(':checkbox') ? 'check' : 'radio' ) )     

    597.     $this.is(':checked') && $span.addClass('checked') // init     

    598.     $span.insertAfter( $this )     

    599.     $this.parent('label').addClass('ideal-radiocheck-label')     

    600.       .attr('onclick', '') // Fix clicking label in iOS     

    601.     $this.css({ position: 'absolute', left: '-9999px' }) // hide by shifting left     

    602.     // Events     

    603.     $this.on({     

    604.       change: function() {     

    605.         var $this = $(this)     

    606.         if ( $this.is('input[type="radio"]') ) {     

    607.           $this.parent().siblings('label').find('.ideal-radio').removeClass('checked')     

    608.         }     

    609.         $span.toggleClass( 'checked', $this.is(':checked') )     

    610.       },     

    611.       focus: function() { $span.addClass('focus') },     

    612.       blur: function() { $span.removeClass('focus') },     

    613.       click: function() { $(this).trigger('focus') }     

    614.     })     

    615.   })     

    616. }     

    617. ;(function( $ ) {     

    618.   // Browser supports HTML5 multiple file?     

    619.   var multipleSupport = typeof $('<input/>')[0].multiple !== 'undefined',     

    620.       isIE = /msie/i.test( navigator.userAgent )     

    621.   $.fn.idealFile = function() {     

    622.     return this.each(function() {     

    623.       var $file = $(this).addClass('ideal-file'), // the original file input     

    624.           // label that will be used for IE hack     

    625.           $wrap = $('<div class="ideal-file-wrap">'),     

    626.           $input = $('<input type="text" class="ideal-file-filename" />'),     

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

    628.           $button = $('<button type="button" class="ideal-file-upload">Openbutton>'),     

    629.           // Hack for IE     

    630.           $label = $('<label class="ideal-file-upload" for="'+ $file[0].id +'">Openlabel>')     

    631.       // Hide by shifting to the left so we     

    632.       // can still trigger events     

    633.       $file.css({     

    634.         position: 'absolute',     

    635.         left: '-9999px'     

    636.       })     

    637.       $wrap.append( $input, ( isIE ? $label : $button ) ).insertAfter( $file )     

    638.       // Prevent focus     

    639.       $file.attr('tabIndex', -1)     

    640.       $button.attr('tabIndex', -1)     

    641.       $button.click(function () {     

    642.         $file.focus().click() // Open dialog     

    643.       })     

    644.       $file.change(function() {     

    645.         var files = [], fileArr, filename     

    646.         // If multiple is supported then extract     

    647.         // all filenames from the file array     

    648.         if ( multipleSupport ) {     

    649.           fileArr = $file[0].files     

    650.           for ( var i = 0len = fileArr.length; i < len; i++ ) {     

    651.             files.push( fileArr[i].name )     

    652.           }     

    653.           filename = files.join(', ')     

    654.         // If not supported then just take the value     

    655.         // and remove the path to just show the filename     

    656.         } else {     

    657.           filename = $file.val().split('\').pop()     

    658.         }     

    659.         $input.val( filename ) // Set the value     

    660.           .attr( 'title', filename ) // Show filename in title tootlip     

    661.       })     

    662.       $input.on({     

    663.         focus: function () { $file.trigger('change') },     

    664.         blur: function () { $file.trigger('blur') },     

    665.         keydown: function( e ) {     

    666.           if ( e.which === 13 ) { // Enter     

    667.             if ( !isIE ) { $file.trigger('click') }     

    668.           } else if ( e.which === 8 || e.which === 46 ) { // Backspace & Del     

    669.             // On some browsers the value is read-only     

    670.             // with this trick we remove the old input and add     

    671.             // a clean clone with all the original events attached     

    672.             $file.replaceWith( $file = $file.val('').clone( true ) )     

    673.             $file.trigger('change')     

    674.             $input.val('')     

    675.           } else if ( e.which === 9 ){ // TAB     

    676.             return     

    677.           } else { // All other keys     

    678.             return false     

    679.           }     

    680.         }     

    681.       })     

    682. })

    683. }

    684. }( jQuery ))

    685. /**    

    686.  * @namespace Errors    

    687.  * @locale en    

    688.  */

    689. $ .idealforms.errors = {

    690. required: 'This is required.',

    691. number: 'Must be a number.',

    692. digits: 'Must be a unique number.',

    693. name: 'Must be at least 3 The character is long, and it can only contain the letters. ',

    694. username:' The shortest user name is 5 digits, and the longest 30 bits. Please use English letters, numbers, Chinese, and subordinate lines. Chinese, it cannot be all numbers. The maximum length of Chinese characters is 21 characters.',

    695. pass: 'The password must be between 6-15 digits and contain at least one number, one uppercase letter and one lowercase letter .',  

    696. strongpass: 'Must be at least 8 characters long, contain at least one uppercase letter and one lowercase letter and one number or special character.',  

    697. email: 'Must be a valid email address . <em>(Example: user@gmail.com)em>',

    698. phone: 'Must be a valid mobile phone number. <em>(Example: 18723101212)em>',

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

    700. url: 'Must be a valid URL. & lt;em> ;(e.g. www.google.com)em>',

    701. minChar: 'Must be at least 0} strong> characters long.', minOption: 'Check at least strong

      > ;
    702. options.',
    703. maxChar: 'No more than <strong>{0}strong

      >

    704. characters long.',
    705. maxOption: 'No more than <strong>{0}strong

      >

    706. options allowed.',
    707. range : 'Must be a number between {0} and {1}.', date: 'Must be a valid date. >',

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

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

    710.   excludeOption: '{0}',     

    711.   equalto: 'Must be the same value as <strong>"{0}"strong>',     

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

    713.   ajaxSuccess: '<strong>{0}strong> is not available.',     

    714.   ajaxError: 'Server error...'     

    715. }     

    716. /**    

    717.  * Get all default filters    

    718.  * @returns object    

    719.  */     

    720. var getFilters = function() {     

    721.   var filters = {     

    722.     required: {     

    723.       regex: /.+/,     

    724.       error: $.idealforms.errors.required     

    725.     },     

    726.     number: {     

    727.       regex: function( i, v ) { return !isNaN(v) },     

    728.       error: $.idealforms.errors.number     

    729.     },     

    730.     digits: {     

    731.       regex: /^d+$/,     

    732.       error: $.idealforms.errors.digits     

    733.     },     

    734.     name: {     

    735.       regex: /^[A-Za-z]{3,}$/,     

    736.       error: $.idealforms.errors.name     

    737.     },     

    738.     username: {     

    739.       regex: /^[a-z](?=[w.]{4,30}$)w*.?w*$/i,     

    740.       error: $.idealforms.errors.username     

    741.     },     

    742.     pass: {     

    743.       regex: /(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{6,}/,     

    744.       error: $.idealforms.errors.pass     

    745.     },     

    746.     strongpass: {     

    747.       regex: /(?=^.{8,}$)((?=.*d)|(?=.*W+))(?![.n])(?=.*[A-Z])(?=.*[a-z]).*$/,     

    748.       error: $.idealforms.errors.strongpass     

    749.     },     

    750.     email: {     

    751.       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})?$/,     

    752.       error: $.idealforms.errors.email     

    753.     },     

    754.     phone: {     

    755.       //regex: /^((13[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$/,     

    756.       regex: /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/,     

    757.       error: $.idealforms.errors.phone     

    758.     },     

    759.     zip: {     

    760.       regex: /^d{5}$|^d{5}-d{4}$/,     

    761.       error: $.idealforms.errors.zip     

    762.     },     

    763.     url: {     

    764.       regex: /^(?:(ftp|http|https)://)?(?:[w-]+.)+[a-z]{2,6}([:/?#].*)?$/i,     

    765.       error: $.idealforms.errors.url     

    766.     },     

    767.     min: {     

    768.       regex: function( input, value ) {     

    769.         var $inputinput = input.input,     

    770.             min = input.userOptions.data.min,     

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

    772.         if ( isRadioCheck ) {     

    773.           this.error = $.idealforms.errors.minOption.replace( '{0}', min )     

    774.           return $input.filter(':checked').length >= min     

    775.         }     

    776.         this.error = $.idealforms.errors.minChar.replace( '{0}', min )     

    777.         return value.length >= min     

    778.       }     

    779.     },     

    780.     max: {     

    781.       regex: function( input, value ) {     

    782.         var $inputinput = input.input,     

    783.             max = input.userOptions.data.max,     

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

    785.         if ( isRadioCheck ) {     

    786.           this.error = $.idealforms.errors.maxOption.replace( '{0}', max )     

    787.           return $input.filter(':checked').length <= max     

    788.         }     

    789.         this.error = $.idealforms.errors.maxChar.replace( '{0}', max )     

    790.         return value.length <= max     

    791.       }     

    792.     },     

    793.     range: {     

    794.       regex: function( input, value ) {     

    795.         var range = input.userOptions.data.range,     

    796.             val = +value     

    797.         this.error = $.idealforms.errors.range     

    798.           .replace( '{0}', range[0] )     

    799.           .replace( '{1}', range[1] )     

    800.         return val >= range[0] && val <= range[1]     

    801.       }     

    802.     },     

    803.     date: {     

    804.       regex: function( input, value ) {     

    805.         var     

    806.         userFormat =     

    807.           input.userOptions.data && input.userOptions.data.date     

    808.             ? input.userOptions.data.date     

    809.             : 'mm/dd/yyyy', // default format     

    810.         delimiter = /[^mdy]/.exec( userFormat )[0],     

    811.         theFormat = userFormat.split(delimiter),     

    812.         theDate = value.split(delimiter),     

    813.         isDate = function( date, format ) {     

    814.           var m, d, y     

    815.           for ( var i = 0len = format.length; i < len; i++ ) {     

    816.             if ( /m/.test( format[i]) ) m = date[i]     

    817.             if ( /d/.test( format[i]) ) d = date[i]     

    818.             if ( /y/.test( format[i]) ) y = date[i]     

    819.           }     

    820.           return (     

    821.             m > 0 && m < 13 &&     

    822.             y && y.length === 4 &&     

    823.             d > 0 && d <= ( new Date( y, m, 0 ) ).getDate()     

    824.           )     

    825.         }     

    826.         this.error = $.idealforms.errors.date.replace( '{0}', userFormat )     

    827.         return isDate( theDate, theFormat )     

    828.       }     

    829.     },     

    830.     dob: {     

    831.       regex: function( input, value ) {     

    832.         var     

    833.         userFormat =     

    834.           input.userOptions.data && input.userOptions.data.dob     

    835.             ? input.userOptions.data.dob     

    836.             : 'mm/dd/yyyy', // default format     

    837.         // Simulate a date input     

    838.         dateInput = {     

    839.           input: input.input,     

    840.           userOptions: {     

    841.             data: { date: userFormat }     

    842.           }     

    843.         },     

    844.         // Use internal date filter to validate the date     

    845.         isDate = filters.date.regex( dateInput, value ),     

    846.         // DOB     

    847.         theYear = /d{4}/.exec( value ),     

    848.         maxYear = new Date().getFullYear(), // Current year     

    849.         minYear = maxYear - 100     

    850.         this.error = $.idealforms.errors.dob     

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

    852.       }     

    853.     },     

    854.     exclude: {     

    855.       regex: function( input, value ) {     

    856.         var $inputinput = input.input,     

    857.             exclude = input.userOptions.data.exclude,     

    858.             isOption = $input.is('[type="checkbox"], [type="radio"], select')     

    859.         this.error = isOption     

    860.           ? $.idealforms.errors.excludeOption.replace( '{0}', value )     

    861.           : this.error = $.idealforms.errors.exclude.replace( '{0}', value )     

    862.         return $.inArray( value, exclude ) === -1     

    863.       }     

    864.     },     

    865.     equalto: {     

    866.       regex: function( input, value ) {     

    867.         var $equals = $( input.userOptions.data.equalto ),     

    868.             $inputinput = input.input,     

    869.             name = $equals.attr('name') || $equals.attr('id'),     

    870.             isValid = $equals.parents('.ideal-field')     

    871.               .filter(function(){ return $(this).data('ideal-isvalid') === true })     

    872.               .length     

    873.         if ( !isValid ) { return false }     

    874.         this.error = $.idealforms.errors.equalto.replace( '{0}', name )     

    875.         return $input.val() === $equals.val()     

    876.       }     

    877.     },     

    878.     extension: {     

    879.       regex: function( input, value ) {     

    880.         nbsp;var files = input.input[0].files || [{ name: value }],     

    881.             extensions = input.userOptions.data.extension,     

    882.             re = new RegExp( '\.'+ extensions.join('|') +'$', 'i' ),     

    883.             valid = false     

    884.         for ( var i = 0len = files.length; i < len; i++ ) {     

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

    886.         }     

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

    888.         return valid     

    889.       }     

    890.     },     

    891.     ajax: {     

    892.       regex: function( input, value, showOrHideError ) {     

    893.         var self = this     

    894.         var $inputinput = input.input     

    895.         var userOptions = input.userOptions     

    896.         var name = $input.attr('name')     

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

    898.         var valid = false     

    899.         var customErrors = userOptions.errors && userOptions.errors.ajax     

    900.         self.error = {}     

    901.         self.error.success = customErrors && customErrors.success     

    902.           ? customErrors.success     

    903.           : $.idealforms.errors.ajaxSuccess.replace( '{0}', value )     

    904.         self.error.fail = customErrors && customErrors.error     

    905.           ? customErrors.error     

    906.           : $.idealforms.errors.ajaxError     

    907.         // Send input name as $_POST[name]     

    908.         var data = {}     

    909.         data[ name ] = $.trim( value )     

    910.         // Ajax options defined by the user     

    911.         var userAjaxOps = input.userOptions.data.ajax     

    912.         var ajaxOps = {     

    913.           type: 'post',     

    914.           dataType: 'json',     

    915.           data: data,     

    916.           success: function( resp, text, xhr ) {     

    917.           console.log(resp)     

    918.             showOrHideError( self.error.success, true )     

    919.             $input.data({     

    920.               'ideal-ajax-resp': resp,     

    921.               'ideal-ajax-error': self.error.success     

    922.             })     

    923.             $input.trigger('change') // to update counter     

    924.             $field.removeClass('ajax')     

    925.             // Run custom success callback     

    926.             if( userAjaxOps._success ) {     

    927.               userAjaxOps._success( resp, text, xhr )     

    928.             }     

    929.           },     

    930.           error: function( xhr, text, error ) {     

    931.             if ( text !== 'abort' ) {     

    932.               showOrHideError( self.error.fail, false )     

    933.               $input.data( 'ideal-ajax-error', self.error.fail )     

    934.               $field.removeClass('ajax')     

    935.               // Run custom error callback     

    936.               if ( userAjaxOps._error ) {     

    937.                 userAjaxOps._error( xhr, text, error )     

    938.               }     

    939.             }     

    940.           }     

    941.         }     

    942.         $.extend( ajaxOps, userAjaxOps )     

    943.         // Init     

    944.         $input.removeData('ideal-ajax-error')     

    945.         $input.removeData('ideal-ajax-resp')     

    946.         $field.addClass('ajax')     

    947.         // Run request and save it to be able to abort it     

    948.         // so requests don't bubble     

    949.         $.idealforms.ajaxRequests[ name ] = $.ajax( ajaxOps )     

    950.       }     

    951.     }     

    952.   }     

    953.   return filters     

    954. }     

    955. $.idealforms.flags = {     

    956.   noerror: function (i) {     

    957.     i.parent().siblings('.ideal-error').hide()     

    958.   },     

    959.   noicons: function (i) {     

    960.     i.siblings('.ideal-icon-valid, .ideal-icon-invalid').hide()     

    961.   },     

    962.   novalidicon: function (i) {     

    963.     i.siblings('.ideal-icon-valid').hide()     

    964.   },     

    965.   noinvalidicon: function (i) {     

    966.     i.siblings('.ideal-icon-invalid').hide()     

    967.   },     

    968.   noclass: function (i) {     

    969.     i.parents('.ideal-field').removeClass('valid invalid')     

    970.   },     

    971.   novalidclass: function (i) {     

    972.     i.parents('.ideal-field').removeClass('valid')     

    973.   },     

    974.   noinvalidclass: function (i) {     

    975.     i.parents('.ideal-field').removeClass('invalid')     

    976.   }     

    977. }     

    978. /*    

    979.  * Ideal Forms plugin    

    980.  */     

    981. var _defaults = {     

    982.   inputs: {},     

    983.   customFilters: {},     

    984.   customFlags: {},     

    985.   globalFlags: '',     

    986.   onSuccess: function(e) { alert('Thank you...') },     

    987.   onFail: function() { alert('Invalid!') },     

    988.   responsiveAt: 'auto',     

    989.   disableCustom: ''     

    990. }     

    991. // Constructor     

    992. var IdealForms = function( element, options ) {     

    993.   var self = this     

    994.   self.$form = $( element )     

    995.   self.opts = $.extend( {}, _defaults, options )     

    996.   self.$tabs = self.$form.find('section')     

    997.   // Set localized filters     

    998.   $.extend( $.idealforms.filters, getFilters() )     

    999.   self._init()     

    1000. }     

    1001. // Plugin     

    1002. $.fn.idealforms = function( options ) {     

    1003.   return this.each(function() {     

    1004.     if ( !$.data( this, 'idealforms' ) ) {     

    1005.       $.data( this, 'idealforms', new IdealForms( this, options ) )     

    1006.     }     

    1007.   })     

    1008. }     

    1009. // Get LESS variables     

    1010. var LessVars = {     

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

    1012. }     

    1013. /*    

    1014.  * Private Methods    

    1015.  */     

    1016. $.extend( IdealForms.prototype, {     

    1017.   _init: function() {     

    1018.     var self = this     

    1019.     var o = self.opts     

    1020.     var formElements = self._getFormElements()     

    1021.     self.$form.css( 'visibility', 'visible' )     

    1022.       .addClass('ideal-form')     

    1023.       .attr( 'novalidate', 'novalidate' ) // disable HTML5 validation     

    1024.     // Do markup     

    1025.     formElements.inputs     

    1026.       .add( formElements.headings )     

    1027.       .add( formElements.separators )     

    1028.       .each(function(){ self._doMarkup( $(this) ) })     

    1029.     // Generate tabs     

    1030.     if ( self.$tabs.length ) {     

    1031.       var $tabContainer = $('<div class="ideal-wrap ideal-tabs ideal-full-width"/>')     

    1032.       self.$form.prepend( $tabContainer )     

    1033.       self.$tabs.idealTabs( $tabContainer )     

    1034.     }     

    1035.     // Always show datepicker below the input     

    1036.     if ( jQuery.ui ) {     

    1037.       $.datepicker._checkOffset = function( a,b,c ) { return b }     

    1038.     }     

    1039.     // Add inputs specified by data-ideal     

    1040.     // to the list of user inputs     

    1041.     self.$form.find('[data-ideal]').each(function() {     

    1042.       var userInput = o.inputs[ this.name ]     

    1043.       o.inputs[ this.name ] = userInput || { filters: $(this).data('ideal') }     

    1044.     })     

    1045.    // Responsive     

    1046.     if ( o.responsiveAt ) {     

    1047.       $(window).resize(function(){ self._responsive() })     

    1048.       self._responsive()     

    1049.     }     

    1050.     // Form events     

    1051.     self.$form.on({     

    1052.       keydown: function( e ) {     

    1053.         // Prevent submit when pressing enter     

    1054.         // but exclude textareas     

    1055.         if ( e.which === 13 && e.target.nodeName !== 'TEXTAREA' ) {     

    1056.           e.preventDefault()     

    1057.         }     

    1058.       },     

    1059.       submit: function( e ) {     

    1060.         if ( !self.isValid() ) {     

    1061.           e.preventDefault()     

    1062.           o.onFail()     

    1063.           self.focusFirstInvalid()     

    1064.         } else {     

    1065.           o.onSuccess( e )     

    1066.         }     

    1067.       }     

    1068.     })     

    1069.     self._adjust()     

    1070.     self._attachEvents()     

    1071.     self.fresh() // Start fresh     

    1072.   },     

    1073.   _getFormElements: function() {     

    1074.     return {     

    1075.       inputs: this.$form.find('input, select, textarea, :button'),     

    1076.       labels: this.$form.find('div > label:first-child'),     

    1077.       text: this.$form.find('input:not([type="checkbox"], [type="radio"], [type="submit"]), textarea'),     

    1078.       select: this.$form.find('select'),     

    1079.       radiocheck: this.$form.find('input[type="radio"], input[type="checkbox"]'),     

    1080.       buttons: this.$form.find(':button'),     

    1081.       file: this.$form.find('input[type="file"]'),     

    1082.       headings: this.$form.find('h1, h2, h3, h4, h5, h6'),     

    1083.       separators: this.$form.find('hr'),     

    1084.       hidden: this.$form.find('input:hidden')     

    1085.     }     

    1086.   },     

    1087.   _getUserInputs: function() {     

    1088.     return this.$form.find('[name="'+ Utils.getKeys( this.opts.inputs ).join('"], [name="') +'"]')     

    1089.   },     

    1090.   _getTab: function( nameOrIdx ) {     

    1091.     var self = this     

    1092.     var isNumber = !isNaN( nameOrIdx )     

    1093.     if ( isNumber ) {     

    1094.       return self.$tabs.eq( nameOrIdx )     

    1095.     }     

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

    1097.       var re = new RegExp( nameOrIdx, 'i' )     

    1098.       return re.test( nbsp;$(this).data('ideal-tabs-content-name') )     

    1099.     })     

    1100.   },     

    1101.   _getCurrentTabIdx: function() {     

    1102.     return this.$tabs.index( this.$form.find('.ideal-tabs-content:visible') )     

    1103.   },     

    1104.   _updateTabsCounter: function() {     

    1105.     var self = this     

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

    1107.       var invalid = self.getInvalidInTab( i ).length     

    1108.       self.$tabs.updateCounter( i, invalid )     

    1109.     })     

    1110.   },     

    1111.   _adjust: function() {     

    1112.     var self = this     

    1113.     var o = self.opts     

    1114.     var formElements = self._getFormElements()     

    1115.     var curTab = self._getCurrentTabIdx()     

    1116.     // Autocomplete causes some problems...     

    1117.     formElements.inputs.attr('autocomplete', 'off')     

    1118.     // Show tabs to calculate dimensions     

    1119.     if ( self.$tabs.length ) { self.$tabs.show() }     

    1120.     // Adjust labels     

    1121.     var labels = formElements.labels     

    1122.     labels.removeAttr('style').width( Utils.getMaxWidth( labels ) )     

    1123.     // Adjust headings and separators     

    1124.     if ( self.$tabs.length ) {     

    1125.       this.$tabs.each(function(){     

    1126.         $( this ).find('.ideal-heading:first').addClass('first-child')     

    1127.       })     

    1128.     } else {     

    1129.       self.$form.find('.ideal-heading:first').addClass('first-child')     

    1130.     }     

    1131.     self._setDatepicker()     

    1132.     // Done calculating hide tabs     

    1133.     if ( self.$tabs.length ) {     

    1134.       self.$tabs.hide()     

    1135.       self.switchTab( curTab )     

    1136.     }     

    1137.   },     

    1138.   _setDatepicker: function() {     

    1139.     var o = this.opts     

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

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

    1142.       $datepicker.each(function() {     

    1143.         var userInput = o.inputs[ this.name ]     

    1144.         var data = userInput && userInput.data && userInput.data.date     

    1145.         var format = data ? data.replace( 'yyyy', 'yy' ) : 'mm/dd/yy'     

    1146.         $(this).datepicker({     

    1147.           dateFormat: format,     

    1148.           beforeShow: function( input ) {     

    1149.             $( input ).addClass('open')     

    1150.           },     

    1151.           onChangeMonthYear: function() {     

    1152.             // Hack to fix IE9 not resizing     

    1153.             var $this = $(this)     

    1154.             var w = $this.outerWidth() // cache first!     

    1155.             setTimeout(function() {     

    1156.               $this.datepicker('widget').css( 'width', w )     

    1157.             }, 1)     

    1158.           },     

    1159.           onClose: function() { $(this).removeClass('open') }     

    1160.         })     

    1161.       })     

    1162.       // Adjust width     

    1163.       $datepicker.on('focus keyup', function() {     

    1164.         var t = $(this), w = t.outerWidth()     

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

    1166.       })     

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

    1168.     }     

    1169.   },     

    1170.   _doMarkup: function( $element ) {     

    1171.     var o = this.opts     

    1172.     var elementType = Utils.getIdealType( $element )     

    1173.     // Validation elements     

    1174.     var $field = $('<span class="ideal-field"/>')     

    1175.     var $error = $('<span class="ideal-error" />')     

    1176.     var $valid = $('<i class="ideal-icon ideal-icon-valid" />')     

    1177.     var $invalid = $('<i class="ideal-icon ideal-icon-invalid"/>')     

    1178.       .click(function(){     

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

    1180.       })     

    1181.     // Basic markup     

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

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

    1184.     var idealElements = {     

    1185.       _defaultInput: function() {     

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

    1187.           .parent().after( $error )     

    1188.       },     

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

    1190.       radiocheck: function() {     

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

    1192.         // wrap radios and checks more than once     

    1193.         var isWrapped = $element.parents('.ideal-field').length     

    1194.         if ( !isWrapped ) {     

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

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

    1197.         }     

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

    1199.           $element.idealRadioCheck()     

    1200.         }     

    1201.       },     

    1202.       select: function() {     

    1203.         idealElements._defaultInput()     

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

    1205.           $element.idealSelect()     

    1206.         }     

    1207.       },     

    1208.       file: function() {     

    1209.         idealElements._defaultInput()     

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

    1211.           $element.idealFile()     

    1212.         }     

    1213.       },     

    1214.       button: function() {     

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

    1216.           $element.addClass('ideal-button')     

    1217.         }     

    1218.       },     

    1219.       hidden: function() {     

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

    1221.       },     

    1222.       heading: function() {     

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

    1224.         $element.parent().children().wrapAll('<span class="ideal-heading"/>')     

    1225.       },     

    1226.       separator: function() {     

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

    1228.         $element.wrapAll('<div class="ideal-separator"/>')     

    1229.       }     

    1230.     }     

    1231.     // Generate markup for current element type     

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

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

    1234.   },     

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

    1236.    * @memberOf Actions    

    1237.    * @param {object} $input jQuery object    

    1238.    * @param {string} e The JavaScript event    

    1239.    */     

    1240.   _validate: function( $input, e ) {     

    1241.     var self = this     

    1242.     var o = this.opts     

    1243.     var userOptions = o.inputs[ $input.attr('name') ]     

    1244.     var userFilters = userOptions.filters && userOptions.filters.split(/s/)     

    1245.     var name = $input.attr('name')     

    1246.     var value = $input.val()     

    1247.     var ajaxRequest = $.idealforms.ajaxRequests[ name ]     

    1248.     var isRadioCheck = $input.is('[type="checkbox"], [type="radio"]')     

    1249.     var inputData = {     

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

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

    1252.       userOptions: userOptions     

    1253.     }     

    1254.     // Validation elements     

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

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

    1257.     var $invalid = isRadioCheck     

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

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

    1260.     var $valid = isRadioCheck     

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

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

    1263.     function resetError() {     

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

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

    1266.     }     

    1267.     function showOrHideError( error, valid ) {     

    1268.       resetError()     

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

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

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

    1272.       if ( !valid ) {     

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

    1274.       }     

    1275.     }     

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

    1277.     // This is mainly to prevent multiple AJAX requests     

    1278.     var oldValue = $input.data('ideal-value') || 0     

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

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

    1281.     // Validate     

    1282.     if ( userFilters ) {     

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

    1284.         var theFilter = $.idealforms.filters[ filter ]     

    1285.         var customError = userOptions.errors && userOptions.errors[ filter ]     

    1286.         var error = ''     

    1287.         // If field is empty and not required     

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

    1289.           resetError()     

    1290.           return false     

    1291.         }     

    1292.         if ( theFilter ) {     

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

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

    1295.             ajaxRequest.abort()     

    1296.             $field.removeClass('ajax')     

    1297.           }     

    1298.           // AJAX     

    1299.           if ( filter === 'ajax' ) {     

    1300.  nbsp;           showOrHideError( error, false ) // set invalid till response comes back     

    1301.             $error.hide()     

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

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

    1304.             } else {     

    1305.               var ajaxError = $input.data('ideal-ajax-error')     

    1306.               if ( ajaxError ) {     

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

    1308.               }     

    1309.             }     

    1310.           }     

    1311.           // All other filters     

    1312.           else {     

    1313.             var valid = Utils.isRegex( theFilter.regex ) && theFilter.regex.test( value ) ||     

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

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

    1316.             showOrHideError( error, valid )     

    1317.             if ( !valid ) { return false }     

    1318.           }     

    1319.         }     

    1320.       })     

    1321.     }     

    1322.     // Reset if there are no filters     

    1323.     else {     

    1324.       resetError()     

    1325.     }     

    1326.     // Flags     

    1327.     var flags = (function(){     

    1328.       var f = userOptions.flags && userOptions.flags.split(' ') || []     

    1329.       if ( o.globalFlags ) {     

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

    1331.       }     

    1332.       return f     

    1333.     }())     

    1334.     if ( flags.length ) {     

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

    1336.         var theFlag = $.idealforms.flags[f]     

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

    1338.       })     

    1339.     }     

    1340.     // Update counter     

    1341.     if ( self.$tabs.length ) {     

    1342.       self._updateTabsCounter( self._getCurrentTabIdx() )     

    1343.     }     

    1344.   },     

    1345.   _attachEvents: function() {     

    1346.     var self = this     

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

    1348.       var $this = $(this)     

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

    1350.       var isFile = $this.is('input[type=file]')     

    1351.       // Trigger on change if type=file cuz custom file     

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

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

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

    1355.       }     

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

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

    1358.       }     

    1359.       self._validate( $this, e )     

    1360.     })     

    1361.   },     

    1362.   _responsive: function() {     

    1363.     var formElements = this._getFormElements()     

    1364.     var maxWidth = LessVars.fieldWidth + formElements.labels.outerWidth()     

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

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

    1367.     })     

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

    1369.     this.opts.responsiveAt === 'auto'     

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

    1371.       : this.$form.toggleClass( 'stack', $(window).width() < this.opts.responsiveAt )     

    1372.     var isStack = this.$form.is('.stack')     

    1373.     $emptyLabel.toggle( !isStack )     

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

    1375.     // Hide datePicker     

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

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

    1378.   }     

    1379. })     

    1380. /*    

    1381.  * Public Methods    

    1382.  */     

    1383. $.extend( IdealForms.prototype, {     

    1384.   getInvalid: function() {     

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

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

    1387.     })     

    1388.   },     

    1389.   getInvalidInTab: function( nameOrIdx ) {     

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

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

    1392.     })     

    1393.   },     

    1394.   isValid: function() {     

    1395.     return !this.getInvalid().length     

    1396.   },     

    1397.   isValidField: function( field ) {     

    1398.     var $input = Utils.getByNameOrId( field )     

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

    1400.   },     

    1401.   focusFirst: function() {     

    1402.     if ( this.$tabs.length ) {     

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

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

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

    1406.     } else {     

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

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

    1409.     }     

    1410.     return this     

    1411.   },     

    1412.   focusFirstInvalid: function() {     

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

    1414.     var tabName = $first.parents('.ideal-tabs-content').data('ideal-tabs-content-name')     

    1415.     if ( this.$tabs.length ) {     

    1416.       this.switchTab( tabName )     

    1417.     }     

    1418.     $first.focus()     

    1419.     return this     

    1420.   },     

    1421.   switchTab: function( nameOrIdx ) {     

    1422.     this.$tabs.switchTab( nameOrIdx )     

    1423.     return this     

    1424.   },     

    1425.   nextTab: function() {     

    1426.     this.$tabs.nextTab()     

    1427.     return this     

    1428.   },     

    1429.   prevTab: function() {     

    1430.     this.$tabs.prevTab()     

    1431.     return this     

    1432.   },     

    1433.   firstTab: function() {     

    1434.     this.$tabs.firstTab()     

    1435.     return this     

    1436.   },     

    1437.   lastTab: function() {     

    1438.     this.$tabs.lastTab()     

    1439.     return this     

    1440.   },     

    1441.   fresh: function() {     

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

    1443.       .removeClass('valid invalid')     

    1444.     return this     

    1445.   },     

    1446.   freshFields: function( fields ) {     

    1447.     fields = Utils.convertToArray( fields )     

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

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

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

    1451.     })     

    1452.     return this     

    1453.   },     

    1454.   reload: function() {     

    1455.     this._adjust()     

    1456.     this._attachEvents()     

    1457.     return this     

    1458.   },     

    1459.   reset: function() {     

    1460.     var formElements = this._getFormElements()     

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

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

    1463.     // Select and custom select     

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

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

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

    1467.     this.focusFirst().fresh()     

    1468.     return this     

    1469.   },     

    1470.   resetFields: function( fields ) {     

    1471.     fields = Utils.convertToArray( fields )     

    1472.     var formElements = this._getFormElements()     

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

    1474.       var $input = Utils.getByNameOrId( v )     

    1475.       var type = Utils.getIdealType( $input )     

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

    1477.         $input.val('')     

    1478.       }     

    1479.       if ( type === 'radiocheck' ) {     

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

    1481.       }     

    1482.       if ( type === 'select' ) {     

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

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

    1485.       }     

    1486.       $input.change()     

    1487.     })     

    1488.     this.freshFields( fields )     

    1489.     return this     

    1490.   },     

    1491.   toggleFields: function( fields ) {     

    1492.     fields = Utils.convertToArray( fields )     

    1493.     var self = this     

    1494.     var $fields = Utils.getFieldsFromArray( fields )     

    1495.     $fields.each(function() {     

    1496.       var $this = $(this)     

    1497.       var name = $this.attr('name') || $this.attr('id')     

    1498.       var input = self.opts.inputs[ name ]     

    1499.       var filters = input && input.filters     

    1500.       var dataFilters = $this.data('ideal-filters') || ''     

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

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

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

    1504.     })     

    1505.     return this     

    1506.   },     

    1507.   setOptions: function( options ) {     

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

    1509.     this.reload().fresh()     

    1510.     return this     

    1511.   },     

    1512.   setFieldOptions: function( name, options ) {     

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

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

    1515.     return this     

    1516.   },     

    1517.   addFields: function( fields ) {     

    1518.     fields = Utils.convertToArray( fields )     

    1519.     var self = this     

    1520.     // Save names of all inputs in Array     

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

    1522.     var allNames = []     

    1523.     // Add an input to the DOM     

    1524.     function add( ops ) {     

    1525.       var name = ops.name     

    1526.  nbsp;     var userOptions = {     

    1527.         filters: ops.filters || '',     

    1528.         data: ops.data || {},     

    1529.         errors: ops.errors || {},     

    1530.         flags: ops.flags || ''     

    1531.       }     

    1532.       var label = ops.label || ''     

    1533.       var type = ops.type     

    1534.       var list = ops.list || []     

    1535.       var placeholder = ops.placeholder || ''     

    1536.       var value = ops.value || ''     

    1537.       var $field = $('<div>'+     

    1538.           '<label>'+ label +':label>'+     

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

    1540.         'div>')     

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

    1542.       // Add inputs with filters to the list     

    1543.       // of user inputs to validate     

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

    1545.       self._doMarkup( $input )     

    1546.       // Insert in DOM     

    1547.       if ( ops.addAfter ) {     

    1548.         $field.insertAfter(     

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

    1550.         )     

    1551.       } else if ( ops.addBefore ) {     

    1552.         $field.insertBefore(     

    1553.           $(Utils.getByNameOrId( ops.addBefore ))     

    1554.           .parents('.ideal-wrap')     

    1555.         )     

    1556.       } else if ( ops.appendToTab ) {     

    1557.         $field.insertAfter(     

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

    1559.         )     

    1560.       } else {     

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

    1562.       }     

    1563.       // Add current field name to list of names     

    1564.       allNames.push( name )     

    1565.     }     

    1566.     // Run through each input     

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

    1568.     self.reload()     

    1569.     self.freshFields( allNames )     

    1570.     self._responsive()     

    1571.     return this     

    1572.   },     

    1573.   removeFields: function( fields ) {     

    1574.     fields = Utils.convertToArray( fields )     

    1575.     var $fields = Utils.getFieldsFromArray( fields )     

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

    1577.     this.reload()     

    1578.     return this     

    1579.   }     

    1580. })     

    1581. }( jQuery, window, document ))

    【Related recommendations】

    1. Html5 free video tutorial

    2. HTML5 local database instance detailed explanation

    3. Teach you how to achieve it An H5 micro-scene

    4. Detailed explanation of H5’s custom attributes data-*

    5. H5 code example for implementing text box prompts

The above is the detailed content of Detailed example of H5 completing automatic verification of user registration. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template