bootstrapValidator.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. /**
  2. * BootstrapValidator (http://github.com/nghuuphuoc/bootstrapvalidator)
  3. *
  4. * A jQuery plugin to validate form fields. Use with Bootstrap 3
  5. *
  6. * @version v0.3.0
  7. * @author https://twitter.com/nghuuphuoc
  8. * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc
  9. * @license MIT
  10. */
  11. (function($) {
  12. var BootstrapValidator = function(form, options) {
  13. this.$form = $(form);
  14. this.options = $.extend({}, BootstrapValidator.DEFAULT_OPTIONS, options);
  15. // Array of deferred
  16. this._dfds = {};
  17. // First invalid field
  18. this._firstInvalidField = null;
  19. // Validating results
  20. this._results = {};
  21. this._init();
  22. };
  23. // The default options
  24. BootstrapValidator.DEFAULT_OPTIONS = {
  25. // The form CSS class
  26. elementClass: 'bootstrap-validator-form',
  27. // Default invalid message
  28. message: 'This value is not valid',
  29. // The number of grid columns
  30. // Change it if you use custom grid with different number of columns
  31. columns: 12,
  32. // The custom submit handler
  33. // It will prevent the form from the default submission
  34. //
  35. // submitHandler: function(validator, form) {
  36. // - validator is the BootstrapValidator instance
  37. // - form is the jQuery object present the current form
  38. // }
  39. submitHandler: null,
  40. // Live validating option
  41. // Can be one of 3 values:
  42. // - enabled: The plugin validates fields as soon as they are changed
  43. // - disabled: Disable the live validating. The error messages are only shown after the form is submitted
  44. // - submitted: The live validating is enabled after the form is submitted
  45. live: 'enabled',
  46. // Map the field name with validator rules
  47. fields: null
  48. };
  49. BootstrapValidator.prototype = {
  50. constructor: BootstrapValidator,
  51. /**
  52. * Init form
  53. */
  54. _init: function() {
  55. if (this.options.fields == null) {
  56. return;
  57. }
  58. var that = this;
  59. this.$form
  60. // Disable client side validation in HTML 5
  61. .attr('novalidate', 'novalidate')
  62. .addClass(this.options.elementClass)
  63. // Disable the default submission first
  64. .on('submit.bootstrapValidator', function(e) {
  65. e.preventDefault();
  66. that.validate();
  67. });
  68. for (var field in this.options.fields) {
  69. this._initField(field);
  70. }
  71. this._setLiveValidating();
  72. },
  73. /**
  74. * Init field
  75. *
  76. * @param {String} field The field name
  77. */
  78. _initField: function(field) {
  79. if (this.options.fields[field] == null || this.options.fields[field].validators == null) {
  80. return;
  81. }
  82. this._dfds[field] = {};
  83. this._results[field] = {};
  84. var fields = this.$form.find('[name="' + field + '"]');
  85. // We don't need to validate ...
  86. if (fields.length == 0 // ... non-existing fields
  87. || (fields.length == 1 && fields.is(':disabled'))) // ... disabled field
  88. {
  89. delete this.options.fields[field];
  90. delete this._dfds[field];
  91. return;
  92. }
  93. // Create a help block element for showing the error
  94. var $field = $(fields[0]),
  95. $parent = $field.parents('.form-group'),
  96. // Calculate the number of columns of the label/field element
  97. // Then set offset to the help block element
  98. label, cssClasses, offset, size;
  99. if (label = $parent.find('label').get(0)) {
  100. // The default Bootstrap form don't require class for label (http://getbootstrap.com/css/#forms)
  101. if (cssClasses = $(label).attr('class')) {
  102. cssClasses = cssClasses.split(' ');
  103. for (var i = 0; i < cssClasses.length; i++) {
  104. if (/^col-(xs|sm|md|lg)-\d+$/.test(cssClasses[i])) {
  105. offset = cssClasses[i].substr(7);
  106. size = cssClasses[i].substr(4, 2);
  107. break;
  108. }
  109. }
  110. }
  111. } else if (cssClasses = $parent.children().eq(0).attr('class')) {
  112. cssClasses = cssClasses.split(' ');
  113. for (var i = 0; i < cssClasses.length; i++) {
  114. if (/^col-(xs|sm|md|lg)-offset-\d+$/.test(cssClasses[i])) {
  115. offset = cssClasses[i].substr(14);
  116. size = cssClasses[i].substr(4, 2);
  117. break;
  118. }
  119. }
  120. }
  121. if (size && offset) {
  122. for (var validatorName in this.options.fields[field].validators) {
  123. if (!$.fn.bootstrapValidator.validators[validatorName]) {
  124. delete this.options.fields[field].validators[validatorName];
  125. continue;
  126. }
  127. this._results[field][validatorName] = null;
  128. $('<small/>')
  129. .css('display', 'none')
  130. .attr('data-bs-validator', validatorName)
  131. .addClass('help-block')
  132. .addClass(['col-', size, '-offset-', offset].join(''))
  133. .addClass(['col-', size, '-', this.options.columns - offset].join(''))
  134. .appendTo($parent);
  135. }
  136. }
  137. },
  138. /**
  139. * Enable live validating
  140. */
  141. _setLiveValidating: function() {
  142. if ('enabled' == this.options.live) {
  143. var that = this;
  144. // Since this should be called once, I have to disable the live validating mode
  145. this.options.live = 'disabled';
  146. for (var field in this.options.fields) {
  147. (function(f) {
  148. var fields = that.getFieldElements(f);
  149. if (fields) {
  150. var type = fields.attr('type'),
  151. event = ('radio' == type || 'checkbox' == type || 'SELECT' == fields[0].tagName) ? 'change' : 'keyup';
  152. fields.on(event, function() {
  153. that.validateField(f);
  154. });
  155. }
  156. })(field);
  157. }
  158. }
  159. },
  160. /**
  161. * Called when all validations are completed
  162. */
  163. _submit: function() {
  164. if (!this.isValid()) {
  165. if ('submitted' == this.options.live) {
  166. this.options.live = 'enabled';
  167. this._setLiveValidating();
  168. }
  169. // Focus to the first invalid field
  170. if (this._firstInvalidField) {
  171. this.getFieldElements(this._firstInvalidField).focus();
  172. }
  173. return;
  174. }
  175. // Call the custom submission if enabled
  176. if (this.options.submitHandler && 'function' == typeof this.options.submitHandler) {
  177. this.options.submitHandler.call(this, this, this.$form);
  178. } else {
  179. // Submit form
  180. this.$form.off('submit.bootstrapValidator').submit();
  181. }
  182. },
  183. // --- Public methods ---
  184. /**
  185. * Retrieve the field elements by given name
  186. *
  187. * @param {String} field The field name
  188. * @returns {null|jQuery[]}
  189. */
  190. getFieldElements: function(field) {
  191. var fields = this.$form.find('[name="' + field + '"]');
  192. return (fields.length == 0) ? null : fields;
  193. },
  194. /**
  195. * Validate the form
  196. */
  197. validate: function() {
  198. if (!this.options.fields) {
  199. return;
  200. }
  201. for (var field in this.options.fields) {
  202. this.validateField(field);
  203. }
  204. this._submit();
  205. },
  206. /**
  207. * Validate given field
  208. *
  209. * @param {String} field The field name
  210. */
  211. validateField: function(field) {
  212. var that = this,
  213. fields = this.$form.find('[name="' + field + '"]'),
  214. $field = $(fields[0]),
  215. validators = this.options.fields[field].validators,
  216. validatorName,
  217. validateResult;
  218. for (validatorName in validators) {
  219. if (this._dfds[field][validatorName]) {
  220. this._dfds[field][validatorName].reject();
  221. }
  222. validateResult = $.fn.bootstrapValidator.validators[validatorName].validate(this, $field, validators[validatorName]);
  223. if ('object' == typeof validateResult) {
  224. this._dfds[field][validatorName] = validateResult;
  225. validateResult.done(function(isValid, v) {
  226. // v is validator name
  227. delete that._dfds[field][v];
  228. /*
  229. if (isValid) {
  230. that._submit();
  231. }*/
  232. });
  233. }
  234. $.when(validateResult).then(function(isValid) {
  235. that._results[field][validatorName] = isValid;
  236. if (isValid) {
  237. that.removeError($field, validatorName);
  238. } else {
  239. that.showError($field, validatorName);
  240. }
  241. });
  242. }
  243. },
  244. /**
  245. * Check the form validity
  246. *
  247. * @returns {Boolean}
  248. */
  249. isValid: function() {
  250. var field, validatorName;
  251. for (field in this._results) {
  252. for (validatorName in this._results[field]) {
  253. if (!this._results[field][validatorName]) {
  254. this._firstInvalidField = field;
  255. return false;
  256. }
  257. }
  258. }
  259. return true;
  260. },
  261. /**
  262. * Show field error
  263. *
  264. * @param {jQuery} $field The field element
  265. * @param {String} validatorName
  266. */
  267. showError: function($field, validatorName) {
  268. var field = $field.attr('name'),
  269. validator = this.options.fields[field].validators[validatorName],
  270. message = validator.message || this.options.message;
  271. // Add has-error class to parent element
  272. $field
  273. .parents('.form-group')
  274. .removeClass('has-success')
  275. .addClass('has-error')
  276. .find('.help-block[data-bs-validator="' + validatorName + '"]')
  277. .html(message)
  278. .show();
  279. },
  280. /**
  281. * Remove error from given field
  282. *
  283. * @param {jQuery} $field The field element
  284. */
  285. removeError: function($field, validatorName) {
  286. $field
  287. .parents('.form-group')
  288. .removeClass('has-error')
  289. .addClass('has-success')
  290. .find('.help-block[data-bs-validator="' + validatorName + '"]')
  291. .hide();
  292. }
  293. };
  294. // Plugin definition
  295. $.fn.bootstrapValidator = function(options) {
  296. return this.each(function() {
  297. var $this = $(this), data = $this.data('bootstrapValidator');
  298. if (!data) {
  299. $this.data('bootstrapValidator', new BootstrapValidator(this, options));
  300. }
  301. });
  302. };
  303. // Available validators
  304. $.fn.bootstrapValidator.validators = {};
  305. $.fn.bootstrapValidator.Constructor = BootstrapValidator;
  306. }(window.jQuery));
  307. ;(function($) {
  308. $.fn.bootstrapValidator.validators.between = {
  309. /**
  310. * Return true if the input value is between (strictly or not) two given numbers
  311. *
  312. * @param {BootstrapValidator} validator The validator plugin instance
  313. * @param {jQuery} $field Field element
  314. * @param {Object} options Can consist of the following keys:
  315. * - min
  316. * - max
  317. * - inclusive [optional]: Can be true or false. Default is true
  318. * - message: The invalid message
  319. * @returns {Boolean}
  320. */
  321. validate: function(validator, $field, options) {
  322. var value = $field.val();
  323. if (value == '') {
  324. return true;
  325. }
  326. value = parseFloat(value);
  327. return (options.inclusive === true)
  328. ? (value > options.min && value < options.max)
  329. : (value >= options.min && value <= options.max);
  330. }
  331. };
  332. }(window.jQuery));
  333. ;(function($) {
  334. $.fn.bootstrapValidator.validators.callback = {
  335. /**
  336. * Return result from the callback method
  337. *
  338. * @param {BootstrapValidator} validator The validator plugin instance
  339. * @param {jQuery} $field Field element
  340. * @param {Object} options Can consist of the following keys:
  341. * - callback: The callback method that passes 2 parameters:
  342. * callback: function(fieldValue, validator) {
  343. * // fieldValue is the value of field
  344. * // validator is instance of BootstrapValidator
  345. * }
  346. * - message: The invalid message
  347. * @returns {Boolean|Deferred}
  348. */
  349. validate: function(validator, $field, options) {
  350. var value = $field.val();
  351. if (options.callback && 'function' == typeof options.callback) {
  352. var dfd = new $.Deferred();
  353. dfd.resolve(options.callback.call(this, value, validator), 'callback');
  354. return dfd;
  355. }
  356. return true;
  357. }
  358. };
  359. }(window.jQuery));
  360. ;(function($) {
  361. $.fn.bootstrapValidator.validators.choice = {
  362. /**
  363. * Check if the number of checked boxes are less or more than a given number
  364. *
  365. * @param {BootstrapValidator} validator The validator plugin instance
  366. * @param {jQuery} $field Field element
  367. * @param {Object} options Consists of following keys:
  368. * - min
  369. * - max
  370. * At least one of two keys is required
  371. * @returns {Boolean}
  372. */
  373. validate: function(validator, $field, options) {
  374. var numChoices = validator
  375. .getFieldElements($field.attr('name'))
  376. .filter(':checked')
  377. .length;
  378. if ((options.min && numChoices < options.min) || (options.max && numChoices > options.max)) {
  379. return false;
  380. }
  381. return true;
  382. }
  383. };
  384. }(window.jQuery));
  385. ;(function($) {
  386. $.fn.bootstrapValidator.validators.creditCard = {
  387. /**
  388. * Return true if the input value is valid credit card number
  389. * Based on https://gist.github.com/DiegoSalazar/4075533
  390. *
  391. * @param {BootstrapValidator} validator The validator plugin instance
  392. * @param {jQuery} $field Field element
  393. * @param {Object} options Can consist of the following key:
  394. * - message: The invalid message
  395. * @returns {Boolean}
  396. */
  397. validate: function(validator, $field, options) {
  398. var value = $field.val();
  399. if (value == '') {
  400. return true;
  401. }
  402. // Accept only digits, dashes or spaces
  403. if (/[^0-9-\s]+/.test(value)) {
  404. return false;
  405. }
  406. // The Luhn Algorithm
  407. // http://en.wikipedia.org/wiki/Luhn
  408. value = value.replace(/\D/g, '');
  409. var check = 0, digit = 0, even = false, length = value.length;
  410. for (var n = length - 1; n >= 0; n--) {
  411. digit = parseInt(value.charAt(n), 10);
  412. if (even) {
  413. if ((digit *= 2) > 9) {
  414. digit -= 9;
  415. }
  416. }
  417. check += digit;
  418. even = !even;
  419. }
  420. return (check % 10) == 0;
  421. }
  422. };
  423. }(window.jQuery));
  424. ;(function($) {
  425. $.fn.bootstrapValidator.validators.different = {
  426. /**
  427. * Return true if the input value is different with given field's value
  428. *
  429. * @param {BootstrapValidator} validator The validator plugin instance
  430. * @param {jQuery} $field Field element
  431. * @param {Object} options Consists of the following key:
  432. * - field: The name of field that will be used to compare with current one
  433. * @returns {Boolean}
  434. */
  435. validate: function(validator, $field, options) {
  436. var value = $field.val();
  437. if (value == '') {
  438. return true;
  439. }
  440. var compareWith = validator.getFieldElements(options.field);
  441. if (compareWith == null) {
  442. return true;
  443. }
  444. if (value != compareWith.val()) {
  445. validator.removeError(compareWith, 'different');
  446. return true;
  447. } else {
  448. return false;
  449. }
  450. }
  451. };
  452. }(window.jQuery));
  453. ;(function($) {
  454. $.fn.bootstrapValidator.validators.digits = {
  455. /**
  456. * Return true if the input value contains digits only
  457. *
  458. * @param {BootstrapValidator} validator Validate plugin instance
  459. * @param {jQuery} $field Field element
  460. * @param {Object} options
  461. * @returns {Boolean}
  462. */
  463. validate: function(validator, $field, options) {
  464. var value = $field.val();
  465. if (value == '') {
  466. return true;
  467. }
  468. return /^\d+$/.test(value);
  469. }
  470. }
  471. }(window.jQuery));
  472. ;(function($) {
  473. $.fn.bootstrapValidator.validators.emailAddress = {
  474. /**
  475. * Return true if and only if the input value is a valid email address
  476. *
  477. * @param {BootstrapValidator} validator Validate plugin instance
  478. * @param {jQuery} $field Field element
  479. * @param {Object} options
  480. * @returns {Boolean}
  481. */
  482. validate: function(validator, $field, options) {
  483. var value = $field.val();
  484. if (value == '') {
  485. return true;
  486. }
  487. // Email address regular expression
  488. // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
  489. var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  490. return emailRegExp.test(value);
  491. }
  492. }
  493. }(window.jQuery));
  494. ;(function($) {
  495. $.fn.bootstrapValidator.validators.greaterThan = {
  496. /**
  497. * Return true if the input value is greater than or equals to given number
  498. *
  499. * @param {BootstrapValidator} validator Validate plugin instance
  500. * @param {jQuery} $field Field element
  501. * @param {Object} options Can consist of the following keys:
  502. * - value: The number used to compare to
  503. * - inclusive [optional]: Can be true or false. Default is true
  504. * - message: The invalid message
  505. * @returns {Boolean}
  506. */
  507. validate: function(validator, $field, options) {
  508. var value = $field.val();
  509. if (value == '') {
  510. return true;
  511. }
  512. value = parseFloat(value);
  513. return (options.inclusive === true) ? (value > options.value) : (value >= options.value);
  514. }
  515. }
  516. }(window.jQuery));
  517. ;(function($) {
  518. $.fn.bootstrapValidator.validators.hexColor = {
  519. /**
  520. * Return true if the input value is a valid hex color
  521. *
  522. * @param {BootstrapValidator} validator The validator plugin instance
  523. * @param {jQuery} $field Field element
  524. * @param {Object} options Can consist of the following keys:
  525. * - message: The invalid message
  526. * @returns {Boolean}
  527. */
  528. validate: function(validator, $field, options) {
  529. var value = $field.val();
  530. if (value == '') {
  531. return true;
  532. }
  533. return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(value);
  534. }
  535. };
  536. }(window.jQuery));
  537. ;(function($) {
  538. $.fn.bootstrapValidator.validators.identical = {
  539. /**
  540. * Check if input value equals to value of particular one
  541. *
  542. * @param {BootstrapValidator} validator The validator plugin instance
  543. * @param {jQuery} $field Field element
  544. * @param {Object} options Consists of the following key:
  545. * - field: The name of field that will be used to compare with current one
  546. * @returns {Boolean}
  547. */
  548. validate: function(validator, $field, options) {
  549. var value = $field.val();
  550. if (value == '') {
  551. return true;
  552. }
  553. var compareWith = validator.getFieldElements(options.field);
  554. if (compareWith == null) {
  555. return true;
  556. }
  557. if (value == compareWith.val()) {
  558. validator.removeError(compareWith, 'identical');
  559. return true;
  560. } else {
  561. return false;
  562. }
  563. }
  564. };
  565. }(window.jQuery));
  566. ;(function($) {
  567. $.fn.bootstrapValidator.validators.lessThan = {
  568. /**
  569. * Return true if the input value is less than or equal to given number
  570. *
  571. * @param {BootstrapValidator} validator The validator plugin instance
  572. * @param {jQuery} $field Field element
  573. * @param {Object} options Can consist of the following keys:
  574. * - value: The number used to compare to
  575. * - inclusive [optional]: Can be true or false. Default is true
  576. * - message: The invalid message
  577. * @returns {Boolean}
  578. */
  579. validate: function(validator, $field, options) {
  580. var value = $field.val();
  581. if (value == '') {
  582. return true;
  583. }
  584. value = parseFloat(value);
  585. return (options.inclusive === true) ? (value < options.value) : (value <= options.value);
  586. }
  587. };
  588. }(window.jQuery));
  589. ;(function($) {
  590. $.fn.bootstrapValidator.validators.notEmpty = {
  591. /**
  592. * Check if input value is empty or not
  593. *
  594. * @param {BootstrapValidator} validator The validator plugin instance
  595. * @param {jQuery} $field Field element
  596. * @param {Object} options
  597. * @returns {Boolean}
  598. */
  599. validate: function(validator, $field, options) {
  600. var type = $field.attr('type');
  601. if ('radio' == type || 'checkbox' == type) {
  602. return validator
  603. .getFieldElements($field.attr('name'))
  604. .filter(':checked')
  605. .length > 0;
  606. }
  607. return $.trim($field.val()) != '';
  608. }
  609. };
  610. }(window.jQuery));
  611. ;(function($) {
  612. $.fn.bootstrapValidator.validators.regexp = {
  613. /**
  614. * Check if the element value matches given regular expression
  615. *
  616. * @param {BootstrapValidator} validator The validator plugin instance
  617. * @param {jQuery} $field Field element
  618. * @param {Object} options Consists of the following key:
  619. * - regexp: The regular expression you need to check
  620. * @returns {Boolean}
  621. */
  622. validate: function(validator, $field, options) {
  623. var value = $field.val();
  624. if (value == '') {
  625. return true;
  626. }
  627. return options.regexp.test(value);
  628. }
  629. };
  630. }(window.jQuery));
  631. ;(function($) {
  632. $.fn.bootstrapValidator.validators.remote = {
  633. /**
  634. * Request a remote server to check the input value
  635. *
  636. * @param {BootstrapValidator} validator Plugin instance
  637. * @param {jQuery} $field Field element
  638. * @param {Object} options Can consist of the following keys:
  639. * - url
  640. * - data [optional]: By default, it will take the value
  641. * {
  642. * <fieldName>: <fieldValue>
  643. * }
  644. * - message: The invalid message
  645. * @returns {Boolean|Deferred}
  646. */
  647. validate: function(validator, $field, options) {
  648. var value = $field.val();
  649. if (value == '') {
  650. return true;
  651. }
  652. var name = $field.attr('name'), data = options.data;
  653. if (data == null) {
  654. data = {};
  655. }
  656. data[name] = value;
  657. var dfd = new $.Deferred();
  658. var xhr = $.ajax({
  659. type: 'POST',
  660. url: options.url,
  661. dataType: 'json',
  662. data: data
  663. });
  664. xhr.then(function(response) {
  665. dfd.resolve(response.valid === true || response.valid === 'true', 'remote');
  666. });
  667. dfd.fail(function() {
  668. xhr.abort();
  669. });
  670. return dfd;
  671. }
  672. };
  673. }(window.jQuery));
  674. ;(function($) {
  675. $.fn.bootstrapValidator.validators.stringLength = {
  676. /**
  677. * Check if the length of element value is less or more than given number
  678. *
  679. * @param {BootstrapValidator} validator The validator plugin instance
  680. * @param {jQuery} $field Field element
  681. * @param {Object} options Consists of following keys:
  682. * - min
  683. * - max
  684. * At least one of two keys is required
  685. * @returns {Boolean}
  686. */
  687. validate: function(validator, $field, options) {
  688. var value = $field.val();
  689. if (value == '') {
  690. return true;
  691. }
  692. var length = $.trim(value).length;
  693. if ((options.min && length < options.min) || (options.max && length > options.max)) {
  694. return false;
  695. }
  696. return true;
  697. }
  698. };
  699. }(window.jQuery));
  700. ;(function($) {
  701. $.fn.bootstrapValidator.validators.uri = {
  702. /**
  703. * Return true if the input value is a valid URL
  704. *
  705. * @param {BootstrapValidator} validator The validator plugin instance
  706. * @param {jQuery} $field Field element
  707. * @param {Object} options
  708. * @returns {Boolean}
  709. */
  710. validate: function(validator, $field, options) {
  711. var value = $field.val();
  712. if (value == '') {
  713. return true;
  714. }
  715. // Credit to https://gist.github.com/dperini/729294
  716. //
  717. // Regular Expression for URL validation
  718. //
  719. // Author: Diego Perini
  720. // Updated: 2010/12/05
  721. //
  722. // the regular expression composed & commented
  723. // could be easily tweaked for RFC compliance,
  724. // it was expressly modified to fit & satisfy
  725. // these test for an URL shortener:
  726. //
  727. // http://mathiasbynens.be/demo/url-regex
  728. //
  729. // Notes on possible differences from a standard/generic validation:
  730. //
  731. // - utf-8 char class take in consideration the full Unicode range
  732. // - TLDs have been made mandatory so single names like "localhost" fails
  733. // - protocols have been restricted to ftp, http and https only as requested
  734. //
  735. // Changes:
  736. //
  737. // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
  738. // first and last IP address of each class is considered invalid
  739. // (since they are broadcast/network addresses)
  740. //
  741. // - Added exclusion of private, reserved and/or local networks ranges
  742. //
  743. // Compressed one-line versions:
  744. //
  745. // Javascript version
  746. //
  747. // /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i
  748. //
  749. // PHP version
  750. //
  751. // _^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS
  752. var urlExp = new RegExp(
  753. "^" +
  754. // protocol identifier
  755. "(?:(?:https?|ftp)://)" +
  756. // user:pass authentication
  757. "(?:\\S+(?::\\S*)?@)?" +
  758. "(?:" +
  759. // IP address exclusion
  760. // private & local networks
  761. "(?!10(?:\\.\\d{1,3}){3})" +
  762. "(?!127(?:\\.\\d{1,3}){3})" +
  763. "(?!169\\.254(?:\\.\\d{1,3}){2})" +
  764. "(?!192\\.168(?:\\.\\d{1,3}){2})" +
  765. "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
  766. // IP address dotted notation octets
  767. // excludes loopback network 0.0.0.0
  768. // excludes reserved space >= 224.0.0.0
  769. // excludes network & broacast addresses
  770. // (first & last IP address of each class)
  771. "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  772. "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  773. "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  774. "|" +
  775. // host name
  776. "(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)" +
  777. // domain name
  778. "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*" +
  779. // TLD identifier
  780. "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
  781. ")" +
  782. // port number
  783. "(?::\\d{2,5})?" +
  784. // resource path
  785. "(?:/[^\\s]*)?" +
  786. "$", "i"
  787. );
  788. return urlExp.test(value);
  789. }
  790. };
  791. }(window.jQuery));
  792. ;(function($) {
  793. $.fn.bootstrapValidator.validators.zipCode = {
  794. /**
  795. * Return true if and only if the input value is a valid country zip code
  796. *
  797. * @param {BootstrapValidator} validator The validator plugin instance
  798. * @param {jQuery} $field Field element
  799. * @param {Object} options Consist of key:
  800. * - country: The ISO 3166 country code
  801. *
  802. * Currently it supports the following countries:
  803. * - US (United State)
  804. * - DK (Denmark)
  805. * - SE (Sweden)
  806. *
  807. * @returns {Boolean}
  808. */
  809. validate: function(validateInstance, $field, options) {
  810. var value = $field.val();
  811. if (value == '' || !options.country) {
  812. return true;
  813. }
  814. switch (options.country.toUpperCase()) {
  815. case 'DK':
  816. return /^(DK(-|\s)?)?\d{4}$/i.test(value);
  817. case 'SE':
  818. return /^(S-)?\d{3}\s?\d{2}$/i.test(value);
  819. case 'US':
  820. default:
  821. return /^\d{5}([\-]\d{4})?$/.test(value);
  822. }
  823. }
  824. };
  825. }(window.jQuery));