validator.sea.js 11 KB

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