bootstrap Validator v0.5.1-dev 爆炸坑

参考
http://1000hz.github.io/bootstrap-validator/#
http://formvalidation.io/download/
http://blog.csdn.net/u013938465/article/details/53507109

神奇的变量命名

a:
b: 需验证字段
c: message容器/配置
d: 表单元素的type

默认字段

获取方式 $.fn.bootstrapValidator.DEFAULT_OPTIONS

{
    "elementClass": "bv-form",
    "message": "This value is not valid",
    "group": ".form-group",
    "container": null,
    "threshold": null,
    "excluded": [
        ":disabled",
        ":hidden",
        ":not(:visible)"
    ],
    "feedbackIcons": {
        "valid": null,
        "invalid": null,
        "validating": null
    },
    "submitButtons": "[type=\"submit\"]",
    "live": "enabled",
    "fields": null
}
fields={
    container 
    excluded
    feedbackIcons
    group
    message
    onError
    onStatus
    onSuccess
    selector
    threshold 开始验证长度(对radio类型无效)
    trigger     触发验证的动作例如:keyup(按键)/blur(失去焦点)
    validators
}

fields.validators = {

    callback:{
        message:[string],
        callback: [function]
    },

    notEmpty

    numeric: {
        message:[string],
        separator: [function]
    },



}

栗子

$("#agentCreate").bootstrapValidator({
        feedbackIcons:{
            valid: 'glyphicon glyphicon-ok',
            invalid: 'glyphicon glyphicon-remove',
            validating: 'glyphicon glyphicon-refresh'
        },
        message:'不能为空',
        fields:{
            title:{
                validators: {
                    notEmpty: {}
                }
            },
            file:{
                validators: {
                    notEmpty: {}
                }
            },
        }
    }).on('success.form.bv', function(e) {
                // 阻止默认事件提交
                e.preventDefault();
            });
    $("#sub").on("click", function () {
        //获取表单对象
        var bootstrapValidator = $("#agentCreate").data('bootstrapValidator');
        //手动触发验证
        bootstrapValidator.validate();
        if (bootstrapValidator.isValid()) {
            console.log("bootstrapValidator", arguments);
            //表单提交的方法、比如ajax提交

        }
    })

操作

获取已配置的表单元素

$("#agentCreate").data("bootstrapValidator").getInvalidFields()

获取配置

$("#agentCreate").data("bootstrapValidator").getOptions()

重置某字段(会清空对应表单元素数据)

$("#agentCreate").data("bootstrapValidator").resetField("imgId","#imgSelector")

更新某字段状态(不会清空数据)

$(formName).data(“bootstrapValidator”).updateStatus("fieldName",  "NOT_VALIDATED",  null );

vue1.0 Observer watcher 双向绑定简单js实现

来源:https://segmentfault.com/a/1190000004384515

