Skip to content

Commit

Permalink
Merge pull request #399 from localgovdrupal/feature/3.x/326-facets-fo…
Browse files Browse the repository at this point in the history
…rm-support

Feature: Support for the facets_form module
  • Loading branch information
Adnan-cds authored Oct 12, 2024
2 parents ce2c5b5 + c9d3bb8 commit 4aaa6e6
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 123 deletions.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
"require-dev": {
"localgovdrupal/localgov_services": "^2.1",
"localgovdrupal/localgov_openreferral": "^2.0",
"localgovdrupal/localgov_paragraphs": "^2.3"
"localgovdrupal/localgov_paragraphs": "^2.3",
"drupal/facets_form": "^1.0"
},
"suggest": {
"drupal/facets_form": "Displays facets as checkboxes within a form.",
"localgovdrupal/localgov_openreferral": "Enables Open Referral output of Directories",
"localgovdrupal/localgov_paragraphs": "For Directory Promo Page content type in Directories"
},
Expand Down
49 changes: 49 additions & 0 deletions localgov_directories.module
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\facets\FacetInterface;
use Drupal\field\FieldConfigInterface;
Expand Down Expand Up @@ -53,6 +54,9 @@ function localgov_directories_theme() {
'base hook' => 'facets_item_list',
'template' => 'facets-item-list--dropdown--localgov-directories-facets',
],
'checkboxes__localgov_directories_facets' => [
'base hook' => 'checkboxes',
],
];
}

Expand Down Expand Up @@ -218,6 +222,51 @@ function localgov_directories_preprocess_facets_item_list(array &$variables) {
}
}

/**
* Implements hook_theme_suggestions_HOOK_alter() for hook_theme_suggestions_checkbox_alter().
*/
function localgov_directories_theme_suggestions_checkboxes_alter(array &$suggestions, array $variables) {

$is_dir_facet_checkbox = isset($variables['element']['#name']) ? ($variables['element']['#name'] === Directory::FACET_CONFIG_ENTITY_ID || $variables['element']['#name'] === Directory::FACET_CONFIG_ENTITY_ID_FOR_PROXIMITY_SEARCH) : FALSE;
if ($is_dir_facet_checkbox) {
$suggestions[] = 'checkboxes__localgov_directories_facets';
}
}

/**
* Preprocess for LocalGov Directory facet checkboxes.
*
* Groups facet checkboxes by their parent LocalGov Directory facet types.
*/
function template_preprocess_checkboxes__localgov_directories_facets(array &$variables) {

\Drupal::service('class_resolver')
->getInstanceFromDefinition(DirectoryExtraFieldDisplay::class)
->preprocessFacetCheckboxes($variables);
}

/**
* Implements hook_form_FORM_ID_alter() for hook_form_facets_form_alter().
*
* Hides form submit buttons for an empty LocalGov Directory facet form.
*
* @see Drupal\facets\FacetManager\DefaultFacetManager::build()
*/
function localgov_directories_form_facets_form_alter(array &$form, FormStateInterface $form_state) {

$has_empty_dir_facet = FALSE;
if (isset($form['facets'][Directory::FACET_CONFIG_ENTITY_ID][0]['#attributes']['class'][0])) {
$has_empty_dir_facet = $form['facets'][Directory::FACET_CONFIG_ENTITY_ID][0]['#attributes']['class'][0] === Directory::FACET_EMPTY_CLASS;
}
elseif (isset($form['facets'][Directory::FACET_CONFIG_ENTITY_ID_FOR_PROXIMITY_SEARCH][0]['#attributes']['class'][0])) {
$has_empty_dir_facet = $form['facets'][Directory::FACET_CONFIG_ENTITY_ID_FOR_PROXIMITY_SEARCH][0]['#attributes']['class'][0] === Directory::FACET_EMPTY_CLASS;
}

if ($has_empty_dir_facet) {
$form['actions']['#attributes']['class'][] = 'hidden';
}
}

