function FilterPluginBase::buildExposedFiltersGroupForm

Same name in other branches
  1. 9 core/modules/views/src/Plugin/views/filter/FilterPluginBase.php \Drupal\views\Plugin\views\filter\FilterPluginBase::buildExposedFiltersGroupForm()
  2. 10 core/modules/views/src/Plugin/views/filter/FilterPluginBase.php \Drupal\views\Plugin\views\filter\FilterPluginBase::buildExposedFiltersGroupForm()
  3. 11.x core/modules/views/src/Plugin/views/filter/FilterPluginBase.php \Drupal\views\Plugin\views\filter\FilterPluginBase::buildExposedFiltersGroupForm()

Build the form to let users create the group of exposed filters. This form is displayed when users click on button 'Build group'

1 call to FilterPluginBase::buildExposedFiltersGroupForm()
FilterPluginBase::showBuildGroupForm in core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
Shortcut to display the exposed options form.

File

core/modules/views/src/Plugin/views/filter/FilterPluginBase.php, line 941

Class

FilterPluginBase
Base class for Views filters handler plugins.

Namespace

Drupal\views\Plugin\views\filter

Code

protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form_state) {
    if (empty($this->options['exposed']) || empty($this->options['is_grouped'])) {
        return;
    }
    $form['#theme'] = 'views_ui_build_group_filter_form';
    // #flatten will move everything from $form['group_info'][$key] to $form[$key]
    // prior to rendering. That's why the preRender for it needs to run first,
    // so that when the next preRender (the one for fieldsets) runs, it gets
    // the flattened data.
    array_unshift($form['#pre_render'], [
        get_class($this),
        'preRenderFlattenData',
    ]);
    $form['group_info']['#flatten'] = TRUE;
    if (!empty($this->options['group_info']['identifier'])) {
        $identifier = $this->options['group_info']['identifier'];
    }
    else {
        $identifier = 'group_' . $this->options['expose']['identifier'];
    }
    $form['group_info']['identifier'] = [
        '#type' => 'textfield',
        '#default_value' => $identifier,
        '#title' => $this->t('Filter identifier'),
        '#size' => 40,
        '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'),
    ];
    $form['group_info']['label'] = [
        '#type' => 'textfield',
        '#default_value' => $this->options['group_info']['label'],
        '#title' => $this->t('Label'),
        '#size' => 40,
    ];
    $form['group_info']['description'] = [
        '#type' => 'textfield',
        '#default_value' => $this->options['group_info']['description'],
        '#title' => $this->t('Description'),
        '#size' => 60,
    ];
    $form['group_info']['optional'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Optional'),
        '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'),
        '#default_value' => $this->options['group_info']['optional'],
    ];
    $form['group_info']['multiple'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Allow multiple selections'),
        '#description' => $this->t('Enable to allow users to select multiple items.'),
        '#default_value' => $this->options['group_info']['multiple'],
    ];
    $form['group_info']['widget'] = [
        '#type' => 'radios',
        '#default_value' => $this->options['group_info']['widget'],
        '#title' => $this->t('Widget type'),
        '#options' => [
            'radios' => $this->t('Radios'),
            'select' => $this->t('Select'),
        ],
        '#description' => $this->t('Select which kind of widget will be used to render the group of filters'),
    ];
    $form['group_info']['remember'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Remember'),
        '#description' => $this->t('Remember the last setting the user gave this filter.'),
        '#default_value' => $this->options['group_info']['remember'],
    ];
    if (!empty($this->options['group_info']['identifier'])) {
        $identifier = $this->options['group_info']['identifier'];
    }
    else {
        $identifier = 'group_' . $this->options['expose']['identifier'];
    }
    $form['group_info']['identifier'] = [
        '#type' => 'textfield',
        '#default_value' => $identifier,
        '#title' => $this->t('Filter identifier'),
        '#size' => 40,
        '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'),
    ];
    $form['group_info']['label'] = [
        '#type' => 'textfield',
        '#default_value' => $this->options['group_info']['label'],
        '#title' => $this->t('Label'),
        '#size' => 40,
    ];
    $form['group_info']['optional'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Optional'),
        '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'),
        '#default_value' => $this->options['group_info']['optional'],
    ];
    $form['group_info']['widget'] = [
        '#type' => 'radios',
        '#default_value' => $this->options['group_info']['widget'],
        '#title' => $this->t('Widget type'),
        '#options' => [
            'radios' => $this->t('Radios'),
            'select' => $this->t('Select'),
        ],
        '#description' => $this->t('Select which kind of widget will be used to render the group of filters'),
    ];
    $form['group_info']['remember'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Remember'),
        '#description' => $this->t('Remember the last setting the user gave this filter.'),
        '#default_value' => $this->options['group_info']['remember'],
    ];
    // The string '- Any -' will not be rendered.
    // @see theme_views_ui_build_group_filter_form()
    $groups = [
        'All' => $this->t('- Any -'),
    ];
    // Provide 3 options to start when we are in a new group.
    if (count($this->options['group_info']['group_items']) == 0) {
        $this->options['group_info']['group_items'] = array_fill(1, 3, []);
    }
    // After the general settings, comes a table with all the existent groups.
    $default_weight = 0;
    foreach ($this->options['group_info']['group_items'] as $item_id => $item) {
        if (!$form_state->isValueEmpty([
            'options',
            'group_info',
            'group_items',
            $item_id,
            'remove',
        ])) {
            continue;
        }
        // Each rows contains three widgets:
        // a) The title, where users define how they identify a pair of operator | value
        // b) The operator
        // c) The value (or values) to use in the filter with the selected operator
        // In each row, we have to display the operator form and the value from
        // $row acts as a fake form to render each widget in a row.
        $row = [];
        $groups[$item_id] = $this->t('Grouping @id', [
            '@id' => $item_id,
        ]);
        $this->operatorForm($row, $form_state);
        // Force the operator form to be a select box. Some handlers uses
        // radios and they occupy a lot of space in a table row.
        $row['operator']['#type'] = 'select';
        $row['operator']['#title'] = '';
        $this->valueForm($row, $form_state);
        // Fix the dependencies to update value forms when operators changes. This
        // is needed because forms are inside a new form and their IDs changes.
        // Dependencies are used when operator changes from to 'Between',
        // 'Not Between', etc, and two or more widgets are displayed.
        FormHelper::rewriteStatesSelector($row['value'], ':input[name="options[operator]"]', ':input[name="options[group_info][group_items][' . $item_id . '][operator]"]');
        // Set default values.
        $children = Element::children($row['value']);
        if (!empty($children)) {
            foreach ($children as $child) {
                if (!empty($row['value'][$child]['#states']['visible'])) {
                    foreach ($row['value'][$child]['#states']['visible'] as $state) {
                        if (isset($state[':input[name="options[group_info][group_items][' . $item_id . '][operator]"]'])) {
                            $row['value'][$child]['#title'] = '';
                            // Exit this loop and process the next child element.
                            break;
                        }
                    }
                }
                if (!empty($this->options['group_info']['group_items'][$item_id]['value'][$child])) {
                    $row['value'][$child]['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'][$child];
                }
            }
        }
        else {
            if (isset($this->options['group_info']['group_items'][$item_id]['value']) && $this->options['group_info']['group_items'][$item_id]['value'] != '') {
                $row['value']['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'];
            }
        }
        if (!empty($this->options['group_info']['group_items'][$item_id]['operator'])) {
            $row['operator']['#default_value'] = $this->options['group_info']['group_items'][$item_id]['operator'];
        }
        $default_title = '';
        if (!empty($this->options['group_info']['group_items'][$item_id]['title'])) {
            $default_title = $this->options['group_info']['group_items'][$item_id]['title'];
        }
        // Per item group, we have a title that identifies it.
        $form['group_info']['group_items'][$item_id] = [
            'title' => [
                '#title' => $this->t('Label'),
                '#title_display' => 'invisible',
                '#type' => 'textfield',
                '#size' => 20,
                '#default_value' => $default_title,
            ],
            'operator' => $row['operator'],
            'value' => $row['value'],
            // No title is given here, since this input is never displayed. It is
            // only triggered by JavaScript.
'remove' => [
                '#type' => 'checkbox',
                '#id' => 'views-removed-' . $item_id,
                '#attributes' => [
                    'class' => [
                        'views-remove-checkbox',
                    ],
                ],
                '#default_value' => 0,
            ],
            'weight' => [
                '#title' => $this->t('Weight'),
                '#title_display' => 'invisible',
                '#type' => 'weight',
                '#delta' => count($this->options['group_info']['group_items']),
                '#default_value' => $default_weight++,
                '#attributes' => [
                    'class' => [
                        'weight',
                    ],
                ],
            ],
        ];
    }
    // From all groups, let chose which is the default.
    $form['group_info']['default_group'] = [
        '#type' => 'radios',
        '#options' => $groups,
        '#default_value' => $this->options['group_info']['default_group'],
        '#required' => TRUE,
        '#attributes' => [
            'class' => [
                'default-radios',
            ],
        ],
    ];
    // From all groups, let chose which is the default.
    $form['group_info']['default_group_multiple'] = [
        '#type' => 'checkboxes',
        '#options' => $groups,
        '#default_value' => $this->options['group_info']['default_group_multiple'],
        '#attributes' => [
            'class' => [
                'default-checkboxes',
            ],
        ],
    ];
    $form['group_info']['add_group'] = [
        '#prefix' => '<div class="views-build-group clear-block">',
        '#suffix' => '</div>',
        '#type' => 'submit',
        '#value' => $this->t('Add another item'),
        '#submit' => [
            [
                $this,
                'addGroupForm',
            ],
        ],
    ];
    $js = [];
    $js['tableDrag']['views-filter-groups']['weight'][0] = [
        'target' => 'weight',
        'source' => NULL,
        'relationship' => 'sibling',
        'action' => 'order',
        'hidden' => TRUE,
        'limit' => 0,
    ];
    $js_settings = $form_state->get('js_settings');
    if ($js_settings && is_array($js)) {
        $js_settings = array_merge($js_settings, $js);
    }
    else {
        $js_settings = $js;
    }
    $form_state->set('js_settings', $js_settings);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.