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/FacetManager/DefaultFacetManager.php b/src/FacetManager/DefaultFacetManager.php
index dd9e30c..a044f6b 100644
--- a/src/FacetManager/DefaultFacetManager.php
+++ b/src/FacetManager/DefaultFacetManager.php
@@ -327,7 +327,7 @@ class DefaultFacetManager {
if (empty($facet->getResults())) {
$empty_behavior = $facet->getEmptyBehavior();
if ($empty_behavior['behavior'] == 'text') {
- return ['#markup' => $empty_behavior['text']];
+ return [['#markup' => $empty_behavior['text']]];
}
else {
return [];
@@ -338,7 +338,7 @@ class DefaultFacetManager {
/** @var \Drupal\facets\Widget\WidgetInterface $widget */
$widget = $this->widgetPluginManager->createInstance($facet->getWidget());
- return $widget->build($facet);
+ return [$widget->build($facet)];
}
/**
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..d8ee5a6 100644
--- a/src/Plugin/facets/widget/LinksWidget.php
+++ b/src/Plugin/facets/widget/LinksWidget.php
@@ -54,6 +54,7 @@ class LinksWidget implements WidgetInterface {
$build = [
'#theme' => 'item_list',
'#items' => $items,
+ '#attributes' => ['data-drupal-facet-id' => $facet->id()],
'#cache' => [
'contexts' => [
'url.path',
@@ -61,6 +62,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 +162,30 @@ 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 = !is_null($config) ? $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;
}