How to build an exposed locality views filter

Created on 25 April 2024, about 2 months ago
Updated 4 June 2024, 19 days ago

Address is a great module to store location values.
Together with geofield and views it is possible to build great maps and lists.

Now i like to filter a view for locality/city names, that are used in a address field exposed in a select list.
Didnt found an module yet. :-/
Is there a best practice or can you give a hint on how to archive this?

πŸ’¬ Support request
Status

Active

Version

2.0

Component

Documentation

Created by

πŸ‡©πŸ‡ͺGermany achikas Lower Saxony, Germany

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @achikas
  • there is an option to group the exposed filter and then use contains "suburb name" as the name and value:



  • πŸ‡΅πŸ‡±Poland Pozi
    
    use Drupal\Core\Cache\Cache;
    use Drupal\node\Entity\Node;
    use Drupal\Core\Cache\CacheBackendInterface;
    
    define('CLINIC_ADDRESS_LOCALITY_CACHE_KEY', 'sql_query_cache_key::field_clinic_address_locality');
    define('CLINIC_ADDRESS_LOCALITY_CACHE_TAG', 'sql_query_cache_tags::field_clinic_address_locality');
    
    /**
     * Implements hook_ENTITY_TYPE_update() for node entities.
     */
    function soft4net_node_update(Node $node) {
        if ($node->getType() == 'clinic') {
            // Invalidate the custom cache tag.
            Cache::invalidateTags([CLINIC_ADDRESS_LOCALITY_CACHE_TAG]);
        }
    }
      
    /**
     * Implements hook_ENTITY_TYPE_delete() for node entities.
     */
    function soft4net_node_delete(Node $node) {
        if ($node->getType() == 'clinic') {
            // Invalidate the custom cache tag.
            Cache::invalidateTags([CLINIC_ADDRESS_LOCALITY_CACHE_TAG]);
        }
    }
    
    /**
     * Function to execute and cache the custom SQL query.
     */
    function soft4net_get_cached_query_results__field_clinic_address_locality() {
        $cache = \Drupal::cache()->get(CLINIC_ADDRESS_LOCALITY_CACHE_KEY);
        if ($cache) {
            return $cache->data;
        }
        else {  
            // SELECT DISTINCT `field_clinic_address_locality` FROM `node__field_clinic_address` WHERE 1
            $database = \Drupal::database();
            $query = $database->select('node__field_clinic_address', 'nfca')
                ->fields('nfca', ['field_clinic_address_locality'])
            ;
    
            // $query->accessCheck(FALSE);
            
            $results = $query->distinct()->execute()->fetchCol();
            // $result = $query->distinct()->execute()->fetchAssoc();
            // $result = $query->distinct()->execute()->fetchAll();
    
            \Drupal::cache()->set(CLINIC_ADDRESS_LOCALITY_CACHE_KEY, $results, CacheBackendInterface::CACHE_PERMANENT, [CLINIC_ADDRESS_LOCALITY_CACHE_TAG]);
        
            return $results;
        }
    }
    
    /**
     * Implements hook_views_pre_view().
     */
    function soft4net_views_pre_view(\Drupal\views\ViewExecutable $view, string $display_id, array $args) {
        if ($view->id() === 'clinics' && $display_id === 'clinics_list') {
    //         $field_clinic_address_locality_options = $view->getHandler($view->current_display, 'filter', 'field_clinic_address_locality');
    // echo '<pre>';
    // print_r($field_clinic_address_locality_options);
    // echo '</pre>';
    
            $field_clinic_address_locality_options = [
                "id" => "field_clinic_address_locality",
                "table" => "node__field_clinic_address",
                "field" => "field_clinic_address_locality",
                "relationship" => "none",
                "group_type" => "group",
                "admin_label" => "",
                "plugin_id" => "string",
                "operator" => "=", // "and",
                "value" => "",            
                "group" => 1,
                "exposed" => TRUE,
                "expose" => [
                    "operator_id" => "field_clinic_address_locality_op",
                    "label" => t('City', [], ['context' => 'Address label']) . ':',
                    "description" => "",
                    "use_operator" => FALSE,
                    "operator" => "field_clinic_address_locality_op",
                    "operator_limit_selection" => FALSE,
                    "operator_list" => [],
                    "identifier" => "field_clinic_address_locality",
                    "required" => FALSE,
                    "remember" => FALSE,
                    "multiple" => FALSE,
                    "remember_roles" => [
                        "authenticated" => "authenticated",
                        "anonymous" => "0",
                    ],
                    "reduce" => FALSE,
                ],
                "is_grouped" => TRUE,
                "group_info" => [
                    "label" => t('City', [], ['context' => 'Address label']) . ':',
                    "description" => "",
                    "identifier" => "field_clinic_address_locality",
                    "optional" => TRUE,
                    "widget" => "select",
                    "multiple" => FALSE,
                    "remember" => FALSE,
                    "default_group" => "All",
                    "default_group_multiple" => [],
                    "group_items" => [
                    ],
                ],
            ];
    
            // $field_clinic_address_locality_options['group_info']['group_items'] = [];
    
            $results = soft4net_get_cached_query_results__field_clinic_address_locality();
            array_walk($results, function($city, $key) use (&$field_clinic_address_locality_options) {
                $field_clinic_address_locality_options['group_info']['group_items'][$city] = [
                    "title" => $city,
                    "operator" => "=",
                    "value" => $city,
                ];
            });
    
            $view->addHandler($view->current_display, 'filter', 'node__field_clinic_address', 'field_clinic_address_locality', $field_clinic_address_locality_options);
        }
    
    }
    
    
Production build 0.69.0 2024