bootstrap.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /**
  2. * FormValidation (http://formvalidation.io)
  3. * The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
  4. *
  5. * @author https://twitter.com/formvalidation
  6. * @copyright (c) 2013 - 2016 Nguyen Huu Phuoc
  7. * @license http://formvalidation.io/license/
  8. */
  9. /**
  10. * This class supports validating Bootstrap form (http://getbootstrap.com/)
  11. */
  12. (function($) {
  13. FormValidation.Framework.Bootstrap = function(element, options, namespace) {
  14. options = $.extend(true, {
  15. button: {
  16. selector: '[type="submit"]:not([formnovalidate])',
  17. // The class of disabled button
  18. // http://getbootstrap.com/css/#buttons-disabled
  19. disabled: 'disabled'
  20. },
  21. err: {
  22. // http://getbootstrap.com/css/#forms-help-text
  23. clazz: 'help-block',
  24. parent: '^(.*)col-(xs|sm|md|lg)-(offset-){0,1}[0-9]+(.*)$'
  25. },
  26. // This feature requires Bootstrap v3.1.0 or later (http://getbootstrap.com/css/#forms-control-validation).
  27. // Since Bootstrap doesn't provide any methods to know its version, this option cannot be on/off automatically.
  28. // In other word, to use this feature you have to upgrade your Bootstrap to v3.1.0 or later.
  29. //
  30. // Examples:
  31. // - Use Glyphicons icons:
  32. // icon: {
  33. // valid: 'glyphicon glyphicon-ok',
  34. // invalid: 'glyphicon glyphicon-remove',
  35. // validating: 'glyphicon glyphicon-refresh',
  36. // feedback: 'form-control-feedback'
  37. // }
  38. // - Use FontAwesome icons:
  39. // icon: {
  40. // valid: 'fa fa-check',
  41. // invalid: 'fa fa-times',
  42. // validating: 'fa fa-refresh',
  43. // feedback: 'form-control-feedback'
  44. // }
  45. icon: {
  46. valid: null,
  47. invalid: null,
  48. validating: null,
  49. feedback: 'form-control-feedback'
  50. },
  51. row: {
  52. // By default, each field is placed inside the <div class="form-group"></div>
  53. // http://getbootstrap.com/css/#forms
  54. selector: '.form-group',
  55. valid: 'has-success',
  56. invalid: 'has-error',
  57. feedback: 'has-feedback'
  58. }
  59. }, options);
  60. FormValidation.Base.apply(this, [element, options, namespace]);
  61. };
  62. FormValidation.Framework.Bootstrap.prototype = $.extend({}, FormValidation.Base.prototype, {
  63. /**
  64. * Specific framework might need to adjust the icon position
  65. *
  66. * @param {jQuery} $field The field element
  67. * @param {jQuery} $icon The icon element
  68. */
  69. _fixIcon: function($field, $icon) {
  70. var ns = this._namespace,
  71. type = $field.attr('type'),
  72. field = $field.attr('data-' + ns + '-field'),
  73. row = this.options.fields[field].row || this.options.row.selector,
  74. $parent = $field.closest(row);
  75. // Place it after the container of checkbox/radio
  76. // so when clicking the icon, it doesn't effect to the checkbox/radio element
  77. if ('checkbox' === type || 'radio' === type) {
  78. var $fieldParent = $field.parent();
  79. if ($fieldParent.hasClass(type)) {
  80. $icon.insertAfter($fieldParent);
  81. } else if ($fieldParent.parent().hasClass(type)) {
  82. $icon.insertAfter($fieldParent.parent());
  83. }
  84. }
  85. // Fix feedback icons in input-group
  86. if ($parent.find('.input-group').length !== 0) {
  87. $icon.addClass('fv-bootstrap-icon-input-group')
  88. .insertAfter($parent.find('.input-group').eq(0));
  89. }
  90. },
  91. /**
  92. * Create a tooltip or popover
  93. * It will be shown when focusing on the field
  94. *
  95. * @param {jQuery} $field The field element
  96. * @param {String} message The message
  97. * @param {String} type Can be 'tooltip' or 'popover'
  98. */
  99. _createTooltip: function($field, message, type) {
  100. var ns = this._namespace,
  101. $icon = $field.data(ns + '.icon');
  102. if ($icon) {
  103. switch (type) {
  104. case 'popover':
  105. $icon
  106. .css({
  107. 'cursor': 'pointer',
  108. 'pointer-events': 'auto'
  109. })
  110. .popover('destroy')
  111. .popover({
  112. container: 'body',
  113. content: message,
  114. html: true,
  115. placement: 'auto top',
  116. trigger: 'hover click'
  117. });
  118. break;
  119. case 'tooltip':
  120. /* falls through */
  121. default:
  122. $icon
  123. .css({
  124. 'cursor': 'pointer',
  125. 'pointer-events': 'auto'
  126. })
  127. .tooltip('destroy')
  128. .tooltip({
  129. container: 'body',
  130. html: true,
  131. placement: 'auto top',
  132. title: message
  133. });
  134. break;
  135. }
  136. }
  137. },
  138. /**
  139. * Destroy the tooltip or popover
  140. *
  141. * @param {jQuery} $field The field element
  142. * @param {String} type Can be 'tooltip' or 'popover'
  143. */
  144. _destroyTooltip: function($field, type) {
  145. var ns = this._namespace,
  146. $icon = $field.data(ns + '.icon');
  147. if ($icon) {
  148. switch (type) {
  149. case 'popover':
  150. $icon
  151. .css({
  152. 'cursor': '',
  153. 'pointer-events': 'none'
  154. })
  155. .popover('destroy');
  156. break;
  157. case 'tooltip':
  158. /* falls through */
  159. default:
  160. $icon
  161. .css({
  162. 'cursor': '',
  163. 'pointer-events': 'none'
  164. })
  165. .tooltip('destroy');
  166. break;
  167. }
  168. }
  169. },
  170. /**
  171. * Hide a tooltip or popover
  172. *
  173. * @param {jQuery} $field The field element
  174. * @param {String} type Can be 'tooltip' or 'popover'
  175. */
  176. _hideTooltip: function($field, type) {
  177. var ns = this._namespace,
  178. $icon = $field.data(ns + '.icon');
  179. if ($icon) {
  180. switch (type) {
  181. case 'popover':
  182. $icon.popover('hide');
  183. break;
  184. case 'tooltip':
  185. /* falls through */
  186. default:
  187. $icon.tooltip('hide');
  188. break;
  189. }
  190. }
  191. },
  192. /**
  193. * Show a tooltip or popover
  194. *
  195. * @param {jQuery} $field The field element
  196. * @param {String} type Can be 'tooltip' or 'popover'
  197. */
  198. _showTooltip: function($field, type) {
  199. var ns = this._namespace,
  200. $icon = $field.data(ns + '.icon');
  201. if ($icon) {
  202. switch (type) {
  203. case 'popover':
  204. $icon.popover('show');
  205. break;
  206. case 'tooltip':
  207. /* falls through */
  208. default:
  209. $icon.tooltip('show');
  210. break;
  211. }
  212. }
  213. }
  214. });
  215. /**
  216. * Plugin definition
  217. * Support backward
  218. * @deprecated It will be removed soon. Instead of using $(form).bootstrapValidator(), use
  219. * $(form).formValidation({
  220. * framework: 'bootstrap' // It's equivalent to use data-fv-framework="bootstrap" for <form>
  221. * });
  222. */
  223. $.fn.bootstrapValidator = function(option) {
  224. var params = arguments;
  225. return this.each(function() {
  226. var $this = $(this),
  227. data = $this.data('formValidation') || $this.data('bootstrapValidator'),
  228. options = 'object' === typeof option && option;
  229. if (!data) {
  230. data = new FormValidation.Framework.Bootstrap(this, $.extend({}, {
  231. events: {
  232. // Support backward
  233. formInit: 'init.form.bv',
  234. formPreValidate: 'prevalidate.form.bv',
  235. formError: 'error.form.bv',
  236. formSuccess: 'success.form.bv',
  237. fieldAdded: 'added.field.bv',
  238. fieldRemoved: 'removed.field.bv',
  239. fieldInit: 'init.field.bv',
  240. fieldError: 'error.field.bv',
  241. fieldSuccess: 'success.field.bv',
  242. fieldStatus: 'status.field.bv',
  243. localeChanged: 'changed.locale.bv',
  244. validatorError: 'error.validator.bv',
  245. validatorSuccess: 'success.validator.bv'
  246. }
  247. }, options), 'bv');
  248. $this.addClass('fv-form-bootstrap')
  249. .data('formValidation', data)
  250. .data('bootstrapValidator', data);
  251. }
  252. // Allow to call plugin method
  253. if ('string' === typeof option) {
  254. data[option].apply(data, Array.prototype.slice.call(params, 1));
  255. }
  256. });
  257. };
  258. $.fn.bootstrapValidator.Constructor = FormValidation.Framework.Bootstrap;
  259. }(jQuery));