表单验证插件

如果你用中文都说不清楚,

那么你肯定也写不出来代码。

编程定律

—— 鲁迅

验证插件的思路

  1. 定义验证规则和出错信息
  2. 收集表单数据
  3. 对每条数据做验证
  4. 返回最终结果
  5. 提示出错信息

定义验证规则和出错信息

中文:

  • 邮箱必须还有 @
  • 手机必须是数字
  • 用户名最小长度为3,最大为30
var rules = {
    email: function(value){
        return value.indexOf('@') >= 0
    },
    phone: function(value){
        return /^\d+$/.test(value)
    },
    username: function(value){
        return value.length >= 3 && value.length <= 30
    }
}

代码:

收集表单数据

中文:

  1. 遍历所有 input、radio、checkbox、select、textarea(不考虑 file)
  2. 获取 name 和 value
var object = {}
$(form).find('input, select, textarea').each(function(index, node){
    var name = node.getAttribute('name')
    var value = node.value
    object[name] =value
})
console.log(object)

代码:

但是,这样是欠妥的

  1. 多个 radio 或者 checkbox 有相同的 name
  2. 对于 radio/checkbox/select,我们只需要被选中的 value
  3. <input type=submit name=submit value=OK> 不应该取 value

收集表单数据 - 换思路

中文:

  1. 获取所有有效的 name(input[type=text]、radio、checkbox、select、textarea、input[type=hidden](注意 input type 为空时)
  2. 根据 name 获取 value(注意获取方式)
  3. 将所有 value 汇总到一个对象里

注:我们遍历了很多遍 form。先走通、再优化。

过早的优化是一切罪恶的根源。

编程定律

—— 高德纳

参考:维基百科

收集表单数据 - 换思路

var selector = 'input[type=text], input[type=hidden], input[type=radio], input[type=checkbox], input[type=password], select, textarea'
var nameList = $(form).find(selector).map(function(index, node){
    return node.getAttribute('name')
}).get()

var allValues = {}
for(var i=0; i<nameList.length; i++){
    var name = nameList[i]

    if(allValues[name] !== undefined){ continue }

    var $input = $(form).find('[name='+ name +']')
    var value = $input.val()
    
    var type = $input.attr('type')
    if(type === 'radio'){
        value = $input.filter('input:checked').val()
    }else if(type === 'checkbox'){
        value = $input.filter('input:checked').map(function(){return this.value}).get().join(',')
    }

    allValues[name] = value
}
console.log(allValues)

对每条数据做校验

  1. 遍历所有数据
  2. 拿到 name 和 value
  3. 根据 name 拿到 rule
  4. 用 rule 来校验 value
  5. 如果不成功,则整个表单校验不通过
  6. 返回最终结果

代码:

中文:

var formValid = true
for(var name in allValues){
    var value = allValues[name]
    var rule = rules[name]
    var inputValid = rule(value)
    if(inputValid === false){
        formValid = false;
        break;
    }
}
console.log(formValid)

对每条数据做校验 - 改进

说明错在哪了:

var messages = {
    email: '邮箱格式不正确',
    phone: '手机。。。'
}
var rules = { email, phone, username}

var formValid = true
var errorList = []

for(var name in allValues){
    var value = allValues[name]
    var rule = rules[name]
    var inputValid = rule(value)
    if(inputValid === false){
        formValid = false;
        errorList.push({
            name: name,
            value: value,
            message: messages[name] || '填写错误'
        })
    }
}

var result = {
    valid: formValid,
    errorList: errorList
}

更多改进:

  • 给出友好的错误提示
  • 给出所有的错误,而不是第一个

提示错误信息

中文:

var result = {
    valid: formValid,
    errorName: errorName,
    errorValue: errorValue,
    errorMessage: errorMessage
}

var $error = $('<span class=error></span>').text(result.errorMessage)

$(form).find('[name='+result.errorName+']').first().after($error)
  1. 根据 name 找到出错的 input
  2. 在 input 后面添加错误信息

代码:

汇总

$.ajax 详解

$.get 和 $.post 是 $.ajax 的简化版

常见设置

jQuery.ajax({
    url:'//...', // 或者  url: '/path/...',
    type: 'get', // 或者 post GET POST delete DELETE put PUT
    async:, //默认是 true(异步),设为 false 则表示同步。
    contentType: '...', // 默认是'application/x-www-form-urlencoded; charset=UTF-8',可以改为 'application/json'
    success: function(){}, // HTTP status 为 200 时的回调
    error: function(){}, // HTTP status 为 404/500/502/503 等值时的回调
    complete: function(){}, // 不管 HTTP status 是多少,都会执行的回调 
    converters: {} // 对响应字符串的处理,具体见文档
    dataType: // 响应的数据的类型 xml/json/text 等
})

完。

下节课:

  • 同源策略、跨域请求

表单验证插件 & 写 JS

By 方方

表单验证插件 & 写 JS

  • 2,238