📄 full-validator.js
字号:
var self = this; if(!Request[this.options.as]) return; var request = new Request[this.options.as]({url: this.options.url, onSuccess : function(data){ window.addEvent('domready', self.wait.bind(self, data)); request = null; }}).get(); }, wait : function(json){ var self = this; json.rules.each(function(rule){ if (!rule['for']) return; self.fill(rule); }); }, fill : function(rule){ rule.element = this.form.getFormItem(rule['for']); this.form.addElement(ns.Factory.Element.build(rule)); } }); ns.XmlReader = new Class({ Extends : ns.JsonReader, options : { url : 'rules/validation.xml', xpath : {name : 'demo', path : '/validator/index.html'}, as : 'XML' }, getXPath : function(){ var ops = this.options; return $type(ops.xpath) == 'string' ? ops.xpath : '//form[@name="' + ops.xpath.name + '" and @path="' + ops.xpath.path + '"]/item'; }, wait : function(xml){ var nodes = xml.selectNodes(this.getXPath()), o; for(var i = 0, l = nodes.length; i < l; i ++){ if (!nodes[i].getAttribute('for')) continue; o = ns.Factory.Element.getAttributes(nodes[i]); if(nodes[i].getAttribute('apply')) o = $merge(ns.Factory.Element.getAttributes(xml.selectSingleNode(nodes[i].getAttribute('apply'))), o); if(o.rule) this.fill(o); }; } }); var Validator = ns.Validator = { forms : {}, setup : function(options){ var form = new ns.Form(options); this.forms[options.form] = form; return form; }, validate : function(options){ }, registerElement : function(className, prototype, autoInherit){ if(autoInherit !== false) prototype.Extends = AbstractElement; ns.ExtendElements[className] = new Class(prototype); }, registerRegex : function(key, regex){ $regexs[key] = regex; }, registerProperty : function(){ for(var i = 0, l = arguments.length, ps = $properties.join(','); i < l; i ++) if(!ps.contains(arguments[i], ',')) $properties.push(arguments[i]); }, registerReader : function(className, prototype, autoInherit){ if(autoInherit !== false) prototype.Extends = AbstractReader; ns.ExtendReaders[className] = new Class(prototype); }, registerMessenger : function(className, prototype, autoInherit){ if(autoInherit !== false) prototype.Extends = AbstractMessenger; ns.ExtendMessengers[className] = new Class(prototype); }, toString : function(){return ['Version: 4.0.0 beta', 'Author: \u6211\u4f5b\u5c71\u4eba', 'Email: wfsr-at-msn.com'].join('\n');} }; ns.Factory = { Element : { build : function(o){ var element, rule = o.rule.capitalize().replace(/Element$/, '') + 'Element'; return new ($pick(ns[rule], ns.ExtendElements[rule], ns.RegexElement))(o); }, getAttributes : function(el){ var options = {element : el}; $properties.each(function(prop){ if(el.getAttribute(prop)) options[prop] = el.getAttribute(prop); }); return options; } }, Messenger : { build : function(name, form, options){ name = name.capitalize().replace(/Messenger$/, '') + 'Messenger'; return new ($pick(ns[name], ns.ExtendMessengers[name]))(form, options); } }, Reader : { build : function(name, form, options){ name = name.capitalize().replace(/Reader$/, '') + 'Reader'; return new ($pick(ns[name], ns.ExtendReaders[name]))(form, options); } } }; ns.Form = new Class({ Implements : [Events, Options], options : { form : null, configs : 'tag', triggers : 'submit, blur', warns : 'follow', step : false, wait : false, title : '\u63d0\u4ea4\u5931\u8d25\uff0c\u8bf7\u6309\u4ee5\u4e0b\u63d0\u793a\u68c0\u67e5\u60a8\u7684\u8f93\u5165\uff1a', ignoreOldEvent : true, events : null/*, onTips : $empty, onRemote : $empty, onSuccess : $empty, onFailure : $empty*/ }, initialize : function(options){ this.isValid = false; this.elements = []; this.invalids = []; this.batch = false; this.setOptions(options); this.initMessenger(); this.parseEnmValue('triggers', $triggers); this.bound = {onTips : this.tips.bind(this), onRemote : this.remote.bind(this), onFailure : this.failure.bind(this), onSuccess : this.success.bind(this)}; if (this.options.initialize) this.options.initialize.call(this); if(this.options.wait) window.addEvent('domready', this.loadConfigs.bind(this)); else this.loadConfigs(); }, validate : function(){ this.invalids.empty(); this.batch = true; for(var i = 0, l = this.elements.length; i < l; i ++) if(!this.elements[i].validate() && this.options.step) break; (this.isValid = this.invalids.length == 0) ? this.fireEvent('onSuccess', this) : this.fireEvent('onFailure', [this.invalids]); this.batch = false; return this.isValid; }, tips : function(el, isBlur){ this.fireEvent('onTips', [el, isBlur]); }, remote : function(el){ this.fireEvent('onRemote', el); }, success : function(el){ this.fireEvent('onSuccess', el); }, failure : function(el){ this.invalids.include(el); if(this.options.step || !this.batch) this.fireEvent('onFailure', el); }, initMessenger : function(){ var self = this; this.options.warns.split(util.comma).each(function(warn){ warn = warn.trim().toLowerCase(); var messenger = ns.Factory.Messenger.build(warn, self, self.options[warn] || {}); if(messenger) self.addEvents(messenger.bound); }); }, loadConfigs : function(){ var self = this; this.options.configs.split(util.comma).each(function(config, i){ config = config.trim().toLowerCase(); ns.Factory.Reader.build(config, self, self.options[config] || {}); }); if(Browser.loaded) this._add(); else window.addEvent('domready', this._add.bind(this)); }, getForm : function(){ if(!this.form){ this.form = $(this.options.form); if(ns.contains.call(this.options.triggers, $triggers.submit)){ if(this.options.ignoreOldEvent){ this.form.removeProperty('onsubmit'); this.form.onsubmit = null; } else { var oldEvent = this.form.onsubmit; } this.form.addEvent('submit', function(){ if(oldEvent) oldEvent(); return this.validate(); }.bind(this)); } } return this.form; }, getFormItem : function(name){ var items = this.getForm().getElements('[name=' + name + ']'); return items.length ? items[items.length - 1] : $(name); }, addElement : function(options){ var ops = this.options; var element = options; this.elements.push(element); element.addEvents(this.bound); if(ops.events && ops.events[element.element.name]) element.addEvents(ops.events[element.element.name]); element.attach(ns.contains.call(ops.triggers, $triggers.blur)); }, add : function(o){ if(!Browser.loaded) { this.rules = this.rules || []; this.rules.push(o); } else { if(!o.validate) o = ns.Factory.Element.build(o); this.addElement(o); } return this; }, _add : function(){ if(!this.rules)return; for(var i = 0, l = this.rules.length; i < l; i ++) this.add(this.rules[i]); this.rules.empty(); this.rules = null; delete this.rules; }, parseEnmValue : function(prop, enums){ var ops = this.options; if(typeof(ops[prop]) == 'string'){ var properties = ops[prop]; ops[prop] = 0; properties.replace(/\s/g, '').split(',').each(function(key){ ops[prop] |= enums[key] || 0; }); ops[prop] = ops[prop] || 1; } } }); var AbstractElement = new Class({ Implements : [Events, Options], options : { element : null, trim : 'all', depend : false, require : true, warn : null, tips : null, empty : null, pass : null, action : null/*, onTips : $empty, onRemote : $empty, onSuccess : $empty, onFailure : $empty*/ }, initialize : function(options){ this.isValid = false; this.setOptions(options); this.options.require = this.toBoolean(this.options.require); this.element = $(this.options.element || this.options['for']); delete this.options.element; if (this.options.initialize) this.options.initialize.call(this); }, attach : function(validateOnBlur){ this.bound = {focus : this.focus.bind(this), 'blur' : this.blur.bind(this, validateOnBlur)}; if(Browser.Engine.webkit && this.element.type == 'file') {this.bound.change = this.bound.blur;delete this.bound.blur;} this.getMessagePanel(); this.fireEvent('onTips', [this, true]); this.element.addEvents(this.bound); }, focus : function(){ this.fireEvent('onTips', this); }, blur : function(validate){ if(!validate) {this.fireEvent('onTips', [this, true]);return;} this.validate(); }, beforeRemote : function(){}, afterRemote : function(json){ this.isValid = (json.state == 1); this.$json = json; this.$value = this.value; this.fireEvent(this.isValid ? 'onSuccess' : 'onFailure', this); }, remoteValidate : function(){ if(this.isValid && this.isRemote() && this.value != (this.$value || '')) { this.params = {}; this.params[this.element.name] = this.value; this.fireEvent('onRemote', this); var remote = new Request.JSON({url:this.options.action, onSuccess : function(json){ this.afterRemote(json); remote = null; }.bind(this), onFailure : function(){ this.afterRemote({state : 1, message : '\u62b1\u6b49\uff0c\u8fdc\u7a0b\u8fde\u63a5\u51fa\u9519\uff0c\u4f46\u662f\u60a8\u53ef\u4ee5\u6b63\u5e38\u63d0\u4ea4\u672c\u9879'}); remote = null; }.bind(this)} ).post(this.params); } }, success : function(){ if(this.options.require || this.value != '') { this.fireEvent('onSuccess', this); } }, failure : function(){ this.fireEvent('onFailure', this); }, getValue : function(){ return this.trim(this.element.get('value') || ''); }, getMessage : function(){ return (this.$json ? this.$json.message : this.options[this.isValid ? 'pass' : (this.value === '' ? 'empty' : 'warn')]) || '\28\u672a\u914d\u7f6e\u63d0\u793a\u4fe1\u606f\29'; }, trim : function(text){ var fn = ns.trim[this.options.trim]; return fn ? fn.call(text) : text; }, getMessagePanel : function(){ if(!this.panel && !(this.panel = $(this.element.name + '_message'))){ this.panel = new Element('div', { id : this.element.name + '_message'}); if(this.options.holder) this.panel.injectBefore($(this.options.holder));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -