bootstrap-show-password.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * @author zhixin wen <wenzhixin2010@gmail.com>
  3. * https://github.com/wenzhixin/bootstrap-show-password
  4. * version: 1.1.2
  5. *//* DaTouWang URL: www.datouwang.com */
  6. !function ($) {
  7. 'use strict';
  8. // TOOLS DEFINITION
  9. // ======================
  10. // it only does '%s', and return '' when arguments are undefined
  11. var sprintf = function(str) {
  12. var args = arguments,
  13. flag = true,
  14. i = 1;
  15. str = str.replace(/%s/g, function () {
  16. var arg = args[i++];
  17. if (typeof arg === 'undefined') {
  18. flag = false;
  19. return '';
  20. }
  21. return arg;
  22. });
  23. if (flag) {
  24. return str;
  25. }
  26. return '';
  27. };
  28. // PASSWORD CLASS DEFINITION
  29. // ======================
  30. var Password = function(element, options) {
  31. this.options = options;
  32. this.$element = $(element);
  33. this.isShown = false;
  34. this.init();
  35. };
  36. Password.DEFAULTS = {
  37. placement: 'after', // 'before' or 'after'
  38. white: false, // v2
  39. message: 'Click here to show/hide password',
  40. eyeClass: 'iconfont xian-mi',
  41. eyeOpenClass: 'icon-icon-test',
  42. eyeCloseClass: 'icon-close-eye',
  43. eyeClassPositionInside: false
  44. };
  45. Password.prototype.init = function() {
  46. var placementFuc,
  47. inputClass; // v2 class
  48. if (this.options.placement === 'before') {
  49. placementFuc = 'insertBefore';
  50. inputClass = 'input-prepend';
  51. } else {
  52. this.options.placement = 'after'; // default to after
  53. placementFuc = 'insertAfter';
  54. inputClass = 'input-append';
  55. }
  56. // Create the text, icon and assign
  57. this.$element.wrap(sprintf('<div class="%s input-group" />', inputClass));
  58. this.$text = $('<input type="text" />')
  59. [placementFuc](this.$element)
  60. .attr('class', this.$element.attr('class'))
  61. .attr('style', this.$element.attr('style'))
  62. .attr('placeholder', this.$element.attr('placeholder'))
  63. .css('display', this.$element.css('display'))
  64. .val(this.$element.val()).hide();
  65. // Copy readonly attribute if it's set
  66. if (this.$element.prop('readonly'))
  67. this.$text.prop('readonly', true);
  68. this.$icon = $([
  69. '<span tabindex="100" title="' + this.options.message + '" class="add-on input-group-addon">',
  70. '<i class="icon-icon-test' + (this.options.white ? 'iconfont' : '') +
  71. ' ' + this.options.eyeClass + ' ' + (this.options.eyeClassPositionInside ? '' : this.options.eyeOpenClass) + '">' +
  72. (this.options.eyeClassPositionInside ? this.options.eyeOpenClass : '') + '</i>',
  73. '</span>'
  74. ].join(''))[placementFuc](this.$text).css('cursor', 'pointer');
  75. // events
  76. this.$text.off('keyup').on('keyup', $.proxy(function() {
  77. if (!this.isShown) return;
  78. this.$element.val(this.$text.val()).trigger('change');
  79. }, this));
  80. this.$icon.off('click').on('click', $.proxy(function() {
  81. this.$text.val(this.$element.val()).trigger('change');
  82. this.toggle();
  83. }, this));
  84. };
  85. Password.prototype.toggle = function(_relatedTarget) {
  86. this[!this.isShown ? 'show' : 'hide'](_relatedTarget);
  87. };
  88. Password.prototype.show = function(_relatedTarget) {
  89. var e = $.Event('show.bs.password', {relatedTarget: _relatedTarget});
  90. this.$element.trigger(e);
  91. this.isShown = true;
  92. this.$element.hide();
  93. this.$text.show();
  94. if (this.options.eyeClassPositionInside) {
  95. this.$icon.find('i')
  96. .removeClass('icon-icon-test')
  97. .addClass('icon-close-eye')
  98. .html(this.options.eyeCloseClass);
  99. } else {
  100. this.$icon.find('i')
  101. .removeClass('icon-icon-test ' + this.options.eyeOpenClass)
  102. .addClass('icon-close-eye ' + this.options.eyeCloseClass);
  103. }
  104. // v3 input-group
  105. this.$text[this.options.placement](this.$element);
  106. };
  107. Password.prototype.hide = function(_relatedTarget) {
  108. var e = $.Event('hide.bs.password', {relatedTarget: _relatedTarget});
  109. this.$element.trigger(e);
  110. this.isShown = false;
  111. this.$element.show();
  112. this.$text.hide();
  113. if (this.options.eyeClassPositionInside) {
  114. this.$icon.find('i')
  115. .removeClass('icon-close-eye')
  116. .addClass('icon-icon-test')
  117. .html(this.options.eyeOpenClass);
  118. } else {
  119. this.$icon.find('i')
  120. .removeClass('icon-close-eye ' + this.options.eyeCloseClass)
  121. .addClass('icon-icon-test ' + this.options.eyeOpenClass);
  122. }
  123. // v3 input-group
  124. this.$element[this.options.placement](this.$text);
  125. };
  126. Password.prototype.val = function (value) {
  127. if (typeof value === 'undefined') {
  128. return this.$element.val();
  129. } else {
  130. this.$element.val(value).trigger('change');
  131. this.$text.val(value);
  132. }
  133. };
  134. Password.prototype.focus = function () {
  135. this.$element.focus();
  136. };
  137. // PASSWORD PLUGIN DEFINITION
  138. // =======================
  139. var old = $.fn.password;
  140. $.fn.password = function() {
  141. var option = arguments[0],
  142. args = arguments,
  143. value,
  144. allowedMethods = [
  145. 'show', 'hide', 'toggle', 'val', 'focus'
  146. ]; // public function
  147. this.each(function() {
  148. var $this = $(this),
  149. data = $this.data('bs.password'),
  150. options = $.extend({}, Password.DEFAULTS, $this.data(), typeof option === 'object' && option);
  151. if (typeof option === 'string') {
  152. if ($.inArray(option, allowedMethods) < 0) {
  153. throw "Unknown method: " + option;
  154. }
  155. value = data[option](args[1]);
  156. } else {
  157. if (!data) {
  158. data = new Password($this, options);
  159. $this.data('bs.password', data);
  160. } else {
  161. data.init(options);
  162. }
  163. }
  164. });
  165. return value ? value : this;
  166. };
  167. $.fn.password.Constructor = Password;
  168. // PASSWORD NO CONFLICT
  169. // =================
  170. $.fn.password.noConflict = function() {
  171. $.fn.password = old;
  172. return this;
  173. };
  174. $(function () {
  175. $('[data-toggle="password"]').password();
  176. });
  177. }(window.jQuery);