facetapi.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. (function ($) {
  2. Drupal.behaviors.facetapi = {
  3. attach: function(context, settings) {
  4. // Iterates over facet settings, applies functionality like the "Show more"
  5. // links for block realm facets.
  6. // @todo We need some sort of JS API so we don't have to make decisions
  7. // based on the realm.
  8. if (settings.facetapi) {
  9. for (var index in settings.facetapi.facets) {
  10. if (null != settings.facetapi.facets[index].makeCheckboxes) {
  11. Drupal.facetapi.makeCheckboxes(settings.facetapi.facets[index].id);
  12. }
  13. if (null != settings.facetapi.facets[index].limit) {
  14. // Applies soft limit to the list.
  15. Drupal.facetapi.applyLimit(settings.facetapi.facets[index]);
  16. }
  17. }
  18. }
  19. }
  20. }
  21. /**
  22. * Class containing functionality for Facet API.
  23. */
  24. Drupal.facetapi = {}
  25. /**
  26. * Applies the soft limit to facets in the block realm.
  27. */
  28. Drupal.facetapi.applyLimit = function(settings) {
  29. if (settings.limit > 0 && !$('ul#' + settings.id).hasClass('facetapi-processed')) {
  30. // Only process this code once per page load.
  31. $('ul#' + settings.id).addClass('facetapi-processed');
  32. // Ensures our limit is zero-based, hides facets over the limit.
  33. var limit = settings.limit - 1;
  34. $('ul#' + settings.id).find('li:gt(' + limit + ')').hide();
  35. // Adds "Show more" / "Show fewer" links as appropriate.
  36. $('ul#' + settings.id).filter(function() {
  37. return $(this).find('li').length > settings.limit;
  38. }).each(function() {
  39. $('<a href="#" class="facetapi-limit-link"></a>').text(Drupal.t(settings.showMoreText)).click(function() {
  40. if ($(this).siblings().find('li:hidden').length > 0) {
  41. $(this).siblings().find('li:gt(' + limit + ')').slideDown();
  42. $(this).addClass('open').text(Drupal.t(settings.showFewerText));
  43. }
  44. else {
  45. $(this).siblings().find('li:gt(' + limit + ')').slideUp();
  46. $(this).removeClass('open').text(Drupal.t(settings.showMoreText));
  47. }
  48. return false;
  49. }).insertAfter($(this));
  50. });
  51. }
  52. }
  53. /**
  54. * Constructor for the facetapi redirect class.
  55. */
  56. Drupal.facetapi.Redirect = function(href) {
  57. this.href = href;
  58. }
  59. /**
  60. * Method to redirect to the stored href.
  61. */
  62. Drupal.facetapi.Redirect.prototype.gotoHref = function() {
  63. window.location.href = this.href;
  64. }
  65. /**
  66. * Turns all facet links into checkboxes.
  67. * Ensures the facet is disabled if a link is clicked.
  68. */
  69. Drupal.facetapi.makeCheckboxes = function(facet_id) {
  70. var $facet = $('#' + facet_id),
  71. $links = $('a.facetapi-checkbox', $facet);
  72. // Find all checkbox facet links and give them a checkbox.
  73. $links.once('facetapi-makeCheckbox').each(Drupal.facetapi.makeCheckbox);
  74. $links.once('facetapi-disableClick').click(function (e) {
  75. Drupal.facetapi.disableFacet($facet);
  76. });
  77. }
  78. /**
  79. * Disable all facet links and checkboxes in the facet and apply a 'disabled'
  80. * class.
  81. */
  82. Drupal.facetapi.disableFacet = function ($facet) {
  83. $facet.addClass('facetapi-disabled');
  84. $('a.facetapi-checkbox').click(Drupal.facetapi.preventDefault);
  85. $('input.facetapi-checkbox', $facet).attr('disabled', true);
  86. }
  87. /**
  88. * Event listener for easy prevention of event propagation.
  89. */
  90. Drupal.facetapi.preventDefault = function (e) {
  91. e.preventDefault();
  92. }
  93. /**
  94. * Replace an unclick link with a checked checkbox.
  95. */
  96. Drupal.facetapi.makeCheckbox = function() {
  97. var $link = $(this),
  98. active = $link.hasClass('facetapi-active');
  99. if (!active && !$link.hasClass('facetapi-inactive')) {
  100. // Not a facet link.
  101. return;
  102. }
  103. // Derive an ID and label for the checkbox based on the associated link.
  104. // The label is required for accessibility, but it duplicates information
  105. // in the link itself, so it should only be shown to screen reader users.
  106. var id = this.id + '--checkbox',
  107. description = $link.find('.element-invisible').html(),
  108. label = $('<label class="element-invisible" for="' + id + '">' + description + '</label>'),
  109. checkbox = $('<input type="checkbox" class="facetapi-checkbox" id="' + id + '" />'),
  110. // Get the href of the link that is this DOM object.
  111. href = $link.attr('href'),
  112. redirect = new Drupal.facetapi.Redirect(href);
  113. checkbox.click(function (e) {
  114. Drupal.facetapi.disableFacet($link.parents('ul.facetapi-facetapi-checkbox-links'));
  115. redirect.gotoHref();
  116. });
  117. if (active) {
  118. checkbox.attr('checked', true);
  119. // Add the checkbox and label, hide the link.
  120. $link.before(label).before(checkbox).hide();
  121. }
  122. else {
  123. $link.before(label).before(checkbox);
  124. }
  125. }
  126. })(jQuery);