search_api.admin.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /**
  2. * @file
  3. * Javascript enhancements for the Search API admin pages.
  4. */
  5. (function ($) {
  6. /**
  7. * Allows the re-ordering of enabled data alterations and processors.
  8. */
  9. // Copied from filter.admin.js
  10. Drupal.behaviors.searchApiStatus = {
  11. attach: function (context, settings) {
  12. $('.search-api-status-wrapper input.form-checkbox', context).once('search-api-status', function () {
  13. var $checkbox = $(this);
  14. // Retrieve the tabledrag row belonging to this processor.
  15. var $row = $('#' + $checkbox.attr('id').replace(/-status$/, '-weight'), context).closest('tr');
  16. // Retrieve the vertical tab belonging to this processor.
  17. var $tab = $('#' + $checkbox.attr('id').replace(/-status$/, '-settings'), context).data('verticalTab');
  18. // Bind click handler to this checkbox to conditionally show and hide the
  19. // filter's tableDrag row and vertical tab pane.
  20. $checkbox.bind('click.searchApiUpdate', function () {
  21. if ($checkbox.is(':checked')) {
  22. $row.show();
  23. if ($tab) {
  24. $tab.tabShow().updateSummary();
  25. }
  26. }
  27. else {
  28. $row.hide();
  29. if ($tab) {
  30. $tab.tabHide().updateSummary();
  31. }
  32. }
  33. // Restripe table after toggling visibility of table row.
  34. Drupal.tableDrag['search-api-' + $checkbox.attr('id').replace(/^edit-([^-]+)-.*$/, '$1') + '-order-table'].restripeTable();
  35. });
  36. // Attach summary for configurable items (only for screen-readers).
  37. if ($tab) {
  38. $tab.fieldset.drupalSetSummary(function (tabContext) {
  39. return $checkbox.is(':checked') ? Drupal.t('Enabled') : Drupal.t('Disabled');
  40. });
  41. }
  42. // Trigger our bound click handler to update elements to initial state.
  43. $checkbox.triggerHandler('click.searchApiUpdate');
  44. });
  45. }
  46. };
  47. /**
  48. * Processes elements with the .dropbutton class on page load.
  49. */
  50. Drupal.behaviors.searchApiDropButton = {
  51. attach: function (context, settings) {
  52. var $dropbuttons = $(context).find('.dropbutton-wrapper').once('dropbutton');
  53. if ($dropbuttons.length) {
  54. //$('.dropbutton-toggle', $dropbuttons).click(dropbuttonClickHandler);
  55. // Initialize all buttons.
  56. for (var i = 0, il = $dropbuttons.length; i < il; i++) {
  57. DropButton.dropbuttons.push(new DropButton($dropbuttons[i], settings.dropbutton));
  58. }
  59. // Adds the delegated handler that will toggle dropdowns on click.
  60. $('.dropbutton-toggle', $dropbuttons).click(dropbuttonClickHandler);
  61. }
  62. }
  63. };
  64. /**
  65. * Delegated callback for opening and closing dropbutton secondary actions.
  66. */
  67. function dropbuttonClickHandler(e) {
  68. e.preventDefault();
  69. $(e.target).closest('.dropbutton-wrapper').toggleClass('open');
  70. }
  71. /**
  72. * A DropButton presents an HTML list as a button with a primary action.
  73. *
  74. * All secondary actions beyond the first in the list are presented in a
  75. * dropdown list accessible through a toggle arrow associated with the button.
  76. *
  77. * @param {jQuery} dropbutton
  78. * A jQuery element.
  79. *
  80. * @param {Object} settings
  81. * A list of options including:
  82. * - {String} title: The text inside the toggle link element. This text is
  83. * hidden from visual UAs.
  84. */
  85. function DropButton(dropbutton, settings) {
  86. // Merge defaults with settings.
  87. var options = $.extend({'title': Drupal.t('List additional actions')}, settings);
  88. var $dropbutton = $(dropbutton);
  89. this.$dropbutton = $dropbutton;
  90. this.$list = $dropbutton.find('.dropbutton');
  91. // Find actions and mark them.
  92. this.$actions = this.$list.find('li').addClass('dropbutton-action');
  93. // Add the special dropdown only if there are hidden actions.
  94. if (this.$actions.length > 1) {
  95. // Identify the first element of the collection.
  96. var $primary = this.$actions.slice(0, 1);
  97. // Identify the secondary actions.
  98. var $secondary = this.$actions.slice(1);
  99. $secondary.addClass('secondary-action');
  100. // Add toggle link.
  101. $primary.after(Drupal.theme('dropbuttonToggle', options));
  102. // Bind mouse events.
  103. this.$dropbutton
  104. .addClass('dropbutton-multiple')
  105. /**
  106. * Adds a timeout to close the dropdown on mouseleave.
  107. */
  108. .bind('mouseleave.dropbutton', $.proxy(this.hoverOut, this))
  109. /**
  110. * Clears timeout when mouseout of the dropdown.
  111. */
  112. .bind('mouseenter.dropbutton', $.proxy(this.hoverIn, this))
  113. /**
  114. * Similar to mouseleave/mouseenter, but for keyboard navigation.
  115. */
  116. .bind('focusout.dropbutton', $.proxy(this.focusOut, this))
  117. .bind('focusin.dropbutton', $.proxy(this.focusIn, this));
  118. }
  119. }
  120. /**
  121. * Extend the DropButton constructor.
  122. */
  123. $.extend(DropButton, {
  124. /**
  125. * Store all processed DropButtons.
  126. *
  127. * @type {Array}
  128. */
  129. dropbuttons: []
  130. });
  131. /**
  132. * Extend the DropButton prototype.
  133. */
  134. $.extend(DropButton.prototype, {
  135. /**
  136. * Toggle the dropbutton open and closed.
  137. *
  138. * @param {Boolean} show
  139. * (optional) Force the dropbutton to open by passing true or to close by
  140. * passing false.
  141. */
  142. toggle: function (show) {
  143. var isBool = typeof show === 'boolean';
  144. show = isBool ? show : !this.$dropbutton.hasClass('open');
  145. this.$dropbutton.toggleClass('open', show);
  146. },
  147. hoverIn: function () {
  148. // Clear any previous timer we were using.
  149. if (this.timerID) {
  150. window.clearTimeout(this.timerID);
  151. }
  152. },
  153. hoverOut: function () {
  154. // Wait half a second before closing.
  155. this.timerID = window.setTimeout($.proxy(this, 'close'), 500);
  156. },
  157. open: function () {
  158. this.toggle(true);
  159. },
  160. close: function () {
  161. this.toggle(false);
  162. },
  163. focusOut: function (e) {
  164. this.hoverOut.call(this, e);
  165. },
  166. focusIn: function (e) {
  167. this.hoverIn.call(this, e);
  168. }
  169. });
  170. $.extend(Drupal.theme, {
  171. /**
  172. * A toggle is an interactive element often bound to a click handler.
  173. *
  174. * @param {Object} options
  175. * - {String} title: (optional) The HTML anchor title attribute and
  176. * text for the inner span element.
  177. *
  178. * @return {String}
  179. * A string representing a DOM fragment.
  180. */
  181. dropbuttonToggle: function (options) {
  182. return '<li class="dropbutton-toggle"><button type="button" role="button"><span class="dropbutton-arrow"><span class="visually-hidden">' + options.title + '</span></span></button></li>';
  183. }
  184. });
  185. // Expose constructor in the public space.
  186. Drupal.DropButton = DropButton;
  187. })(jQuery);