(function(){
    //Observer
    var Observer = cc.Class.extend({
        ctor: function(value){
            this.value = value;
            this.walk(value);
        },
        walk: function(value){
            Object.keys(value).forEach(function(key, ind, arr){
                this.convert(key,value[key]);
            },this);
        },
        convert: function(key, val){
            defineReactive(this.value, key, val);
        }
    });
    var defineReactive = function(obj, key, val){
        var dep = new Dep();
        var childOb = observer(val);
        Object.defineProperty(obj, key, {
            enumberable: true,
            configurable: true,
            get: function(){
                console.log("get");
                if(Dep.target){
                    dep.addSub(Dep.target);
                }
                return val;
            },
            set: function(newValue){
                console.log("set",newValue);
                var value = val;
                if(newValue === value){
                    return;
                }
                childOb = observer(newValue);
                dep.notify();
            }
        })
    };
    var observer = function(value, vm){
        if (!value || typeof value !== 'object') {
            return;
        }
        return new Observer(value);
    };
    //订阅器
    var Dep = cc.Class.extend({
        ctor: function(){
            this.subs = [];
        },
        addSub:function(sub){
            this.subs.push(sub);
        },
        notify:function(){
            this.subs.forEach(function(sub, ind, arr){
                sub.update();
            })
        },
    });
    Dep.target = null
    //watcher
    var Watcher = cc.Class.extend({
        ctor: function(vm, expOrFn, cb){
            this.cb = cb;
            this.vm = vm;
            //暂时只考虑expression的情况
            this.expOrFn = expOrFn;
            this.value = this.get();
        },
        update: function(){
            this.run();
        },
        run: function(){
            var value = this.get();
            if(value !== this.value){
                this.value = value ;
                this.cb.call(this.vm);
            }
        },
        get: function(){
            Dep.target = this;
            //暂时只考虑expression的情况
            var value = this.vm._data[this.expOrFn];
            Dep.target = null;
            return value;
        }
    });
    //Vue
    var vue = cc.Class.extend({
        ctor: function(options){
           this.$options = options || {};
           var data = this._data = this.$options.data;
           Object.keys(data).forEach(function(key, ind, arr){
               this._proxy(key);
           },this);
           observer(data, this);
        },
        $watcher: function(expOrFn, cb, options){
            new Watcher(this, expOrFn, cb);
        },
        _proxy: function(key){
            var self = this;
            Object.defineProperty(self, key, {
                configurable: true,
                enumberalbe: true,
                get:function proxyGetter(){
                    return self._data[key];
                },
                set: function proxySetter(val){
                    self._data[key] = val;
                }
            });
        }
    });

    mj.vue = vue;
})();

js 模拟jq 实现 $ 选择器

