dropdowns.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. define([
  6. 'jquery'
  7. ], function ($) {
  8. 'use strict';
  9. /**
  10. * @param {Object} options
  11. */
  12. $.fn.dropdown = function (options) {
  13. var defaults = {
  14. parent: null,
  15. autoclose: true,
  16. btnArrow: '.arrow',
  17. menu: '[data-target="dropdown"]',
  18. activeClass: 'active'
  19. },
  20. actionElem = $(this),
  21. self = this;
  22. options = $.extend(defaults, options);
  23. actionElem = $(this);
  24. self = this;
  25. /**
  26. * @param {HTMLElement} elem
  27. */
  28. this.openDropdown = function (elem) {
  29. elem
  30. .addClass(options.activeClass)
  31. .attr('aria-expanded', true)
  32. .parent()
  33. .addClass(options.activeClass);
  34. elem.parent()
  35. .find(options.menu)
  36. .attr('aria-hidden', false);
  37. $(options.btnArrow, elem).text('-');
  38. };
  39. /**
  40. * @param {HTMLElement} elem
  41. */
  42. this.closeDropdown = function (elem) {
  43. elem.removeClass(options.activeClass)
  44. .attr('aria-expanded', false)
  45. .parent()
  46. .removeClass(options.activeClass);
  47. elem.parent()
  48. .find(options.menu)
  49. .attr('aria-hidden', true);
  50. $(options.btnArrow, elem).text('+');
  51. };
  52. /**
  53. * Reset all dropdowns.
  54. *
  55. * @param {Object} param
  56. */
  57. this.reset = function (param) {
  58. var params = param || {},
  59. dropdowns = params.elems || actionElem;
  60. dropdowns.each(function (index, elem) {
  61. self.closeDropdown($(elem));
  62. });
  63. };
  64. /* document Event bindings */
  65. if (options.autoclose === true) {
  66. $(document).on('click.hideDropdown', this.reset);
  67. $(document).on('keyup.hideDropdown', function (e) {
  68. var ESC_CODE = '27';
  69. if (e.keyCode == ESC_CODE) { //eslint-disable-line eqeqeq
  70. self.reset();
  71. }
  72. });
  73. }
  74. if (options.events) {
  75. $.each(options.events, function (index, event) {
  76. $(document).on(event.name, event.selector, event.action);
  77. });
  78. }
  79. return this.each(function () {
  80. var elem = $(this),
  81. parent = $(options.parent).length > 0 ? $(options.parent) : elem.parent(),
  82. menu = $(options.menu, parent) || $('.dropdown-menu', parent);
  83. // ARIA (adding aria attributes)
  84. if (menu.length) {
  85. elem.attr('aria-haspopup', true);
  86. }
  87. if (!elem.hasClass(options.activeClass)) {
  88. elem.attr('aria-expanded', false);
  89. menu.attr('aria-hidden', true);
  90. } else {
  91. elem.attr('aria-expanded', true);
  92. menu.attr('aria-hidden', false);
  93. }
  94. if (!elem.is('a, button')) {
  95. elem.attr('role', 'button');
  96. elem.attr('tabindex', 0);
  97. }
  98. if (elem.attr('data-trigger-keypress-button')) {
  99. elem.on('keypress', function (e) {
  100. var keyCode = e.keyCode || e.which,
  101. ENTER_CODE = 13;
  102. if (keyCode === ENTER_CODE) {
  103. e.preventDefault();
  104. elem.trigger('click.toggleDropdown');
  105. }
  106. });
  107. }
  108. elem.on('click.toggleDropdown', function () {
  109. var el = actionElem;
  110. if (options.autoclose === true) {
  111. actionElem = $();
  112. $(document).trigger('click.hideDropdown');
  113. actionElem = el;
  114. }
  115. self[el.hasClass(options.activeClass) ? 'closeDropdown' : 'openDropdown'](elem);
  116. return false;
  117. });
  118. });
  119. };
  120. return function (data, el) {
  121. $(el).dropdown(data);
  122. };
  123. });