您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

378 行
13KB

  1. /**
  2. * Yii validation module.
  3. *
  4. * This JavaScript module provides the validation methods for the built-in validators.
  5. *
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright (c) 2008 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. * @author Qiang Xue <qiang.xue@gmail.com>
  10. * @since 2.0
  11. */
  12. yii.validation = (function ($) {
  13. var pub = {
  14. isEmpty: function (value) {
  15. return value === null || value === undefined || value == [] || value === '';
  16. },
  17. addMessage: function (messages, message, value) {
  18. messages.push(message.replace(/\{value\}/g, value));
  19. },
  20. required: function (value, messages, options) {
  21. var valid = false;
  22. if (options.requiredValue === undefined) {
  23. var isString = typeof value == 'string' || value instanceof String;
  24. if (options.strict && value !== undefined || !options.strict && !pub.isEmpty(isString ? $.trim(value) : value)) {
  25. valid = true;
  26. }
  27. } else if (!options.strict && value == options.requiredValue || options.strict && value === options.requiredValue) {
  28. valid = true;
  29. }
  30. if (!valid) {
  31. pub.addMessage(messages, options.message, value);
  32. }
  33. },
  34. boolean: function (value, messages, options) {
  35. if (options.skipOnEmpty && pub.isEmpty(value)) {
  36. return;
  37. }
  38. var valid = !options.strict && (value == options.trueValue || value == options.falseValue)
  39. || options.strict && (value === options.trueValue || value === options.falseValue);
  40. if (!valid) {
  41. pub.addMessage(messages, options.message, value);
  42. }
  43. },
  44. string: function (value, messages, options) {
  45. if (options.skipOnEmpty && pub.isEmpty(value)) {
  46. return;
  47. }
  48. if (typeof value !== 'string') {
  49. pub.addMessage(messages, options.message, value);
  50. return;
  51. }
  52. if (options.min !== undefined && value.length < options.min) {
  53. pub.addMessage(messages, options.tooShort, value);
  54. }
  55. if (options.max !== undefined && value.length > options.max) {
  56. pub.addMessage(messages, options.tooLong, value);
  57. }
  58. if (options.is !== undefined && value.length != options.is) {
  59. pub.addMessage(messages, options.notEqual, value);
  60. }
  61. },
  62. file: function (attribute, messages, options) {
  63. var files = getUploadedFiles(attribute, messages, options);
  64. $.each(files, function (i, file) {
  65. validateFile(file, messages, options);
  66. });
  67. },
  68. image: function (attribute, messages, options, deferred) {
  69. var files = getUploadedFiles(attribute, messages, options);
  70. $.each(files, function (i, file) {
  71. validateFile(file, messages, options);
  72. // Skip image validation if FileReader API is not available
  73. if (typeof FileReader === "undefined") {
  74. return;
  75. }
  76. var def = $.Deferred(),
  77. fr = new FileReader(),
  78. img = new Image();
  79. img.onload = function () {
  80. if (options.minWidth && this.width < options.minWidth) {
  81. messages.push(options.underWidth.replace(/\{file\}/g, file.name));
  82. }
  83. if (options.maxWidth && this.width > options.maxWidth) {
  84. messages.push(options.overWidth.replace(/\{file\}/g, file.name));
  85. }
  86. if (options.minHeight && this.height < options.minHeight) {
  87. messages.push(options.underHeight.replace(/\{file\}/g, file.name));
  88. }
  89. if (options.maxHeight && this.height > options.maxHeight) {
  90. messages.push(options.overHeight.replace(/\{file\}/g, file.name));
  91. }
  92. def.resolve();
  93. };
  94. img.onerror = function () {
  95. messages.push(options.notImage.replace(/\{file\}/g, file.name));
  96. def.resolve();
  97. };
  98. fr.onload = function () {
  99. img.src = fr.result;
  100. };
  101. // Resolve deferred if there was error while reading data
  102. fr.onerror = function () {
  103. def.resolve();
  104. };
  105. fr.readAsDataURL(file);
  106. deferred.push(def);
  107. });
  108. },
  109. number: function (value, messages, options) {
  110. if (options.skipOnEmpty && pub.isEmpty(value)) {
  111. return;
  112. }
  113. if (typeof value === 'string' && !value.match(options.pattern)) {
  114. pub.addMessage(messages, options.message, value);
  115. return;
  116. }
  117. if (options.min !== undefined && value < options.min) {
  118. pub.addMessage(messages, options.tooSmall, value);
  119. }
  120. if (options.max !== undefined && value > options.max) {
  121. pub.addMessage(messages, options.tooBig, value);
  122. }
  123. },
  124. range: function (value, messages, options) {
  125. if (options.skipOnEmpty && pub.isEmpty(value)) {
  126. return;
  127. }
  128. if (!options.allowArray && $.isArray(value)) {
  129. pub.addMessage(messages, options.message, value);
  130. return;
  131. }
  132. var inArray = true;
  133. $.each($.isArray(value) ? value : [value], function(i, v) {
  134. if ($.inArray(v, options.range) == -1) {
  135. inArray = false;
  136. return false;
  137. } else {
  138. return true;
  139. }
  140. });
  141. if (options.not === inArray) {
  142. pub.addMessage(messages, options.message, value);
  143. }
  144. },
  145. regularExpression: function (value, messages, options) {
  146. if (options.skipOnEmpty && pub.isEmpty(value)) {
  147. return;
  148. }
  149. if (!options.not && !value.match(options.pattern) || options.not && value.match(options.pattern)) {
  150. pub.addMessage(messages, options.message, value);
  151. }
  152. },
  153. email: function (value, messages, options) {
  154. if (options.skipOnEmpty && pub.isEmpty(value)) {
  155. return;
  156. }
  157. var valid = true;
  158. if (options.enableIDN) {
  159. var regexp = /^(.*<?)(.*)@(.*)(>?)$/,
  160. matches = regexp.exec(value);
  161. if (matches === null) {
  162. valid = false;
  163. } else {
  164. value = matches[1] + punycode.toASCII(matches[2]) + '@' + punycode.toASCII(matches[3]) + matches[4];
  165. }
  166. }
  167. if (!valid || !(value.match(options.pattern) || (options.allowName && value.match(options.fullPattern)))) {
  168. pub.addMessage(messages, options.message, value);
  169. }
  170. },
  171. url: function (value, messages, options) {
  172. if (options.skipOnEmpty && pub.isEmpty(value)) {
  173. return;
  174. }
  175. if (options.defaultScheme && !value.match(/:\/\//)) {
  176. value = options.defaultScheme + '://' + value;
  177. }
  178. var valid = true;
  179. if (options.enableIDN) {
  180. var regexp = /^([^:]+):\/\/([^\/]+)(.*)$/,
  181. matches = regexp.exec(value);
  182. if (matches === null) {
  183. valid = false;
  184. } else {
  185. value = matches[1] + '://' + punycode.toASCII(matches[2]) + matches[3];
  186. }
  187. }
  188. if (!valid || !value.match(options.pattern)) {
  189. pub.addMessage(messages, options.message, value);
  190. }
  191. },
  192. trim: function ($form, attribute, options) {
  193. var $input = $form.find(attribute.input);
  194. var value = $input.val();
  195. if (!options.skipOnEmpty || !pub.isEmpty(value)) {
  196. $input.val($.trim(value));
  197. }
  198. },
  199. captcha: function (value, messages, options) {
  200. if (options.skipOnEmpty && pub.isEmpty(value)) {
  201. return;
  202. }
  203. // CAPTCHA may be updated via AJAX and the updated hash is stored in body data
  204. var hash = $('body').data(options.hashKey);
  205. if (hash == null) {
  206. hash = options.hash;
  207. } else {
  208. hash = hash[options.caseSensitive ? 0 : 1];
  209. }
  210. var v = options.caseSensitive ? value : value.toLowerCase();
  211. for (var i = v.length - 1, h = 0; i >= 0; --i) {
  212. h += v.charCodeAt(i);
  213. }
  214. if (h != hash) {
  215. pub.addMessage(messages, options.message, value);
  216. }
  217. },
  218. compare: function (value, messages, options) {
  219. if (options.skipOnEmpty && pub.isEmpty(value)) {
  220. return;
  221. }
  222. var compareValue, valid = true;
  223. if (options.compareAttribute === undefined) {
  224. compareValue = options.compareValue;
  225. } else {
  226. compareValue = $('#' + options.compareAttribute).val();
  227. }
  228. if (options.type === 'number') {
  229. value = parseFloat(value);
  230. compareValue = parseFloat(compareValue);
  231. }
  232. switch (options.operator) {
  233. case '==':
  234. valid = value == compareValue;
  235. break;
  236. case '===':
  237. valid = value === compareValue;
  238. break;
  239. case '!=':
  240. valid = value != compareValue;
  241. break;
  242. case '!==':
  243. valid = value !== compareValue;
  244. break;
  245. case '>':
  246. valid = parseFloat(value) > parseFloat(compareValue);
  247. break;
  248. case '>=':
  249. valid = parseFloat(value) >= parseFloat(compareValue);
  250. break;
  251. case '<':
  252. valid = parseFloat(value) < parseFloat(compareValue);
  253. break;
  254. case '<=':
  255. valid = parseFloat(value) <= parseFloat(compareValue);
  256. break;
  257. default:
  258. valid = false;
  259. break;
  260. }
  261. if (!valid) {
  262. pub.addMessage(messages, options.message, value);
  263. }
  264. }
  265. };
  266. function getUploadedFiles(attribute, messages, options) {
  267. // Skip validation if File API is not available
  268. if (typeof File === "undefined") {
  269. return [];
  270. }
  271. var files = $(attribute.input).get(0).files;
  272. if (!files) {
  273. messages.push(options.message);
  274. return [];
  275. }
  276. if (files.length === 0) {
  277. if (!options.skipOnEmpty) {
  278. messages.push(options.uploadRequired);
  279. }
  280. return [];
  281. }
  282. if (options.maxFiles && options.maxFiles < files.length) {
  283. messages.push(options.tooMany);
  284. return [];
  285. }
  286. return files;
  287. }
  288. function validateFile(file, messages, options) {
  289. if (options.extensions && options.extensions.length > 0) {
  290. var index, ext;
  291. index = file.name.lastIndexOf('.');
  292. if (!~index) {
  293. ext = '';
  294. } else {
  295. ext = file.name.substr(index + 1, file.name.length).toLowerCase();
  296. }
  297. if (!~options.extensions.indexOf(ext)) {
  298. messages.push(options.wrongExtension.replace(/\{file\}/g, file.name));
  299. }
  300. }
  301. if (options.mimeTypes && options.mimeTypes.length > 0) {
  302. if (!~options.mimeTypes.indexOf(file.type)) {
  303. messages.push(options.wrongMimeType.replace(/\{file\}/g, file.name));
  304. }
  305. }
  306. if (options.maxSize && options.maxSize < file.size) {
  307. messages.push(options.tooBig.replace(/\{file\}/g, file.name));
  308. }
  309. if (options.minSize && options.minSize > file.size) {
  310. messages.push(options.tooSmall.replace(/\{file\}/g, file.name));
  311. }
  312. }
  313. return pub;
  314. })(jQuery);