user.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. (function ($, Drupal) {
  2. Drupal.BootstrapPassword = function (element) {
  3. var self = this;
  4. var $element = $(element);
  5. this.settings = Drupal.settings.password;
  6. this.$wrapper = $element.parent().parent();
  7. this.$row = $('<div class="row">').prependTo(this.$wrapper);
  8. // The password object.
  9. this.password = {
  10. $input: $element,
  11. $label: $element.parent().find('label'),
  12. $wrapper: $element.parent().addClass('col-sm-6 col-md-4 has-feedback').appendTo(self.$row)
  13. };
  14. this.password.$icon = $('<span class="glyphicon form-control-feedback"></span>').appendTo(this.password.$wrapper);
  15. // Strength meter.
  16. this.strength = {
  17. $label: $('<div class="label" aria-live="assertive"></div>').appendTo(this.password.$label),
  18. $progress: $('<div class="progress"><div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div>').appendTo(this.password.$wrapper)
  19. };
  20. this.strength.$bar = this.strength.$progress.find('.progress-bar');
  21. // The confirmation object.
  22. this.confirm = {
  23. $input: this.$wrapper.find('input.password-confirm')
  24. };
  25. this.confirm.$wrapper = this.confirm.$input.parent().addClass('col-sm-6 col-md-4 has-feedback').appendTo(self.$row);
  26. this.confirm.$icon = $('<span class="glyphicon form-control-feedback"></span>').appendTo(this.confirm.$wrapper);
  27. // Bind events.
  28. this.password.$input.on('keyup focus blur', function () {
  29. self.validateStrength();
  30. });
  31. this.confirm.$input.on('keyup blur', function () {
  32. self.validateMatch();
  33. });
  34. // Add password help at the of row.
  35. this.$helpBlock = $('<div class="help-block password-help"></div>').appendTo(this.$row);
  36. return this;
  37. };
  38. /**
  39. * Helper method to switch classes on elements based on status.
  40. *
  41. * @param {jQuery} $element
  42. * The jQuery element to modify.
  43. * @param {string} type
  44. * The name of the class to switch to. Can be one of: "danger", "info",
  45. * "success" or "warning".
  46. * @param {string} prefix
  47. * The prefix to use. Typically this would be something like "label" or
  48. * "progress-bar".
  49. */
  50. Drupal.BootstrapPassword.prototype.switchClass = function ($element, type, prefix) {
  51. prefix = prefix + '-' || '';
  52. var types = prefix === 'has-' ? ['error', 'warning', 'success'] : ['danger', 'info', 'success', 'warning'];
  53. if (type) {
  54. type = types.splice($.inArray(type, types), 1).shift();
  55. $element.addClass(prefix + type);
  56. }
  57. $element.removeClass(prefix + types.join(' ' + prefix));
  58. };
  59. /**
  60. * Validates the strength of a password.
  61. */
  62. Drupal.BootstrapPassword.prototype.validateStrength = function () {
  63. var result = Drupal.evaluatePasswordStrength(this.password.$input.val(), Drupal.settings.password);
  64. // Ensure visibility.
  65. this.$helpBlock.show();
  66. this.strength.$label.show();
  67. this.strength.$bar.show();
  68. // Update the suggestions for how to improve the password.
  69. this.$helpBlock.html(result.message);
  70. // Only show the description box if there is a weakness in the password.
  71. this.$helpBlock[result.strength === 100 ? 'hide' : 'show']();
  72. // Update the strength indication text.
  73. this.strength.$label.html(result.indicatorText);
  74. // Adjust the length of the strength indicator.
  75. this.strength.$bar.attr('aria-valuenow', result.strength);
  76. this.strength.$bar.css('width', result.strength + '%');
  77. // Change the classes (color) of the strength meter based on result level.
  78. switch (result.indicatorText) {
  79. case this.settings.weak:
  80. this.switchClass(this.password.$wrapper, 'error', 'has');
  81. this.switchClass(this.strength.$label, 'danger', 'label');
  82. this.switchClass(this.strength.$bar, 'danger', 'progress-bar');
  83. this.password.$icon.addClass('glyphicon-remove').removeClass('glyphicon-warning-sign glyphicon-ok');
  84. break;
  85. case this.settings.fair:
  86. case this.settings.good:
  87. this.switchClass(this.password.$wrapper, 'warning', 'has');
  88. this.switchClass(this.strength.$label, 'warning', 'label');
  89. this.switchClass(this.strength.$bar, 'warning', 'progress-bar');
  90. this.password.$icon.addClass('glyphicon-warning-sign').removeClass('glyphicon-remove glyphicon-ok');
  91. break;
  92. case this.settings.strong:
  93. this.switchClass(this.password.$wrapper, 'success', 'has');
  94. this.switchClass(this.strength.$label, 'success', 'label');
  95. this.switchClass(this.strength.$bar, 'success', 'progress-bar');
  96. this.password.$icon.addClass('glyphicon-ok').removeClass('glyphicon-warning-sign glyphicon-remove');
  97. break;
  98. }
  99. this.validateMatch();
  100. };
  101. /**
  102. * Validates both original and confirmation passwords to ensure they match.
  103. */
  104. Drupal.BootstrapPassword.prototype.validateMatch = function () {
  105. var password = this.password.$input.val();
  106. // Passwords match.
  107. if (password && password === this.confirm.$input.val()) {
  108. this.switchClass(this.password.$wrapper, 'success', 'has');
  109. this.switchClass(this.confirm.$wrapper, 'success', 'has');
  110. this.$helpBlock.hide();
  111. this.strength.$label.hide();
  112. this.strength.$bar.hide();
  113. this.password.$icon.addClass('glyphicon-ok').removeClass('glyphicon-warning-sign glyphicon-remove');
  114. this.confirm.$icon.addClass('glyphicon-ok').removeClass('glyphicon-remove');
  115. }
  116. // Passwords do not match.
  117. else if (password) {
  118. this.switchClass(this.confirm.$wrapper, 'error', 'has');
  119. this.confirm.$icon.addClass('glyphicon-remove').removeClass('glyphicon-ok');
  120. }
  121. // No password.
  122. else {
  123. this.confirm.$icon.removeClass('glyphicon-ok glyphicon-remove');
  124. this.confirm.$input.val('');
  125. this.switchClass(this.confirm.$wrapper, '', 'has');
  126. }
  127. };
  128. /**
  129. * Overrides core JS for password strength and confirmation.
  130. *
  131. * Attach handlers to evaluate the strength of any password fields and to check
  132. * that its confirmation is correct.
  133. */
  134. Drupal.behaviors.password = {
  135. attach: function (context) {
  136. $('input.password-field', context).once('password', function () {
  137. new Drupal.BootstrapPassword(this);
  138. });
  139. }
  140. };
  141. })(jQuery, window.Drupal);