bootstrapValidator.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  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 this;
  200. }
  201. for (var field in this.options.fields) {
  202. this.validateField(field);
  203. }
  204. this._submit();
  205. return this;
  206. },
  207. /**
  208. * Validate given field
  209. *
  210. * @param {String} field The field name
  211. */
  212. validateField: function(field) {
  213. var that = this,
  214. fields = this.$form.find('[name="' + field + '"]'),
  215. $field = $(fields[0]),
  216. validators = this.options.fields[field].validators,
  217. validatorName,
  218. validateResult;
  219. for (validatorName in validators) {
  220. if (this._dfds[field][validatorName]) {
  221. this._dfds[field][validatorName].reject();
  222. }
  223. validateResult = $.fn.bootstrapValidator.validators[validatorName].validate(this, $field, validators[validatorName]);
  224. if ('object' == typeof validateResult) {
  225. this._dfds[field][validatorName] = validateResult;
  226. validateResult.done(function(isValid, v) {
  227. // v is validator name
  228. delete that._dfds[field][v];
  229. /*
  230. if (isValid) {
  231. that._submit();
  232. }*/
  233. });
  234. }
  235. $.when(validateResult).then(function(isValid) {
  236. that._results[field][validatorName] = isValid;
  237. if (isValid) {
  238. that.removeError($field, validatorName);
  239. } else {
  240. that.showError($field, validatorName);
  241. }
  242. });
  243. }
  244. },
  245. /**
  246. * Check the form validity
  247. *
  248. * @returns {Boolean}
  249. */
  250. isValid: function() {
  251. var field, validatorName;
  252. for (field in this._results) {
  253. for (validatorName in this._results[field]) {
  254. if (!this._results[field][validatorName]) {
  255. this._firstInvalidField = field;
  256. return false;
  257. }
  258. }
  259. }
  260. return true;
  261. },
  262. /**
  263. * Show field error
  264. *
  265. * @param {jQuery} $field The field element
  266. * @param {String} validatorName
  267. */
  268. showError: function($field, validatorName) {
  269. var field = $field.attr('name'),
  270. validator = this.options.fields[field].validators[validatorName],
  271. message = validator.message || this.options.message;
  272. // Add has-error class to parent element
  273. $field
  274. .parents('.form-group')
  275. .removeClass('has-success')
  276. .addClass('has-error')
  277. .find('.help-block[data-bs-validator="' + validatorName + '"]')
  278. .html(message)
  279. .show();
  280. },
  281. /**
  282. * Remove error from given field
  283. *
  284. * @param {jQuery} $field The field element
  285. */
  286. removeError: function($field, validatorName) {
  287. $field
  288. .parents('.form-group')
  289. .removeClass('has-error')
  290. .addClass('has-success')
  291. .find('.help-block[data-bs-validator="' + validatorName + '"]')
  292. .hide();
  293. }
  294. };
  295. // Plugin definition
  296. $.fn.bootstrapValidator = function(options) {
  297. return this.each(function() {
  298. var $this = $(this), data = $this.data('bootstrapValidator');
  299. if (!data) {
  300. $this.data('bootstrapValidator', (data = new BootstrapValidator(this, options)));
  301. }
  302. if ('string' == typeof options) {
  303. data[options]();
  304. }
  305. });
  306. };
  307. // Available validators
  308. $.fn.bootstrapValidator.validators = {};
  309. $.fn.bootstrapValidator.Constructor = BootstrapValidator;
  310. }(window.jQuery));
  311. ;(function($) {
  312. $.fn.bootstrapValidator.validators.between = {
  313. /**
  314. * Return true if the input value is between (strictly or not) two given numbers
  315. *
  316. * @param {BootstrapValidator} validator The validator plugin instance
  317. * @param {jQuery} $field Field element
  318. * @param {Object} options Can consist of the following keys:
  319. * - min
  320. * - max
  321. * - inclusive [optional]: Can be true or false. Default is true
  322. * - message: The invalid message
  323. * @returns {Boolean}
  324. */
  325. validate: function(validator, $field, options) {
  326. var value = $field.val();
  327. if (value == '') {
  328. return true;
  329. }
  330. value = parseFloat(value);
  331. return (options.inclusive === true)
  332. ? (value > options.min && value < options.max)
  333. : (value >= options.min && value <= options.max);
  334. }
  335. };
  336. }(window.jQuery));
  337. ;(function($) {
  338. $.fn.bootstrapValidator.validators.callback = {
  339. /**
  340. * Return result from the callback method
  341. *
  342. * @param {BootstrapValidator} validator The validator plugin instance
  343. * @param {jQuery} $field Field element
  344. * @param {Object} options Can consist of the following keys:
  345. * - callback: The callback method that passes 2 parameters:
  346. * callback: function(fieldValue, validator) {
  347. * // fieldValue is the value of field
  348. * // validator is instance of BootstrapValidator
  349. * }
  350. * - message: The invalid message
  351. * @returns {Boolean|Deferred}
  352. */
  353. validate: function(validator, $field, options) {
  354. var value = $field.val();
  355. if (options.callback && 'function' == typeof options.callback) {
  356. var dfd = new $.Deferred();
  357. dfd.resolve(options.callback.call(this, value, validator), 'callback');
  358. return dfd;
  359. }
  360. return true;
  361. }
  362. };
  363. }(window.jQuery));
  364. ;(function($) {
  365. $.fn.bootstrapValidator.validators.choice = {
  366. /**
  367. * Check if the number of checked boxes are less or more than a given number
  368. *
  369. * @param {BootstrapValidator} validator The validator plugin instance
  370. * @param {jQuery} $field Field element
  371. * @param {Object} options Consists of following keys:
  372. * - min
  373. * - max
  374. * At least one of two keys is required
  375. * @returns {Boolean}
  376. */
  377. validate: function(validator, $field, options) {
  378. var numChoices = validator
  379. .getFieldElements($field.attr('name'))
  380. .filter(':checked')
  381. .length;
  382. if ((options.min && numChoices < options.min) || (options.max && numChoices > options.max)) {
  383. return false;
  384. }
  385. return true;
  386. }
  387. };
  388. }(window.jQuery));
  389. ;(function($) {
  390. $.fn.bootstrapValidator.validators.creditCard = {
  391. /**
  392. * Return true if the input value is valid credit card number
  393. * Based on https://gist.github.com/DiegoSalazar/4075533
  394. *
  395. * @param {BootstrapValidator} validator The validator plugin instance
  396. * @param {jQuery} $field Field element
  397. * @param {Object} options Can consist of the following key:
  398. * - message: The invalid message
  399. * @returns {Boolean}
  400. */
  401. validate: function(validator, $field, options) {
  402. var value = $field.val();
  403. if (value == '') {
  404. return true;
  405. }
  406. // Accept only digits, dashes or spaces
  407. if (/[^0-9-\s]+/.test(value)) {
  408. return false;
  409. }
  410. // The Luhn Algorithm
  411. // http://en.wikipedia.org/wiki/Luhn
  412. value = value.replace(/\D/g, '');
  413. var check = 0, digit = 0, even = false, length = value.length;
  414. for (var n = length - 1; n >= 0; n--) {
  415. digit = parseInt(value.charAt(n), 10);
  416. if (even) {
  417. if ((digit *= 2) > 9) {
  418. digit -= 9;
  419. }
  420. }
  421. check += digit;
  422. even = !even;
  423. }
  424. return (check % 10) == 0;
  425. }
  426. };
  427. }(window.jQuery));
  428. ;(function($) {
  429. $.fn.bootstrapValidator.validators.different = {
  430. /**
  431. * Return true if the input value is different with given field's value
  432. *
  433. * @param {BootstrapValidator} validator The validator plugin instance
  434. * @param {jQuery} $field Field element
  435. * @param {Object} options Consists of the following key:
  436. * - field: The name of field that will be used to compare with current one
  437. * @returns {Boolean}
  438. */
  439. validate: function(validator, $field, options) {
  440. var value = $field.val();
  441. if (value == '') {
  442. return true;
  443. }
  444. var compareWith = validator.getFieldElements(options.field);
  445. if (compareWith == null) {
  446. return true;
  447. }
  448. if (value != compareWith.val()) {
  449. validator.removeError(compareWith, 'different');
  450. return true;
  451. } else {
  452. return false;
  453. }
  454. }
  455. };
  456. }(window.jQuery));
  457. ;(function($) {
  458. $.fn.bootstrapValidator.validators.digits = {
  459. /**
  460. * Return true if the input value contains digits only
  461. *
  462. * @param {BootstrapValidator} validator Validate plugin instance
  463. * @param {jQuery} $field Field element
  464. * @param {Object} options
  465. * @returns {Boolean}
  466. */
  467. validate: function(validator, $field, options) {
  468. var value = $field.val();
  469. if (value == '') {
  470. return true;
  471. }
  472. return /^\d+$/.test(value);
  473. }
  474. }
  475. }(window.jQuery));
  476. ;(function($) {
  477. $.fn.bootstrapValidator.validators.emailAddress = {
  478. /**
  479. * Return true if and only if the input value is a valid email address
  480. *
  481. * @param {BootstrapValidator} validator Validate plugin instance
  482. * @param {jQuery} $field Field element
  483. * @param {Object} options
  484. * @returns {Boolean}
  485. */
  486. validate: function(validator, $field, options) {
  487. var value = $field.val();
  488. if (value == '') {
  489. return true;
  490. }
  491. // Email address regular expression
  492. // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
  493. 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,}))$/;
  494. return emailRegExp.test(value);
  495. }
  496. }
  497. }(window.jQuery));
  498. ;(function($) {
  499. $.fn.bootstrapValidator.validators.greaterThan = {
  500. /**
  501. * Return true if the input value is greater than or equals to given number
  502. *
  503. * @param {BootstrapValidator} validator Validate plugin instance
  504. * @param {jQuery} $field Field element
  505. * @param {Object} options Can consist of the following keys:
  506. * - value: The number used to compare to
  507. * - inclusive [optional]: Can be true or false. Default is true
  508. * - message: The invalid message
  509. * @returns {Boolean}
  510. */
  511. validate: function(validator, $field, options) {
  512. var value = $field.val();
  513. if (value == '') {
  514. return true;
  515. }
  516. value = parseFloat(value);
  517. return (options.inclusive === true) ? (value > options.value) : (value >= options.value);
  518. }
  519. }
  520. }(window.jQuery));
  521. ;(function($) {
  522. $.fn.bootstrapValidator.validators.hexColor = {
  523. /**
  524. * Return true if the input value is a valid hex color
  525. *
  526. * @param {BootstrapValidator} validator The validator plugin instance
  527. * @param {jQuery} $field Field element
  528. * @param {Object} options Can consist of the following keys:
  529. * - message: The invalid message
  530. * @returns {Boolean}
  531. */
  532. validate: function(validator, $field, options) {
  533. var value = $field.val();
  534. if (value == '') {
  535. return true;
  536. }
  537. return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(value);
  538. }
  539. };
  540. }(window.jQuery));
  541. ;(function($) {
  542. $.fn.bootstrapValidator.validators.identical = {
  543. /**
  544. * Check if input value equals to value of particular one
  545. *
  546. * @param {BootstrapValidator} validator The validator plugin instance
  547. * @param {jQuery} $field Field element
  548. * @param {Object} options Consists of the following key:
  549. * - field: The name of field that will be used to compare with current one
  550. * @returns {Boolean}
  551. */
  552. validate: function(validator, $field, options) {
  553. var value = $field.val();
  554. if (value == '') {
  555. return true;
  556. }
  557. var compareWith = validator.getFieldElements(options.field);
  558. if (compareWith == null) {
  559. return true;
  560. }
  561. if (value == compareWith.val()) {
  562. validator.removeError(compareWith, 'identical');
  563. return true;
  564. } else {
  565. return false;
  566. }
  567. }
  568. };
  569. }(window.jQuery));
  570. ;(function($) {
  571. $.fn.bootstrapValidator.validators.lessThan = {
  572. /**
  573. * Return true if the input value is less than or equal to given number
  574. *
  575. * @param {BootstrapValidator} validator The validator plugin instance
  576. * @param {jQuery} $field Field element
  577. * @param {Object} options Can consist of the following keys:
  578. * - value: The number used to compare to
  579. * - inclusive [optional]: Can be true or false. Default is true
  580. * - message: The invalid message
  581. * @returns {Boolean}
  582. */
  583. validate: function(validator, $field, options) {
  584. var value = $field.val();
  585. if (value == '') {
  586. return true;
  587. }
  588. value = parseFloat(value);
  589. return (options.inclusive === true) ? (value < options.value) : (value <= options.value);
  590. }
  591. };
  592. }(window.jQuery));
  593. ;(function($) {
  594. $.fn.bootstrapValidator.validators.notEmpty = {
  595. /**
  596. * Check if input value is empty or not
  597. *
  598. * @param {BootstrapValidator} validator The validator plugin instance
  599. * @param {jQuery} $field Field element
  600. * @param {Object} options
  601. * @returns {Boolean}
  602. */
  603. validate: function(validator, $field, options) {
  604. var type = $field.attr('type');
  605. if ('radio' == type || 'checkbox' == type) {
  606. return validator
  607. .getFieldElements($field.attr('name'))
  608. .filter(':checked')
  609. .length > 0;
  610. }
  611. return $.trim($field.val()) != '';
  612. }
  613. };
  614. }(window.jQuery));
  615. ;(function($) {
  616. $.fn.bootstrapValidator.validators.regexp = {
  617. /**
  618. * Check if the element value matches given regular expression
  619. *
  620. * @param {BootstrapValidator} validator The validator plugin instance
  621. * @param {jQuery} $field Field element
  622. * @param {Object} options Consists of the following key:
  623. * - regexp: The regular expression you need to check
  624. * @returns {Boolean}
  625. */
  626. validate: function(validator, $field, options) {
  627. var value = $field.val();
  628. if (value == '') {
  629. return true;
  630. }
  631. return options.regexp.test(value);
  632. }
  633. };
  634. }(window.jQuery));
  635. ;(function($) {
  636. $.fn.bootstrapValidator.validators.remote = {
  637. /**
  638. * Request a remote server to check the input value
  639. *
  640. * @param {BootstrapValidator} validator Plugin instance
  641. * @param {jQuery} $field Field element
  642. * @param {Object} options Can consist of the following keys:
  643. * - url
  644. * - data [optional]: By default, it will take the value
  645. * {
  646. * <fieldName>: <fieldValue>
  647. * }
  648. * - message: The invalid message
  649. * @returns {Boolean|Deferred}
  650. */
  651. validate: function(validator, $field, options) {
  652. var value = $field.val();
  653. if (value == '') {
  654. return true;
  655. }
  656. var name = $field.attr('name'), data = options.data;
  657. if (data == null) {
  658. data = {};
  659. }
  660. data[name] = value;
  661. var dfd = new $.Deferred();
  662. var xhr = $.ajax({
  663. type: 'POST',
  664. url: options.url,
  665. dataType: 'json',
  666. data: data
  667. });
  668. xhr.then(function(response) {
  669. dfd.resolve(response.valid === true || response.valid === 'true', 'remote');
  670. });
  671. dfd.fail(function() {
  672. xhr.abort();
  673. });
  674. return dfd;
  675. }
  676. };
  677. }(window.jQuery));
  678. ;(function($) {
  679. $.fn.bootstrapValidator.validators.stringLength = {
  680. /**
  681. * Check if the length of element value is less or more than given number
  682. *
  683. * @param {BootstrapValidator} validator The validator plugin instance
  684. * @param {jQuery} $field Field element
  685. * @param {Object} options Consists of following keys:
  686. * - min
  687. * - max
  688. * At least one of two keys is required
  689. * @returns {Boolean}
  690. */
  691. validate: function(validator, $field, options) {
  692. var value = $field.val();
  693. if (value == '') {
  694. return true;
  695. }
  696. var length = $.trim(value).length;
  697. if ((options.min && length < options.min) || (options.max && length > options.max)) {
  698. return false;
  699. }
  700. return true;
  701. }
  702. };
  703. }(window.jQuery));
  704. ;(function($) {
  705. $.fn.bootstrapValidator.validators.uri = {
  706. /**
  707. * Return true if the input value is a valid URL
  708. *
  709. * @param {BootstrapValidator} validator The validator plugin instance
  710. * @param {jQuery} $field Field element
  711. * @param {Object} options
  712. * @returns {Boolean}
  713. */
  714. validate: function(validator, $field, options) {
  715. var value = $field.val();
  716. if (value == '') {
  717. return true;
  718. }
  719. // Credit to https://gist.github.com/dperini/729294
  720. //
  721. // Regular Expression for URL validation
  722. //
  723. // Author: Diego Perini
  724. // Updated: 2010/12/05
  725. //
  726. // the regular expression composed & commented
  727. // could be easily tweaked for RFC compliance,
  728. // it was expressly modified to fit & satisfy
  729. // these test for an URL shortener:
  730. //
  731. // http://mathiasbynens.be/demo/url-regex
  732. //
  733. // Notes on possible differences from a standard/generic validation:
  734. //
  735. // - utf-8 char class take in consideration the full Unicode range
  736. // - TLDs have been made mandatory so single names like "localhost" fails
  737. // - protocols have been restricted to ftp, http and https only as requested
  738. //
  739. // Changes:
  740. //
  741. // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
  742. // first and last IP address of each class is considered invalid
  743. // (since they are broadcast/network addresses)
  744. //
  745. // - Added exclusion of private, reserved and/or local networks ranges
  746. //
  747. // Compressed one-line versions:
  748. //
  749. // Javascript 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\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
  752. //
  753. // PHP version
  754. //
  755. // _^(?:(?: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
  756. var urlExp = new RegExp(
  757. "^" +
  758. // protocol identifier
  759. "(?:(?:https?|ftp)://)" +
  760. // user:pass authentication
  761. "(?:\\S+(?::\\S*)?@)?" +
  762. "(?:" +
  763. // IP address exclusion
  764. // private & local networks
  765. "(?!10(?:\\.\\d{1,3}){3})" +
  766. "(?!127(?:\\.\\d{1,3}){3})" +
  767. "(?!169\\.254(?:\\.\\d{1,3}){2})" +
  768. "(?!192\\.168(?:\\.\\d{1,3}){2})" +
  769. "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
  770. // IP address dotted notation octets
  771. // excludes loopback network 0.0.0.0
  772. // excludes reserved space >= 224.0.0.0
  773. // excludes network & broacast addresses
  774. // (first & last IP address of each class)
  775. "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  776. "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  777. "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  778. "|" +
  779. // host name
  780. "(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)" +
  781. // domain name
  782. "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*" +
  783. // TLD identifier
  784. "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
  785. ")" +
  786. // port number
  787. "(?::\\d{2,5})?" +
  788. // resource path
  789. "(?:/[^\\s]*)?" +
  790. "$", "i"
  791. );
  792. return urlExp.test(value);
  793. }
  794. };
  795. }(window.jQuery));
  796. ;(function($) {
  797. $.fn.bootstrapValidator.validators.zipCode = {
  798. /**
  799. * Return true if and only if the input value is a valid country zip code
  800. *
  801. * @param {BootstrapValidator} validator The validator plugin instance
  802. * @param {jQuery} $field Field element
  803. * @param {Object} options Consist of key:
  804. * - country: The ISO 3166 country code
  805. *
  806. * Currently it supports the following countries:
  807. * - US (United State)
  808. * - DK (Denmark)
  809. * - SE (Sweden)
  810. *
  811. * @returns {Boolean}
  812. */
  813. validate: function(validateInstance, $field, options) {
  814. var value = $field.val();
  815. if (value == '' || !options.country) {
  816. return true;
  817. }
  818. switch (options.country.toUpperCase()) {
  819. case 'DK':
  820. return /^(DK(-|\s)?)?\d{4}$/i.test(value);
  821. case 'SE':
  822. return /^(S-)?\d{3}\s?\d{2}$/i.test(value);
  823. case 'US':
  824. default:
  825. return /^\d{5}([\-]\d{4})?$/.test(value);
  826. }
  827. }
  828. };
  829. }(window.jQuery));