diff --git a/src/Plugin/facets/widget/CheckboxWidget.php b/src/Plugin/facets/widget/CheckboxWidget.php index 685ffea..d45da2e 100644 --- a/src/Plugin/facets/widget/CheckboxWidget.php +++ b/src/Plugin/facets/widget/CheckboxWidget.php @@ -7,10 +7,14 @@ namespace Drupal\facets\Plugin\facets\widget; +use Drupal\Core\Cache\CacheableRedirectResponse; +use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Link; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\facets\FacetInterface; use Drupal\facets\Widget\WidgetInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * The checkbox / radios widget. @@ -21,7 +25,7 @@ use Drupal\facets\Widget\WidgetInterface; * description = @Translation("A configurable widget that shows a list of checkboxes"), * ) */ -class CheckboxWidget implements WidgetInterface { +class CheckboxWidget implements WidgetInterface, FormInterface { use StringTranslationTrait; @@ -44,33 +48,14 @@ class CheckboxWidget implements WidgetInterface { * {@inheritdoc} */ public function build(FacetInterface $facet) { - /** @var \Drupal\facets\Result\Result[] $results */ - $results = $facet->getResults(); - $items = []; + $form_builder = \Drupal::getContainer()->get('form_builder'); - $configuration = $facet->getWidgetConfigs(); - $show_numbers = (bool) $configuration['show_numbers']; + // The form builder's getForm method accepts 1 argument in the interface, + // the form ID. Extra arguments get passed into the form states addBuildInfo + // method. This way we can pass the facet to the ::buildForm method, it uses + // FormState::getBuildInfo to get the facet out. + $build = $form_builder->getForm(static::class, $facet); - foreach ($results as $result) { - if ($result->getCount()) { - // Get the link. - $text = $result->getDisplayValue(); - if ($show_numbers) { - $text .= ' (' . $result->getCount() . ')'; - } - if ($result->isActive()) { - $text = '(-) ' . $text; - } - $link = $this->linkGenerator()->generate($text, $result->getUrl()); - $items[] = $link; - } - } - $build = [ - '#theme' => 'item_list', - '#items' => $items, - ]; - - $build['#prefix'] = $this->t('Checkboxes'); return $build; } @@ -114,4 +99,91 @@ class CheckboxWidget implements WidgetInterface { return $this->linkGenerator; } + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'facets_checkbox_widget'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + + /** @var \Drupal\facets\FacetInterface $facet */ + $build_info = $form_state->getBuildInfo(); + $facet = $build_info['args'][0]; + + /** @var \Drupal\facets\Result\Result[] $results */ + $results = $facet->getResults(); + + $configuration = $facet->getWidgetConfigs(); + $show_numbers = (bool) $configuration['show_numbers']; + $form[$facet->getFieldAlias()] = [ + '#type' => 'checkboxes', + '#title' => $facet->getName(), + ]; + + $options = array(); + 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(); + + /** @var \Drupal\facets\FacetInterface $facet */ + $build_info = $form_state->getBuildInfo(); + $facet = $build_info['args'][0]; + $result_link = FALSE; + + 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 redirecting to that page. + if ($result_link instanceof Link) { + return new CacheableRedirectResponse($result_link->toUriString()); + } + + // Form was submitted, but nothing was selected, so we should submit to the + // facet. + return new CacheableRedirectResponse('/' . $facet->getFacetSource()->getPath()); + } }