diff --git a/facets.libraries.yml b/facets.libraries.yml index 4e5980e..643be6f 100644 --- a/facets.libraries.yml +++ b/facets.libraries.yml @@ -38,3 +38,11 @@ drupal.facets.dropdown-widget: - core/jquery - core/drupal - core/jquery.once +soft-limit: + version: VERSION + js: + js/soft-limit.js: {} + dependencies: + - core/jquery + - core/jquery.once + - core/drupalSettings diff --git a/js/checkbox-widget.js b/js/checkbox-widget.js index 997aaca..ff04ea6 100644 --- a/js/checkbox-widget.js +++ b/js/checkbox-widget.js @@ -7,7 +7,7 @@ "use strict"; - Drupal.facets = {}; + Drupal.facets = Drupal.facets || {}; Drupal.behaviors.facetsCheckboxWidget = { attach: function (context, settings) { Drupal.facets.makeCheckboxes(); @@ -31,7 +31,7 @@ var active = $link.hasClass('is-active'); var description = $link.html(); var href = $link.attr('href'); - var id = $link.data('facet-id'); + var id = $link.data('drupal-facet-item-id'); var checkbox = $(''); var label = $(''); diff --git a/js/soft-limit.js b/js/soft-limit.js new file mode 100644 index 0000000..d639e29 --- /dev/null +++ b/js/soft-limit.js @@ -0,0 +1,50 @@ +/** + * @file + * Provides the soft limit functionality. + */ + +(function ($) { + + "use strict"; + + Drupal.behaviors.facetSoftLimit = { + attach: function (context, settings) { + if (settings.facets.softLimit != undefined) { + $.each(settings.facets.softLimit, function (facet, limit) { + Drupal.facets.applySoftLimit(facet, limit); + }) + } + } + }; + + Drupal.facets = Drupal.facets || {}; + + /** + * Applies the soft limit UI feature to a specific facets list. + */ + Drupal.facets.applySoftLimit = function (facet, limit) { + var zero_based_limit = limit - 1; + var facetsList = $('ul[data-drupal-facet-id="' + facet + '"]'); + + // Hide facets over the limit. + facetsList.find('li:gt(' + zero_based_limit + ')').once().hide(); + + // Add "Show more" / "Show less" links. + facetsList.once().filter(function() { + return $(this).find('li').length > limit; + }).each(function() { + $('').text(Drupal.t('Show more')).click(function() { + if ($(this).siblings().find('li:hidden').length > 0) { + $(this).siblings().find('li:gt(' + zero_based_limit + ')').slideDown(); + $(this).addClass('open').text(Drupal.t('Show less')); + } + else { + $(this).siblings().find('li:gt(' + zero_based_limit + ')').slideUp(); + $(this).removeClass('open').text(Drupal.t('Show more')); + } + return false; + }).insertAfter($(this)); + }); + }; + +})(jQuery); diff --git a/src/Plugin/Block/FacetBlock.php b/src/Plugin/Block/FacetBlock.php index 747f636..3d22a3c 100644 --- a/src/Plugin/Block/FacetBlock.php +++ b/src/Plugin/Block/FacetBlock.php @@ -93,6 +93,9 @@ class FacetBlock extends BlockBase implements ContainerFactoryPluginInterface { ]; } + // Add facet group identifier. + $build['#attributes']['data-drupal-facet-id'] = $facet_id; + return $build; } diff --git a/src/Plugin/facets/widget/CheckboxWidget.php b/src/Plugin/facets/widget/CheckboxWidget.php index b22b4aa..02fbae6 100644 --- a/src/Plugin/facets/widget/CheckboxWidget.php +++ b/src/Plugin/facets/widget/CheckboxWidget.php @@ -28,35 +28,8 @@ class CheckboxWidget extends LinksWidget { */ public function build(FacetInterface $facet) { $this->facet = $facet; - - /** @var \Drupal\facets\Result\Result[] $results */ - $results = $facet->getResults(); - $items = []; - - $configuration = $facet->getWidgetConfigs(); - $this->showNumbers = empty($configuration['show_numbers']) ? FALSE : (bool) $configuration['show_numbers']; - - foreach ($results as $result) { - if (is_null($result->getUrl())) { - $text = $this->extractText($result); - $items[] = ['#markup' => $text]; - } - else { - $items[] = $this->buildListItems($result); - } - } - - $build = [ - '#theme' => 'item_list', - '#items' => $items, - '#attributes' => ['class' => ['js-facets-checkbox-links']], - '#cache' => [ - 'contexts' => [ - 'url.path', - 'url.query_args', - ], - ], - ]; + $build = parent::build($facet); + $build['#attributes']['class'][] = 'js-facets-checkbox-links'; $build['#attached']['library'][] = 'facets/drupal.facets.checkbox-widget'; return $build; @@ -67,7 +40,7 @@ class CheckboxWidget extends LinksWidget { */ protected function buildListItems(ResultInterface $result) { $items = parent::buildListItems($result); - $items['#attributes']['data-facet-id'] = $this->facet->getUrlAlias() . '-' . $result->getRawValue(); + $items['#attributes']['data-drupal-facet-item-id'] = $this->facet->getUrlAlias() . '-' . $result->getRawValue(); return $items; } diff --git a/src/Plugin/facets/widget/LinksWidget.php b/src/Plugin/facets/widget/LinksWidget.php index 31db9ee..19bd326 100644 --- a/src/Plugin/facets/widget/LinksWidget.php +++ b/src/Plugin/facets/widget/LinksWidget.php @@ -61,6 +61,12 @@ class LinksWidget implements WidgetInterface { ], ], ]; + + if (!empty($configuration['soft_limit'])) { + $build['#attached']['library'][] = 'facets/soft-limit'; + $build['#attached']['drupalSettings']['facets']['softLimit'][$facet->id()] = (int) $configuration['soft_limit']; + } + return $build; } @@ -155,20 +161,33 @@ class LinksWidget implements WidgetInterface { /** * {@inheritdoc} + * + * @todo This is inheriting noting. We need a method on the interface and, + * probably, a base class. */ public function buildConfigurationForm(array $form, FormStateInterface $form_state, $config) { + $widget_configs = []; + if (!is_null($config)) { + $widget_configs = $config->get('widget_configs'); + } + // Assure sane defaults. + // @todo This should be handled upstream, in facet entity. Facet schema + // should be fixed and all configs should get sane defaults. + $widget_configs += ['show_numbers' => FALSE, 'soft_limit' => 0]; $form['show_numbers'] = [ '#type' => 'checkbox', '#title' => $this->t('Show the amount of results'), + '#default_value' => $widget_configs['show_numbers'], + ]; + $options = [50, 40, 30, 20, 15, 10, 5, 3]; + $form['soft_limit'] = [ + '#type' => 'select', + '#title' => $this->t('Soft limit'), + '#default_value' => $widget_configs['soft_limit'], + '#options' => [0 => $this->t('No limit')] + array_combine($options, $options), + '#description' => $this->t('Limits the number of displayed facets via JavaScript.'), ]; - - if (!is_null($config)) { - $widget_configs = $config->get('widget_configs'); - if (isset($widget_configs['show_numbers'])) { - $form['show_numbers']['#default_value'] = $widget_configs['show_numbers']; - } - } return $form; }