kaka.validator.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. kaka.validator = function(form, opts){
  2. var self = this;
  3. self.defaults = {
  4. form: '',
  5. enabled: 1,
  6. showContainer: false,
  7. focusClass: 'has-info',
  8. errorClass: 'has-error',
  9. successClass: 'has-success',
  10. onkeyup: false,
  11. onchange: true,
  12. onblur: true,
  13. onsubmit: true,
  14. trigger: false,
  15. skipErr: true,
  16. rules: {}
  17. };
  18. self.opts = $.extend(self.defaults, opts);
  19. self.opts.form = form;
  20. $('input, textarea, select', form).each(function(){
  21. var name = $(this).attr('name');
  22. var valid = $(this).attr('valid');
  23. var errorText = $(this).attr('errorText');
  24. var successText = $(this).attr('successText');
  25. var func = $(this).attr('func');
  26. var item = {};
  27. if (valid) {
  28. key = '[name="'+name+'"]';
  29. self.opts.rules[key] = {'valid':valid, 'errorText':errorText, 'successText':successText, 'func':func};
  30. }
  31. })
  32. //绑定事件
  33. self.bind = function() {
  34. var onfocus = function(DOM, rule) {
  35. var focusText = rule ? rule['focusText'] : $(DOM).attr('focusText');
  36. if (focusText) {
  37. self.tip('focus', $(DOM), focusText);
  38. }
  39. };
  40. if (self.opts.showContainer) {
  41. $(self.opts.showContainer).hide();
  42. }
  43. for(var item in self.opts.rules) {
  44. var el = item;
  45. var firstText = item.substr(0,1);
  46. if (firstText != '[' && firstText != '.' && firstText != '#') {
  47. var el = '[name='+item+']';
  48. }
  49. $(el, form).data('valid', self.opts.rules[item]);
  50. if (self.opts.onchange) {
  51. $(el, form).bind('change', function() { self.valid(this, $(this).data('valid')) });
  52. }
  53. if (self.opts.onkeyup) {
  54. $(el, form).bind('keyup', function() { self.valid(this, $(this).data('valid')) });
  55. }
  56. if (self.opts.onblur) {
  57. $(el, form).bind('blur', function() { self.valid(this, $(this).data('valid')) });
  58. $(el, form).bind('focus', function() { onfocus($(this), $(this).data('valid')) });
  59. }
  60. }
  61. $(form).submit( function () {
  62. return self.run(form);
  63. });
  64. };
  65. //开始验证
  66. self.run = function() {
  67. var form = self.opts.form;
  68. if (!self.opts.onsubmit || !self.opts.enabled) return true;
  69. var flag = true;
  70. var isFocus = false;
  71. for(var item in self.opts.rules) {
  72. var el = item;
  73. var firstText = item.substr(0,1);
  74. if (firstText != '[' && firstText != '.' && firstText != '#') {
  75. var el = '[name='+item+']';
  76. }
  77. if (self.valid($(el, form), self.opts.rules[item]) == false) {
  78. flag = false;
  79. if (!isFocus) {
  80. $(el, form).focus();
  81. isFocus = true;
  82. }
  83. if (!self.opts.skipErr) {
  84. return false;
  85. }
  86. }
  87. }
  88. if (self.opts.submitHandler) {
  89. flag = self.opts.submitHandler(flag, self.opts);
  90. }
  91. return flag;
  92. };
  93. self.tip = function (type, obj, msg) {
  94. var name = $(obj).attr('name') ? $(obj).attr('name') : $(obj).attr('id');
  95. try {
  96. v = name.split('[');
  97. for(i = 0; i < v.length; i++) {
  98. name = name.replace('[', '').replace(']', '');
  99. }
  100. } catch(e) {}
  101. switch (type) {
  102. /*case 'tip':
  103. var curClass = self.opts.tipClass;
  104. var curInputClass = self.opts.inputTipClass;
  105. break;*/
  106. case 'focus':
  107. var curClass = self.opts.focusClass;
  108. var curInputClass = self.opts.focusClass;
  109. break;
  110. case 'error':
  111. var curClass = self.opts.errorClass;
  112. var curInputClass = self.opts.errorClass;
  113. break;
  114. case 'success':
  115. var curClass = self.opts.successClass;
  116. var curInputClass = self.opts.successClass;
  117. break;
  118. }
  119. var html = msg ? '<p id="_'+name+'_msg" class="help-block '+curClass+' regex-tip"><i class="addon"></i>'+(msg ? msg : '&nbsp;')+'</p>' : '';
  120. if ($(obj).parents('.form-group').length > 0) {
  121. $(obj).parents('.form-group').removeClass(self.opts.focusClass);
  122. $(obj).parents('.form-group').removeClass(self.opts.successClass);
  123. $(obj).parents('.form-group').removeClass(self.opts.errorClass);
  124. //$(obj).parents('.form-group').removeClass(self.opts.inputTipClass);
  125. $(obj).parents('.form-group').addClass(curInputClass);
  126. } else {
  127. $(obj).removeClass(self.opts.focusClass);
  128. $(obj).removeClass(self.opts.successClass);
  129. $(obj).removeClass(self.opts.errorClass);
  130. //$(obj).removeClass(self.opts.inputTipClass);
  131. $(obj).addClass(curInputClass);
  132. }
  133. $('#_'+name+'_msg').remove();
  134. if (self.opts.showContainer) {
  135. if (!self.opts.skipErr) {
  136. $(self.opts.showContainer).empty();
  137. }
  138. $(self.opts.showContainer).show().append(html);
  139. } else {
  140. if ($(obj).parents('.input-group').length > 0) {
  141. $(obj).parents('.input-group').parent().append(html);
  142. } else {
  143. $(obj).parent().append(html);
  144. }
  145. }
  146. };
  147. self.valid = function(DOM, rule) {
  148. if ($(DOM).length <= 0) {
  149. return true;
  150. }
  151. var val = $(DOM).val();
  152. var func = rule ? rule['func'] : eval($(DOM).attr('func'));
  153. var validates = rule ? rule['valid'] : $(DOM).attr('valid');
  154. var errorTexts = rule ? rule['errorText'] : $(DOM).attr('errorText');
  155. var successText = rule ? rule['successText'] : $(DOM).attr('successText');
  156. var tip = function (type, obj, msg) {
  157. return self.tip(type, obj, msg);
  158. };
  159. if (validates) validates = validates.split('|'); else return true;
  160. if (errorTexts) errorTexts = errorTexts.split('|'); else return true;
  161. for (j=0; j<validates.length; j++) {
  162. var validate = validates[j];
  163. var errorText = errorTexts[j];
  164. if (errorTexts.length <= 1) {
  165. errorText = errorTexts[0];
  166. }
  167. if (!validate) { continue; }
  168. switch(validate) {
  169. case 'required':
  170. if (DOM.tagName == 'SELECT') {
  171. var v = $('option:selected', DOM).val();
  172. if (!v) {
  173. tip('error', $(DOM), errorText);
  174. return false;
  175. }
  176. } else if (DOM.length > 1) { //检测是否选项框
  177. var fg = 0;
  178. $(DOM).each(function(i) {
  179. if ($(this).prop('checked')) {
  180. fg = 1;
  181. return;
  182. }
  183. lastDom = this;
  184. })
  185. if (!fg) {
  186. tip('error', $(lastDom), errorText);
  187. return false;
  188. }
  189. return true;
  190. } else {
  191. if (val == '' || val == null) {
  192. tip('error', $(DOM), errorText);
  193. return false;
  194. }
  195. }
  196. break;
  197. case 'string':
  198. var patrn=/^[A-Za-z]+$/;
  199. if( !patrn.exec(val) && val != ''){
  200. tip('error', $(DOM), errorText);
  201. return false;
  202. }
  203. break;
  204. case 'password':
  205. var patrn=/^(.+){6,16}$/;
  206. if( !patrn.exec(val) && val != ''){
  207. tip('error', $(DOM), errorText);
  208. return false;
  209. }
  210. break;
  211. case 'strlen':
  212. var length = val.length;
  213. var arr = val.match(/[\u4e00-\u9fa5]/ig); //中文两字节
  214. if (arr != null) length += arr.length;
  215. _min = rule['minlen'] ? rule['minlen'] : $(DOM).attr('minlen');
  216. _max = rule['maxlen'] ? rule['maxlen'] : $(DOM).attr('maxlen');
  217. if (length < parseInt(_min) || length > parseInt(_max)) {
  218. tip('error', $(DOM), errorText);
  219. return false;
  220. }
  221. break;
  222. case 'range':
  223. _min = rule['min'] ? rule['min'] : $(DOM).attr('min');
  224. _max = rule['max'] ? rule['max'] : $(DOM).attr('max');
  225. var patrn=/^\d+(\.\d+)?$/;
  226. if( !patrn.exec(val) && val != ''){
  227. tip('error', $(DOM), errorText);
  228. return false;
  229. }
  230. if (parseInt(val) < parseInt(_min) || parseInt(val) > parseInt(_max)) {
  231. tip('error', $(DOM), errorText);
  232. return false;
  233. }
  234. break;
  235. case 'notZero':
  236. if (parseFloat(val) == 0) {
  237. tip('error', $(DOM), errorText);
  238. return false;
  239. }
  240. break;
  241. case 'equal':
  242. var compare = rule['compare'] ? rule['compare'] : $(DOM).attr('compare');
  243. if ($(compare).val() != val && compare != val) {
  244. tip('error', $(DOM), errorText);
  245. return false;
  246. }
  247. break;
  248. case 'notEqual':
  249. var compare = rule['compare'] ? rule['compare'] : $(DOM).attr('compare');
  250. if ($(compare).val() == val || compare == val) {
  251. tip('error', $(DOM), errorText);
  252. return false;
  253. }
  254. break;
  255. case 'email':
  256. var patrn=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
  257. if( !patrn.exec(val) && val != ''){
  258. tip('error', $(DOM), errorText);
  259. return false;
  260. }
  261. break;
  262. case 'numeric':
  263. var patrn=/^\d+(\.\d+)?$/;
  264. if( !patrn.exec(val) && val != ''){
  265. tip('error', $(DOM), errorText);
  266. return false;
  267. }
  268. break;
  269. case 'phone':
  270. var patrn=/^(0\d{2,3}\-?)?\d{6,11}$/;
  271. if( !patrn.exec(val) && val != ''){
  272. tip('error', $(DOM), errorText);
  273. return false;
  274. }
  275. break;
  276. case 'telphone':
  277. var patrn=/^(0\d{2,3}\-?)?\d{6,8}$/;
  278. if( !patrn.exec(val) && val != ''){
  279. tip('error', $(DOM), errorText);
  280. return false;
  281. }
  282. break;
  283. case 'mobile':
  284. var patrn=/^(1|01)\d{10}$/;
  285. if( !patrn.test(val) && val != ''){
  286. tip('error', $(DOM), errorText);
  287. return false;
  288. }
  289. break;
  290. case 'zipcode':
  291. var patrn=/^[1-9]\d{5}$/;
  292. if( !patrn.exec(val) && val != ''){
  293. tip('error', $(DOM), errorText);
  294. return false;
  295. }
  296. break;
  297. case 'chinese':
  298. var patrn=/[\u4e00-\u9fa5]/;
  299. if( !patrn.exec(val) && val != ''){
  300. tip('error', $(DOM), errorText);
  301. return false;
  302. }
  303. break;
  304. case 'currency':
  305. var patrn=/^\d+(?:\.\d{0,2})?$/;
  306. if( !patrn.exec(val) && val != ''){
  307. tip('error', $(DOM), errorText);
  308. return false;
  309. }
  310. break;
  311. case 'idcard':
  312. var patrn=/^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X)?$/;
  313. if( !patrn.exec(val) && val != ''){
  314. tip('error', $(DOM), errorText);
  315. return false;
  316. }
  317. break;
  318. default:
  319. var patrn=eval(rule ? rule['valid'] : $(DOM).attr('valid'));
  320. if( !patrn.exec(val) && val != ''){
  321. tip('error', $(DOM), errorText);
  322. return false;
  323. }
  324. break;
  325. }
  326. tip('success', $(DOM), successText);
  327. }
  328. //回调方法
  329. if (func) {
  330. msg = func($(DOM));
  331. if (msg != true) {
  332. tip('error', $(DOM), msg);
  333. return false;
  334. }
  335. }
  336. return true;
  337. };
  338. self.bind(form);
  339. return self;
  340. }