一个不错的无刷新表单验证

2011-05-23 17:06:17 by 【6yang】, 253 visits, 收藏 | 返回

/*
*Jquery 表单验证和表单Ajax提交合体插件
*需要jquery1.4或者以上版本支持
*By 甘强 2011/03/17
*1.0版
*插件官方地址:http://www.skygq.com/2010/12/29/skygq-check-ajax-form-plugins/
*/
;(function($){
    $.fn.skygqCheckAjaxForm = function(settings){
        //如果选择器选择的不是form,则阻止插件继续运行
        if( !this.is("form") ) return;
        var form_id = this.selector.substring(1);
        settings = $.extend({}, $.skygqCheckAjaxForm.defaultSettings, settings || {});
        // 计算skygqCheckAjaxForm的根路径
        if (!settings.root) {
            $('script').each(function(a, tag) {
                miuScript = $(tag).get(0).src.match(/(.*)jquery.skygqCheckAjaxform.1.5(.mini)?.js$/);
                if (miuScript !== null) settings.root = miuScript[1];
            });
        }
        //设定ajax loading的图片地址
        if (!settings.ajaxImage) settings.ajaxImage = settings.root + 'images/loading.gif';

        //加载css样式
        if ($("link[href$=skygq_valid.css]").length == 0){
            var css_href = settings.root+'css/skygq_valid.css';
            var styleTag = document.createElement("link");
            styleTag.setAttribute('type', 'text/css');
            styleTag.setAttribute('rel', 'stylesheet');
            styleTag.setAttribute('href', css_href);
            $("head")[0].appendChild(styleTag);
        }

        //装载ajax loading图片和遮罩层
        if ($("#skygqCheckAjaxFormOverlay").length == 0){
            $("body").append('<div id="skygqCheckAjaxFormOverlay" style="display:none;text-align:center;position:absolute;z-index:2000;left:0;top:0;background:black;cursor:hand"><img src="'+settings.ajaxImage+'" id="skygqCheckAjaxForm_image"></div>');
        }
        settings.ajaxImageObj = $("#skygqCheckAjaxForm_image");
        settings.overLayObj    = $("#skygqCheckAjaxFormOverlay");
        var    msg = "",
            formObj = this,
            checkRet = true,
            rule = $.skygqCheckAjaxForm.rule,
            isAll,
            tipname = function(namestr){
                namestr = namestr.replace(/(.|[|])/g,'');
                return form_id + "tip_" + namestr.replace(/([a-zA-Z0-9])/g,"-$1");
            },
            //规则类型匹配检测
            typeTest = function(){
                var result = true,args = arguments;
                if(rule.hasOwnProperty(args[0])){
                    var t = rule[args[0]][0], v = args[1];
                    result = args.length>2 ? t.apply(arguments,[].slice.call(args,1)):($.isFunction(t) ? t(v) :t.test(v));
                }
                return result;
            },
            //错误信息提示
            showError = function(fieldObj,filedName,warnInfo){
                checkRet = false;
                var tipObj = $("#"+tipname(filedName));
                if(tipObj.length>0) tipObj.remove();
                var tipPosition = fieldObj.next().length>0 ? fieldObj.nextAll(":last"):fieldObj;
                tipPosition.after("<span class='Wrong' id='"+tipname(filedName)+"'> "+warnInfo+" </span>");
                if(settings.isAlert && isAll) msg += " " + warnInfo;
            },

            //正确信息提示
            showRight = function(fieldObj,filedName,SuccessInfo){
                var tipObj = $("#"+tipname(filedName));
                if(tipObj.length>0) tipObj.remove();
                var tipPosition = fieldObj.next().length>0 ? fieldObj.nextAll(":last"):fieldObj;
                if (!SuccessInfo){
                    SuccessInfo = '填写正确';
                }
                tipPosition.after("<span class='Correct' id='"+tipname(filedName)+"'> "+ SuccessInfo +" </span>");
            },
            //focus时提示
            showExp = function(obj){
                var i = obj, fieldObj = $("[name='"+i.name+"']",formObj[0]);
                var tipObj = $("#"+tipname(i.name));
                if(tipObj.length>0) tipObj.remove();
                var tipPosition = fieldObj.next().length>0 ? fieldObj.nextAll(":last"):fieldObj;
                if (i.focusMsg){
                    tipPosition.after("<span class='Exp' id='"+tipname(i.name)+"'>"+ i.focusMsg +"</span>");
                }
            },
            //匹配对比值的提示名
            findTo = function(objName){
                var find;
                $.each(settings.items, function(){
                    if(this.name == objName && this.simple){
                        find = this.simple;    return false;
                    }
                });
                if(!find) find = $("[name='"+objName+"']")[0].name;
                return find;
            },
            //ajax验证
            ajax = function (obj,fv,field){
                var i = obj, fieldObj = $("[name='"+i.name+"']",formObj[0]);
                var tipObj = $("#"+tipname(i.name));
                if(tipObj.length>0) tipObj.remove();
                var tipPosition = fieldObj.next().length>0 ? fieldObj.nextAll().eq(this.length):fieldObj.eq(this.length - 1);
                tipPosition.after("<span class='Exp' id='"+tipname(i.name)+"'>检测中......</span>");
                fv = encodeURI(fv);
                $.ajax({
                    type    : obj.ajax.method || 'GET',
                    url        : obj.ajax.url,
                    data    : obj.name+"="+fv,
                    cache    : false,
                    async    : !isAll,// false使用同步方式执行AJAX,true使用异步方式执行ajax
                    success    : function(data){
                        if (data == 1){
                            showRight(field,obj.name,obj.ajax.success_msg);
                        }
                        else if(data == 0){
                            showError(field ,obj.name, obj.ajax.failure_msg);
                        }else{
                            showError(field ,obj.name, data);
                        }
                    }
                });
            },
            //单元素验证
            fieldCheck = function(item){
                var i = item, field = $("[name='"+i.name+"']",formObj[0]),filed_length = field.length;
                if(filed_length == 0) return;
                var warnMsg,
                    fv = $.trim(field.val()),
                    isRq = typeof i.require ==="boolean" ? i.require : true;
                if (filed_length == 1){
                    if( isRq && ((field.is(":radio")|| field.is(":checkbox")) && !field.is(":checked"))){
                        warnMsg =  i.message|| "请选择" + i.simple;
                        showError(field ,i.name, warnMsg);
                    }else if(isRq && fv == "" ){
                        warnMsg =  i.message|| ( field.is("select") ? "请选择" :"请填写" ) + i.simple;
                        showError(field ,i.name, warnMsg);
                    }else if(fv != ""){
                        if(i.min || i.max){
                            var len = fv.length, min = i.min || 0, max = i.max;
                            warnMsg =  i.message || (max? i.simple + "长度范围应在"+min+"~"+max+"之间":i.simple + "长度应大于"+min);
                            if( (max && (len>max || len<min)) || (!max && len<min) ){
                                showError(field ,i.name, warnMsg);    return;
                            }
                        }
                        if(i.type){
                            var matchVal = i.to ? $.trim($("[name='"+i.to+"']",formObj[0]).val()) :i.value;
                            var matchRet = matchVal ? typeTest(i.type,fv,matchVal) :typeTest(i.type,fv);
                            warnMsg = i.message|| i.simple + rule[i.type][1];
                            if(matchVal && i.simple) warnMsg += (i.to ? findTo(i.to) +"的值" :i.value);
                            if(!matchRet){
                                showError(field ,i.name, warnMsg);return;
                            }else{
                                showRight(field,i.name);
                            }
                        }
                        if (i.between){
                            var from = i.between[0],to = i.between[1];
                            warnMsg = i.message || i.simple + "的值必须在" + from + "和" + to + "之间";
                            if (fv >= +from && fv <= +to){
                                showRight(field,i.name);
                            }else{
                                showError(field ,i.name, warnMsg);return;
                            }
                        }
                        if (i.ajax){
                            ajax(i,fv,field);
                        }else{
                            showRight(field,i.name);
                        }
                    }
                }else{
                    if (field.is("input:checkbox")){
                        var checked_count = 0;
                        field.each(function(){
                            if (this.checked == true){
                                checked_count ++;
                            }
                        });
                        if(i.checked_limit){
                            var min = i.checked_limit[0] || 1, max = i.checked_limit[1] || null;
                            warnMsg = i.message || min==max?"请必须选择"+min+"项"+i.simple:(max? "请选择"+i.simple + min+"到"+max+"项目":"请至少选择" +min + "项" + i.simple);
                            if( (max && (checked_count>max || checked_count<min)) || (!max && checked_count<min) ){
                                showError(field ,i.name, warnMsg);    return;
                            }else{
                                showRight(field,i.name,'正确');
                            }
                        }
                    }
                }
            },
            //元素组验证
            validate = function(){
                checkRet = true;
                $.each(settings.items, function(){
                    isAll=true; fieldCheck(this);
                });
                if(settings.isAlert && msg != ""){
                    alert(msg);    msg = "";
                }
                return checkRet;
            };
            //单元素事件绑定
            $.each(settings.items, function(){
                var field = $("[name='"+this.name+"']",formObj[0]);
                var obj = this,
                toExp = function(){showExp(obj);},
                toCheck = function(){ isAll=false; fieldCheck(obj);};
                if(field.is(":file") || field.is("select")){
                    field.change(toCheck).focus(toExp);
                }else{
                    field.blur(toCheck).focus(toExp);
                }
            });
            return this.each(function(){
                //提交事件绑定
                if(settings.isAjaxSubmit) {
                    formObj.submit(function(){
                        if (validate()){//验证通过-ajax提交数据
                            if (settings.isBg){
                                $.fn.skygqCheckAjaxForm.setPosition(formObj,settings);
                            }
                            $('input:submit',formObj).attr('disabled','disabled');
                            formObj.skygqajaxSubmit(settings);
                        }
                        return false;
                    });
                }else{//非ajax提交数据
                    formObj.submit(validate);
                }
            });
    };
    $.skygqCheckAjaxForm = function(){};

    $.skygqCheckAjaxForm.defaultSettings = {
        items                : [],
        isAlert                : false,
        isAjaxSubmit        : false,
        success                : $.noop,
        isBg                : true,
        clearForm            : true,
        root                : '',
        ajaxImage            : null
    };

    $.skygqCheckAjaxForm.rule    = {
        "eng"         : [/^[A-Za-z]+$/,"只能输入英文"],
        "chn"         : [/^[u0391-uFFE5]+$/,"只能输入汉字"],
        "mail"         : [/w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*/,"格式不正确"],
        "url"         : [/^http[s]?://[A-Za-z0-9]+.[A-Za-z0-9]+[/=?%-&_~`@[]':+!]*([^<>""])*$/,"格式不正确"],
        "currency"     : [/^d+(.d+)?$/,"数字格式有误"],
        "number"     : [/^d+$/,"只能为数字"],
        "int"         : [/^[0-9]{1,30}$/,"只能为整数"],
        "double"     : [/^[-+]?d+(.d+)?$/,"只能为带小数的数字"],
        "username"     : [/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){3,19}$/,"用户名不合法"],
        "password"     : [/^(w){6,20}$/,"只能为数字和英文及下划线的组合,6-20个字符"],
        "safe"         : [/>|<|,|[|]|{|}|?|/|+|=|||'|\|"|:|;|~|!|@|#|*|$|%|^|&|(|)|`/i,"不能有特殊字符"],
        "dbc"         : [/[a-zA-Z0-9!@#¥%^&*()_+{}[]|:"';.,/?<>`~ ]/,"不能有全角字符"],
        "qq"         : [/[1-9][0-9]{4,}/,"格式不正确"],
        "date"         : [/^((((1[6-9]|[2-9]d)d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]d|3[01]))|(((1[6-9]|[2-9]d)d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]d|30))|(((1[6-9]|[2-9]d)d{2})-0?2-(0?[1-9]|1d|2[0-8]))|(((1[6-9]|[2-9]d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$/,"格式不正确"],
        "telephone" : [/^1d{10}$/,"格式不正确"],
        "zipcode"     : [/^[1-9]d{5}$/,"格式不正确"],
        "bodycard"     : [/^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)d{4}((19d{2}(0[13-9]|1[012])(0[1-9]|[12]d|30))|(19d{2}(0[13578]|1[02])31)|(19d{2}02(0[1-9]|1d|2[0-8]))|(19([13579][26]|[2468][048]|0[48])0229))d{3}(d|X|x)?$/,"格式不正确"],
        "ip"         : [/^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$/,"IP不正确"],
        // 函数规则
        "eq"        : [function(arg1,arg2){ return arg1==arg2 ? true:false;},"必须等于"],
        "gt"        : [function(arg1,arg2){ return arg1>arg2 ? true:false;},"必须大于"],
        "gte"        : [function(arg1,arg2){ return arg1>=arg2 ? true:false;},"必须大于或等于"],
        "lt"        : [function(arg1,arg2){ return arg1<arg2 ? true:false;},"必须小于"],
        "lte"        : [function(arg1,arg2){ return arg1<=arg2 ? true:false;},"必须小于或等于"]
    };
    $.skygqCheckAjaxForm.extendRemove = function(target, props) {
        $.extend(target, props);
        for (var name in props)
            if (props[name] == null || props[name] == undefined)
                target[name] = props[name];
        return target;
    };
    $.skygqCheckAjaxForm.addRules = function(settings) {
        $.skygqCheckAjaxForm.extendRemove($.skygqCheckAjaxForm.rule, settings || {});
        return this;
    };

    $.fn.skygqCheckAjaxForm.setPosition = function(formObj,settings){
        var form_position = formObj.offset();
        settings.overLayObj.css({
            'width' : formObj.outerWidth(),
            'height': formObj.outerHeight(),
            'top'    : form_position.top,
            'left'    : form_position.left,
            'opacity':'0.5'
        }).fadeIn();
        var image_h = settings.ajaxImageObj[0].height;
        var marginTop = parseInt((formObj.outerHeight() - image_h)/2,10);
        if (settings.ajaxImage) settings.ajaxImageObj.css('marginTop',marginTop);
    };
    $.fn.skygqajaxSubmit = function(options) {
        if (!this.length) {    return this;}
        return this.each(function(){
            var $form = $(this), callbacks = [];
            var url = $.trim($form.attr('action'));
            if (url) url = (url.match(/^([^#]+)/)||[])[1];// 获取url中“#”字符前面的地址
            url = url || window.location.href || '';
            options = $.extend(true, {
                url        :  url,
                type    : $form.attr('method') || 'GET',
                dataType:'html'
            }, options);

            var q = $form.serialize();

            if(options.type.toUpperCase() == 'GET') {
                options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
                options.data = null;
            }else{
                options.data = q;
            }

            if (options.clearForm) {
                callbacks.push(function() { $form.clearForm(); });
            }

            callbacks.push(function(){
                $.fn.removeBg($form);
            });

            if (options.success) {
                callbacks.push(options.success);
            }

            options.success = function(data, status, xhr) {
                var context = options.context || options;
                for (var i=0, max=callbacks.length; i < max; i++) {
                    callbacks[i].apply(context, [data, status, xhr || $form, $form]);
                }
            };
               $.ajax(options);
        });
    };

    $.fn.removeBg = function($form){
        $('#skygqCheckAjaxFormOverlay').fadeOut();
        $('input:submit',$form[0]).removeAttr('disabled');
    };

    $.fn.clearForm = function() {
        return this.each(function() {
            $('input,select,textarea', this).clearFields();
        });
    };

    $.fn.clearFields = function() {
        return this.each(function() {
            var t = this.type, tag = this.tagName.toLowerCase();
            if (t == 'text' || t == 'password' || tag == 'textarea') {
                this.value = '';
            }
            else if (t == 'checkbox' || t == 'radio') {
                this.checked = false;
            }
            else if (tag == 'select') {
                this.selectedIndex = -1;
            }
        });
    };
})(jQuery);

分享到:
share

    图片原图

    loading

    loading