/**
* Prepares variables for directory facets templates.
*
Expand Down
4 changes: 4 additions & 0 deletions src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class Constants {

const FACET_CONFIG_FILE_FOR_PROXIMITY_SEARCH = 'facets.facet.localgov_directories_facets_proximity_search';

const FACET_EMPTY_CLASS = 'facet-empty';

const FACETS_FORM_DIR_FACET_BLOCK_PLUGIN_ID = 'facets_form:search_api:views_embed__localgov_directory_channel__node_embed';

const CHANNEL_VIEW = 'localgov_directory_channel';

const CHANNEL_VIEW_DISPLAY = 'node_embed';
Expand Down
61 changes: 44 additions & 17 deletions src/DirectoryExtraFieldDisplay.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
Expand Down Expand Up @@ -305,13 +306,47 @@ public function preprocessFacetList(array &$variables) {
}
}

$variables['items'] = $this->groupDirFacetItems($variables['items']);

if (!empty($show_reset_link)) {
// Add the reset link.
$variables['items']['show_reset_all']['items'][] = $show_reset_link;
$reset_all = $variables['items']['show_reset_all'];
// Place the reset link at the top of the facet filters.
array_unshift($variables['items'], $reset_all);
array_pop($variables['items']);
}
}

/**
* Groups facet checkboxes.
*
* Prepares variables for facet checkboxes grouped by LocalGov Directory facet
* types.
*
* @see templates/checkboxes--localgov-directories-facets.html.twig
* @see template_preprocess_checkboxes__localgov_directories_facets()
*/
public function preprocessFacetCheckboxes(array &$variables): void {

$facet_id_list = Element::children($variables['element']);
$facet_options = array_filter($variables['element'], fn($facet_id) => in_array($facet_id, $facet_id_list, strict: TRUE), ARRAY_FILTER_USE_KEY);
$variables['grouped_options'] = $this->groupDirFacetItems($facet_options);
}

/**
* Groups facet items by LocalGov Directory facet types.
*/
public function groupDirFacetItems(array $facet_items): array {

$facet_storage = $this->entityTypeManager
->getStorage(Directory::FACET_CONFIG_ENTITY_ID);
$group_items = [];
foreach ($variables['items'] as $key => $item) {
if ($entity = $facet_storage->load($item['value']['#attributes']['data-drupal-facet-item-value'])) {
assert($entity instanceof LocalgovDirectoriesFacets);
$group_items[$entity->bundle()]['items'][$key] = $item;
foreach ($facet_items as $key => $item) {
$facet_id = $item['value']['#attributes']['data-drupal-facet-item-value'] ?? $key;
if ($facet_entity = $facet_storage->load($facet_id)) {
assert($facet_entity instanceof LocalgovDirectoriesFacets);
$group_items[$facet_entity->bundle()]['items'][$key] = $item;
}
}

Expand All @@ -331,22 +366,14 @@ public function preprocessFacetList(array &$variables) {
$type_storage = $this->entityTypeManager
->getStorage(Directory::FACET_TYPE_CONFIG_ENTITY_ID);
foreach ($group_items as $bundle => $items) {
$entity = $type_storage->load($bundle);
assert($entity instanceof LocalgovDirectoriesFacetsType);
$group_items[$bundle]['title'] = Html::escape($this->entityRepository->getTranslationFromContext($entity)->label());
$group_items[$bundle]['weight'] = $entity->get('weight');
$facet_type_entity = $type_storage->load($bundle);
assert($facet_type_entity instanceof LocalgovDirectoriesFacetsType);
$group_items[$bundle]['title'] = Html::escape($this->entityRepository->getTranslationFromContext($facet_type_entity)->label());
$group_items[$bundle]['weight'] = $facet_type_entity->get('weight');
}
uasort($group_items, static::compareFacetBundlesByWeight(...));
$variables['items'] = $group_items;

if (!empty($show_reset_link)) {
// Add the reset link.
$variables['items']['show_reset_all']['items'][] = $show_reset_link;
$reset_all = $variables['items']['show_reset_all'];
// Place the reset link at the top of the facet filters.
array_unshift($variables['items'], $reset_all);
array_pop($variables['items']);
}
return $group_items;
}

/**
Expand Down
40 changes: 40 additions & 0 deletions templates/checkboxes--localgov-directories-facets.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{#
/**
* @file
* Default theme template for directory facet checkboxes.
*
* These checkboxes are used within the facets_form_checkbox facet widget.
*
* Available variables:
* - title: Optional list title.
* - grouped_options: checkboxes grouped by their corresponding LocalGov Directory facet type. Each group array contains:
* - title: Label of the facet type.
* - items: Checkbox element.
* - weight: Sorting weight of the facet type.
* - attributes: HTML attributes to be applied to the list.
*
* @see template_preprocess_checkboxes__localgov_directories_facets()
*/
#}
<div class="facets-widget facets-widget--facets-form-checkbox">

{%- if title is not empty -%}
<h3>{{ title }}</h3>
{%- endif -%}

{% if grouped_options %}
<ul{{ attributes }}>
{%- for group_id, group_record in grouped_options -%}
<li>
<h4 class="facet-group__title">{{ group_record.title }}</h4>

<ul{{ attributes.addClass('facet-filter-checkboxes') }}>
{%- for checkbox in group_record.items -%}
<li>{{ checkbox }}</li>
{%- endfor -%}
</ul>
</li>
{%- endfor -%}
</ul>
{%- endif %}
</div>
Loading

0 comments on commit 4aaa6e6

Please sign in to comment.