(function(){
    var jQ = function(selector, father){
        return new jQ.prototype.init(selector);
    };
    jQ.prototype = {
        length:0,
        init:function(selector, father){
            var _document = father || ja.view,
                classInt = 0,
                res = this;
            if (typeof selector != "string" || !selector ){
                if(typeof selector == "object" && selector.hasOwnProperty("length")){
                    for(var i = 0 ; i < selector.length ; i++){
                        this[classInt] = selector[i];
                        classInt++;
                    }
                }else{
                    this[classInt] = selector;
                    classInt++;
                }

            }else{
                var props = selector.trim().split(" "),
                    selector = props.shift(),
                    selectLast = props.join(" "),
                    mark = selector.charAt(0);
                if(mark == "["){
                    var selector=selector.replace(/[\[\]]/g,""),
                        arr = selector.split("=");
                    key = arr.length > 1 ? arr[0].trim() : "name",
                        val = arr.length > 1 ? arr[1].trim() : arr[0].trim();
                    //遍历children
                    // ja.log(key,val);
                    _document.children.map(function(ele){
                        return (function(father,deep){
                            // var res = [];
                            if(typeof father[key] !="undefined" && father[key] == val){

                                this[classInt] = father;
                                classInt++;
                            }
                            var c = father.children;
                            if(c && deep < 5){
                                deep++;
                                for(var i in c){
                                    arguments.callee.call(this,c[i],deep);
                                }
                            }
                            // return res;
                        }).call(this,ele,0);
                    }.bind(this))
                }else if(mark == "."){
                    var res = this.__class(selector.substring(1));
                    res.map(function(ele){
                        this[classInt] = ele;
                        classInt++;
                    }.bind(this));

                }
            }
            this.length = classInt;
            return this;
        },
        /*原型方法,不暴露*/
        //类选择器位置列表
        __class:function(className){
            var arr = [];
            switch (className){
                case "mainView":
                    arr.push(ja.view);
                    break;
                case "setBalance":
                    arr.push(ja.setb);
                    break;
                case "gameBalance":
                    arr.push( ja.gameb);
                    break;
                case "playerFrameList":
                    for(var key in ja.view.playerInfoHandler.playerFrameList){
                        arr.push(ja.view.playerInfoHandler.playerFrameList[key].view);
                    }
                    break;
                case "playerArea":
                    arr.push( ja.view.posLocal2Player);
                    break;
                case "playerOut":
                    ja.view.posLocal2Player.map(function(ele){
                        arr.push( ele.outTile);
                    });
                    break;
                default:
                    return null
            }
            return arr;
        },
        //通过选择器确定子元素获取方式
        _selector: function(selector, father){
            if(typeof selector != "string" || !selector){
                return this;
            }
            father = father ? father.children : Array.prototype.slice.apply(this);
            var mark = selector.charAt(0);
            switch(mark){
                case "[":
                    var reg = /\[(([\w\W]+)=["']?([\w\W]+)["']?|([\w\W]+))\]/;
                    var reg_res = reg.exec(selector);
                    var res_key = reg_res[2] || "name";
                    var res_val = reg_res[3] || reg_res[4];
                    var res = [];
                    father.map(function(ele){
                        return (function(fa, deep){

                            if(typeof fa[res_key] != "undefined" && fa[res_key] == res_val){
                                res.push(fa);
                            }

                            if (fa.children.length > 0 && deep < 5){
                                deep++;
                                for( var i = 0 ; i < fa.children.length ; i++){
                                    var add = arguments.callee.call(this,fa.children[i],deep);
                                }
                            }
                            return res;
                        }).call(this,ele,0);
                    }.bind(this));

                    return res;
                case ":":

                    break;
                case "*":

                    break;
                default:

            }
        },
        //表达式筛选器,未完成
        _expression:function(expression){
            if(!expression){

            }
            switch (expression){
                case "first":
                    return 0;
                case "last":
                    return
            }
        },
        /*过滤*/
        find:function(selector){
            var res = this._selector(selector);
            return new jQ.prototype.init(res);
        },
        parent:function(){
            var arr = [];
            Array.prototype.slice.apply(this).map(function(ele,ind){
                arr.push(ele["parent"]);
            }.bind(this));
            if(arr.length > 0){
                var res = arr.length == 1 ? arr.shift() : arr;
                return new jQ.prototype.init(res);
            }
        },
        parents:function(){

        },
        child:function(selector){

        },
        /*操作*/
        attr:function(selector, setValue){
            var arr = [];
            Array.prototype.slice.apply(this).map(function(ele,ind){
                if(typeof setValue == "undefined"){
                    if(typeof ele[selector] != "undefined"){
                        arr.push(ele[selector]) ;
                    }else if(typeof ele["_"+selector] != "undefined"){
                        arr.push(ele["_"+selector]) ;
                    }

                }else{
                    ele[selector] = setValue;
                }
            }.bind(this));
            if(arr.length > 0){
                return arr.length == 1 ? arr.shift() : arr;
            }
        },
        hide:function(){
            Array.prototype.slice.apply(this).map(function(ele){
                ele.setVisible(false);
            })
        },
        show:function(){
            Array.prototype.slice.apply(this).map(function(ele){
                ele.setVisible(true);
            })
        },
    };
    jQ.prototype.init.prototype = jQ.prototype;
    return window.$ = jQ;
})()

js 模拟类, 继承

var initializing = false, fnTest = /xyz/.test(function() { xyz; }) ? /\b_super\b/ : /.*/;
    //构造基类
    this.jaClass = function() {};
    jaClass.extend = function(props){
        var _super = this.prototype;
        initializing = true;
        var prototype = new this();
        initializing = false;

        for (var name in props){
            //这一段是赋值到prototype中,运用三元运算符的方式很灵活
            //满足函数的条件作为函数插入到prototype中
            prototype[name] = typeof props[name] =="function" &&
            typeof _super[name] == "function" && fnTest.test(props[name]) ?
                (function(name, fn) {
                    return function(){
                        var tmp = this._super;
                        this._super = _super[name];
                        var ret = fn.apply(this, arguments);
                        this._super = tmp;
                        return ret;
                    };
                })(name, props[name]) :
                props[name]
        }

        function Class(){
            if(!initializing && this.ctor)
                this.ctor.apply(this, arguments);
        }

        //子类prototype指向父类的实例,继承的关键
        Class.prototype = prototype ;
        Class.prototype.constructor = Class;
        //子类自动获得extend方法,arguments.callee 指向当前正在执行的函数
        Class.extend = arguments.callee;
        return Class;
    };