1(function($) { 2 3 var rules = { 4 required: { 5 selector: '.required', 6 rule: function($el) { 7 return ($el.attr('type') != 'checkbox' && $el.val().length > 0) || $el.attr('checked'); 8 } 9 }, 10 notdefault: { 11 selector: '.notdefault', 12 rule: function($el) { 13 return $el.val() != $el[0].defaultValue; 14 } 15 }, 16 email: { selector: '.email', rule: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i }, 17 date: { selector: '.date', rule: /^[0-3]?[0-9]\/[0123]?[0-9]\/[12][09][0-9][0-9]$/ }, 18 numeric: { selector: '.numeric', rule: /^[\d]*(\.[\d]{1,})?$/ }, 19 url: { selector: '.url', rule: /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/ } 20 }; 21 22 23 var methods = { 24 init: function(options) { 25 26 var settings = { 27 'refocus': true, 28 'invalidClass': 'alert', 29 'invalidSelector': 'label[for=<<id>>]', 30 'invalidCallback': null, 31 'validCallback': null, 32 'smother': false 33 }; 34 35 if(options) { 36 $.extend(settings, options); 37 } 38 39 return this.each(function() { 40 41 var $this = $(this); 42 43 $this.bind('submit.legit', function(e) { 44 45 if(settings.smother) { 46 e.preventDefault(); 47 } 48 49 var feedback = '', focus = false, tmpSelector; 50 51 $this.find('input[type="password"]:enabled, input[type="file"]:enabled, input[type="text"]:enabled, input[type="checkbox"]:enabled, select:enabled, textarea:enabled').each(function() { 52 53 var $el = $(this), valid = true; 54 55 for(var i in rules) { 56 57 if($el.is(rules[i].selector)) { 58 59 if(i != 'required' && $el.val().length == 0) { 60 //the field is empty and only the required rule tests empty fields 61 continue; 62 } 63 64 if(typeof rules[i].rule.test == 'function') { 65 if(!rules[i].rule.test($el.val())) { 66 valid = false; 67 } 68 } 69 else if(typeof rules[i].rule == 'function' && !rules[i].rule($el)) { 70 valid = false; 71 } 72 73 } 74 75 } 76 77 tmpSelector = false; 78 if(settings.invalidSelector) { 79 80 tmpSelector = settings.invalidSelector; 81 82 if($el.attr('id') && $el.attr('id').length > 0) { 83 tmpSelector = tmpSelector.replace(/<<id>>/g, $el.attr('id')); 84 } 85 86 if($el.attr('name') && $el.attr('name').length > 0) { 87 tmpSelector = tmpSelector.replace(/<<name>>/g, $el.attr('name')) 88 } 89 } 90 91 if(!valid) { 92 93 if(settings.invalidClass) { 94 if(tmpSelector) { 95 $(tmpSelector).addClass(settings.invalidClass); 96 } 97 else { 98 $el.addClass(settings.invalidClass); 99 } 100 } 101 102 feedback += $el.attr('title') + "\n"; 103 if(!focus) focus = $el; 104 } 105 else { 106 107 if(settings.invalidClass) { 108 if(tmpSelector) { 109 $(tmpSelector).removeClass(settings.invalidClass); 110 } 111 else { 112 $el.removeClass(settings.invalidClass); 113 } 114 } 115 } 116 117 }); 118 119 if(feedback.length > 0) { 120 121 if(settings.refocus) focus.focus(); 122 123 if(typeof settings.invalidCallback == 'function') { 124 return settings.invalidCallback(feedback); 125 } 126 else { 127 alert(feedback); 128 return false; 129 } 130 } 131 132 if(typeof settings.validCallback == 'function') { 133 return settings.validCallback(feedback); 134 } 135 else { 136 return true; 137 } 138 }); 139 }); 140 }, //init 141 142 destroy: function() { 143 144 this.unbind('.legit'); 145 146 return this; 147 }, //destroy 148 149 addRule: function(name, rule) { 150 151 rules[name] = rule; 152 153 return this; 154 } 155 }; 156 157 $.fn.legit = function(method) { 158 if(methods[method]) { 159 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 160 } 161 else if(typeof method === 'object' || !method) { 162 return methods.init.apply(this, arguments); 163 } 164 else { 165 $.error('Method ' + method + ' does not exist on jQuery.legit'); 166 } 167 } 168 169})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.