diff --git a/facets.libraries.yml b/facets.libraries.yml index 84a7c46..62daaf3 100644 --- a/facets.libraries.yml +++ b/facets.libraries.yml @@ -14,10 +14,17 @@ drupal.facets.edit-facet: dependencies: - core/jquery - core/drupal - - core/jquery.once drupal.facets.admin_css: version: VERSION css: theme: css/facets.admin.css: {} + +drupal.facets.checkbox-widget: + version: VERSION + js: + js/checkbox-widget.js: {} + dependencies: + - core/jquery + - core/drupal diff --git a/js/checkbox-widget.js b/js/checkbox-widget.js new file mode 100644 index 0000000..608cfc0 --- /dev/null +++ b/js/checkbox-widget.js @@ -0,0 +1,79 @@ +/** + * @file + * Transforms links into checkboxes. + */ + +(function ($) { + + "use strict"; + + Drupal.facets = {}; + + Drupal.behaviors.facetsCheckboxWidget = { + attach: function (context, settings) { + Drupal.facets.makeCheckboxes(); + } + }; + + + /** + * Turns all facet links into checkboxes. + * Ensures the facet is disabled if a link is clicked. + */ + Drupal.facets.makeCheckboxes = function () { + + var $checkbox_facets = $('.js-facets-checkbox-links'), + $links = $('.facet-item a', $checkbox_facets); + + // Find all checkbox facet links and give them a checkbox. + $links.once('facets-makeCheckbox').each(Drupal.facets.makeCheckbox); + } + + + /** + * Replace an unclick link with a checked checkbox. + */ + Drupal.facets.makeCheckbox = function () { + var $link = $(this); + var active = $link.hasClass('is-active'); + var description = $link.html(); + var href = $link.attr('href'); + var id = $link.attr('id'); + + var checkbox = $(''); + var label = $(''); + + checkbox.change(function (e) { + Drupal.facets.disableFacet($link.parents('.js-facets-checkbox-links')); + window.location.href = $(this).data('facetsredir'); + }); + + if (active) { + checkbox.attr('checked', true); + label.find('.facet-deactivate').remove(); + } + + $link.before(checkbox).before(label).hide(); + + } + + + /** + * Disable all facet links and checkboxes in the facet and apply a 'disabled' + * class. + */ + Drupal.facets.disableFacet = function ($facet) { + $facet.addClass('facets-disabled'); + $('input.facets-checkbox').click(Drupal.facets.preventDefault); + $('input.facetapi-checkbox', $facet).attr('disabled', true); + } + + + /** + * Event listener for easy prevention of event propagation. + */ + Drupal.facets.preventDefault = function (e) { + e.preventDefault(); + } + +})(jQuery); diff --git a/src/Form/CheckboxWidgetForm.php b/src/Form/CheckboxWidgetForm.php deleted file mode 100644 index 33beff9..0000000 --- a/src/Form/CheckboxWidgetForm.php +++ /dev/null @@ -1,135 +0,0 @@ -facet = $facet; - } - - /** - * {@inheritdoc} - */ - public function getBaseFormId() { - return 'facets_checkbox_widget'; - } - - /** - * {@inheritdoc} - */ - public function getFormId() { - return $this->getBaseFormId() . '__' . $this->facet->id(); - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state) { - $facet = $this->facet; - - /** @var \Drupal\facets\Result\Result[] $results */ - $results = $facet->getResults(); - - $configuration = $facet->getWidgetConfigs(); - $show_numbers = (bool) isset($configuration['show_numbers']) ? $configuration['show_numbers'] : FALSE; - $form[$facet->getFieldAlias()] = [ - '#type' => 'checkboxes', - '#title' => $facet->getName(), - ]; - - $options = []; - foreach ($results as $result) { - $text = $result->getDisplayValue(); - if ($show_numbers) { - $text .= ' (' . $result->getCount() . ')'; - } - - $options[$result->getRawValue()] = $text; - - if ($result->isActive()) { - $form[$facet->getFieldAlias()]['#default_value'][] = $result->getRawValue(); - } - } - - $form[$facet->getFieldAlias()]['#options'] = $options; - - $form[$facet->id() . '_submit'] = [ - '#type' => 'submit', - '#value' => 'submit', - ]; - - return $form; - } - - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, FormStateInterface $form_state) {} - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - $values = $form_state->getValues(); - $facet = $this->facet; - - $result_link = FALSE; - $active_items = []; - - foreach ($values[$facet->getFieldAlias()] as $key => $value) { - if ($value !== 0) { - $active_items[] = $value; - } - } - - foreach ($facet->getResults() as $result) { - if (in_array($result->getRawValue(), $active_items)) { - $result_link = $result->getUrl(); - } - } - - // We have an active item, so we redirect to the page that has that facet - // selected. This should be an absolute link because RedirectResponse is a - // symfony class that requires a full URL. - if ($result_link instanceof Url) { - $result_link->setAbsolute(); - $form_state->setResponse(new RedirectResponse($result_link->toString())); - return; - } - - // The form was submitted but nothing was active in the form, we should - // still redirect, but the url for the new page can't come from a result. - // So we're redirecting to the facet source's page. - $path = $facet->getFacetSource()->getPath(); - if (substr($path, 0, 1) !== '/') { - $path = '/' . $path; - } - $link = Url::fromUserInput($path); - $link->setAbsolute(); - $form_state->setResponse(new RedirectResponse($link->toString())); - } - -} diff --git a/src/Plugin/facets/widget/CheckboxWidget.php b/src/Plugin/facets/widget/CheckboxWidget.php index 48ffe93..9d0f3ce 100644 --- a/src/Plugin/facets/widget/CheckboxWidget.php +++ b/src/Plugin/facets/widget/CheckboxWidget.php @@ -3,9 +3,11 @@ namespace Drupal\facets\Plugin\facets\widget; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\facets\FacetInterface; use Drupal\facets\Form\CheckboxWidgetForm; +use Drupal\facets\Result\ResultInterface; use Drupal\facets\Widget\WidgetInterface; /** @@ -17,44 +19,47 @@ use Drupal\facets\Widget\WidgetInterface; * description = @Translation("A configurable widget that shows a list of checkboxes"), * ) */ -class CheckboxWidget implements WidgetInterface { - - use StringTranslationTrait; +class CheckboxWidget extends LinksWidget { /** * {@inheritdoc} */ public function build(FacetInterface $facet) { - $form_builder = \Drupal::getContainer()->get('form_builder'); - $form_object = new CheckboxWidgetForm($facet); - return $form_builder->getForm($form_object); - } + /** @var \Drupal\facets\Result\Result[] $results */ + $results = $facet->getResults(); + $items = []; - /** - * {@inheritdoc} - */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state, $config) { - - $form['show_numbers'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Show the amount of results'), - ]; + $configuration = $facet->getWidgetConfigs(); + $this->showNumbers = empty($configuration['show_numbers']) ? FALSE : (bool) $configuration['show_numbers']; - 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']; + foreach ($results as $result) { + if (is_null($result->getUrl())) { + $text = $this->extractText($result); + $items[] = ['#markup' => $text]; + } + else { + $items[] = $this->buildListItems($result, $facet); } } - return $form; + $build = [ + '#theme' => 'item_list', + '#items' => $items, + '#attributes' => ['class' => ['js-facets-checkbox-links']], + '#cache' => [ + 'contexts' => [ + 'url.path', + 'url.query_args', + ], + ], + ]; + $build['#attached']['library'][] = 'facets/drupal.facets.checkbox-widget'; + return $build; } - /** - * {@inheritdoc} - */ - public function getQueryType($query_types) { - return $query_types['string']; + protected function buildListItems(ResultInterface $result, FacetInterface $facet) { + $items = parent::buildListItems($result); + $items['#attributes']['id'] = $facet->getUrlAlias() . '-' . $result->getRawValue(); + return $items; } - }