class ExposedGroups in Views exposed groups 3.0.x
Provides an views exposed form plugin that groups filters.
Plugin annotation
@ViewsExposedForm(
id = "views_exposed_groups",
title = @Translation("Grouped filters"),
help = @Translation("Groups fields into fieldgroups or vertical tabs."),
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
- class \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase implements CacheableDependencyInterface, ExposedFormPluginInterface
- class \Drupal\views_exposed_groups\Plugin\views\exposed_form\ExposedGroups
- class \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase implements CacheableDependencyInterface, ExposedFormPluginInterface
- class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of ExposedGroups
File
- src/
Plugin/ views/ exposed_form/ ExposedGroups.php, line 20
Namespace
Drupal\views_exposed_groups\Plugin\views\exposed_formView source
class ExposedGroups extends ExposedFormPluginBase {
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['exposed_groups'] = [
'default' => [
[
'name' => '_none',
'label' => 'Not grouped',
'weight' => 0,
'filters' => [],
],
],
];
$options['exposed_groups_format'] = [
'default' => 'vertical_tabs',
];
$options['exposed_groups_vertical_tabs_summary'] = [
'default' => 0,
];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['exposed_groups'] = [
'#tree' => FALSE,
'#attributes' => [
'id' => 'views-exposed-groups-settings-wrapper',
],
];
$form['exposed_groups']['format'] = [
'#type' => 'select',
'#title' => $this
->t('Render groups as'),
'#description' => $this
->t('Choose the way that the grouped filters will be displayed.'),
'#parents' => [
'exposed_form_options',
'exposed_groups_format',
],
'#options' => [
'vertical_tabs' => $this
->t('Vertical tabs'),
'fieldsets_collapsed' => $this
->t('Fieldsets (collapsed)'),
'fieldsets' => $this
->t('Fieldsets (expanded)'),
],
'#default_value' => $this->options['exposed_groups_format'],
];
$form['exposed_groups']['vertical_tabs_summary'] = [
'#type' => 'select',
'#title' => $this
->t('Use vertical tabs summaries'),
'#description' => $this
->t('Enable this option to display a summary of filters on the vertical tab link.'),
'#parents' => [
'exposed_form_options',
'exposed_groups_vertical_tabs_summary',
],
'#options' => [
0 => $this
->t('Do not add summaries'),
1 => $this
->t('Add summaries'),
],
'#default_value' => (int) $this->options['exposed_groups_vertical_tabs_summary'],
'#states' => [
'visible' => [
[
':input[name="exposed_form_options[exposed_groups_format]"]' => [
'value' => 'vertical_tabs',
],
],
],
],
];
// Assembles the groups and filters as a table with tabledrag support.
$headers = [
[
'data' => $this
->t('Filter'),
],
[
'data' => $this
->t('Group'),
],
[
'data' => $this
->t('Weight'),
],
];
$form['exposed_groups']['groups'] = [
'#type' => 'table',
'#header' => $headers,
'#empty' => $this
->t('This view does not have any filters.'),
'#attributes' => [
'id' => 'views-exposed-groups-table',
],
'#tabledrag' => [],
'#parents' => [
'exposed_form_options',
'groups',
],
];
$allFilters = $this->displayHandler
->getHandlers('filter');
$filters = array_filter($allFilters, function (ViewsHandlerInterface $filter) {
// @todo Refactor to use PHP 7.4 arrow functions when Drupal requires 7.4.
return $filter
->isExposed();
});
$weight_delta = round(count($filters) / 2);
$groups = $this->options['exposed_groups'];
foreach ($groups as $group) {
$group_name_class_replace = Xss::filter(str_replace('_', '-', $group['name']));
$form['exposed_groups']['groups']['#tabledrag'][] = [
'action' => 'match',
'relationship' => 'sibling',
'group' => 'filter-group-select',
'subgroup' => 'filter-group-' . $group_name_class_replace,
'hidden' => TRUE,
'limit' => FALSE,
];
$form['exposed_groups']['groups']['#tabledrag'][] = [
'action' => 'order',
'relationship' => 'sibling',
'group' => 'filter-weight',
'subgroup' => 'filter-weight-' . $group_name_class_replace,
];
$form['exposed_groups']['groups'][$group['name']] = [
'#attributes' => [
'colspan' => 4,
'class' => [
'tabledrag-root',
],
'no_striping' => TRUE,
],
];
if ($group['name'] === '_none') {
$form['exposed_groups']['groups']['_none']['title'] = [
'#plain_text' => $this
->t('Not grouped'),
];
$form['exposed_groups']['groups'][$group['name']]['#weight'] = 999;
}
else {
$form['exposed_groups']['groups'][$group['name']]['title'] = [
'#prefix' => Xss::filter($group['label']),
'#type' => 'button',
'#value' => $this
->t('Remove group'),
];
}
}
$default_group = array_reduce($groups, function (&$result, $group) {
if ($result !== NULL && $group['name'] === '_none') {
return $group;
}
return $result;
}, NULL);
$group_options = [];
foreach ($groups as $index => $group) {
$group_options[$group['name']] = $group['label'] !== NULL ? Xss::filter($group['label']) : $this
->t('Not grouped');
}
/* @var \Drupal\views\Plugin\views\filter\FilterPluginBase $filter */
foreach ($filters as $filter_name => $filter) {
$id = $filter->options['expose']['identifier'];
// Filter is not escaped until t() or Xss::filter() is called.
$label = $filter->options['expose']['label'];
$group = $default_group;
foreach ($groups as $gindex => $g) {
foreach ($g['filters'] as $f) {
if ($f['id'] === $id) {
$group = $g;
}
}
}
$group_name = $group['name'];
$group_name_class = Xss::filter(str_replace('_', '-', $group_name));
$grouped_filter = NULL;
if ($group['filters'] !== NULL) {
$grouped_filter = array_reduce($group['filters'], function (&$result, array $f) use ($id) {
if ($result !== NULL && $f['id'] === $id) {
return $f;
}
return $result;
}, NULL);
}
$grouped_filter = $grouped_filter !== NULL ? $grouped_filter : [
'id' => $id,
'weight' => 0,
];
$weight = $grouped_filter['weight'];
$form['exposed_groups']['groups']['filter-' . $id] = [
'#attributes' => [
'class' => [
'draggable',
'tabledrag-leaf',
],
],
'#tree' => TRUE,
'#parents' => [
'exposed_form_options',
'filters',
$id,
],
'filter' => [
'id' => [
'#type' => 'value',
'#value' => $id,
],
'title' => [
'#plain_text' => $label,
],
],
'group' => [
'#type' => 'select',
'#title' => $this
->t('Group'),
'#title_display' => 'invisible',
'#attributes' => [
'class' => [
'filter-group-select',
'filter-group-' . $group_name_class,
],
],
'#options' => $group_options,
],
'weight' => [
'#type' => 'weight',
'#title' => $this
->t('Weight for @label', [
'@label' => $label,
]),
'#title_display' => 'invisible',
'#delta' => $weight_delta,
'#filter_field' => $filter,
'#default_value' => $weight,
'#attributes' => [
'class' => [
'filter-weight',
'filter-weight-' . $group_name_class,
],
],
],
];
}
// Add another group button.
$groups_value = '';
foreach ($this->options['exposed_groups'] as $group_weight => $group) {
$groups_value .= ($group['name'] !== '_none' ? $group['label'] : '_none') . "\n";
}
$groups_value = trim($groups_value);
$form['exposed_groups']['manage_groups'] = [
'#tree' => TRUE,
'groups' => [
'#type' => 'textarea',
'#title' => $this
->t('Groups'),
'#rows' => 5,
'#columns' => 40,
'#default_value' => Html::escape($groups_value),
'#element_validate' => [
[
$this,
'updateGroupsValidate',
],
],
],
];
}
/**
* Validate the groups text area.
*
* @param array &$element
* The form element array.
* @param \Drupal\Core\Form\FormStateInterface $formState
* The form state.
*/
public function updateGroupsValidate(array &$element, FormStateInterface $formState) {
$groups_value = $formState
->getValue([
'manage_groups',
'groups',
]);
$groups = explode("\n", $groups_value);
$groups = array_map('trim', $groups);
if (!in_array('_none', $groups)) {
$formState
->setError($element, $this
->t('The "_none" group is required.'));
}
foreach ($groups as $group_label) {
$groups_with_label = array_filter($groups, function ($group) use ($group_label) {
return $group === $group_label;
});
if (count($groups_with_label) > 1) {
$formState
->setError($element, $this
->t('Duplicate group "@name" found.', [
'@name' => $group_label,
]));
}
}
}
/**
* {@inheritdoc}
*/
public function submitOptionsForm(&$form, FormStateInterface $form_state) {
$parents = [
'manage_groups',
'groups',
];
$groups_value = $form_state
->getValue($parents);
$new_groups = explode("\n", $groups_value);
$new_groups = array_map(function ($group_weight, $group_label) {
$label = trim($group_label);
return [
'name' => strtolower(preg_replace('/[^a-zA-Z0-9_]/', '_', $label)),
'label' => $label,
'weight' => $group_weight,
'filters' => [],
];
}, array_keys($new_groups), $new_groups);
$group_names = array_reduce($new_groups, function (&$result, $group) {
$result[] = $group['name'];
return $result;
}, []);
$filters = $form_state
->getValue([
'exposed_form_options',
'filters',
]);
$none_index = array_search('_none', $group_names);
foreach ($filters as $id => $filter) {
$index = array_search($filter['group'], $group_names);
if ($index === FALSE) {
// The filter is not in any of the new groups so it needs to be moved to
// the _none group.
$index = $none_index;
}
$new_groups[$index]['filters'][] = [
'id' => $id,
'weight' => $filter['weight'],
];
}
$this->options['exposed_groups'] = $new_groups;
$form_state
->setValue([
'exposed_form_options',
'exposed_groups',
], $new_groups);
parent::submitOptionsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function exposedFormAlter(&$form, FormStateInterface $form_state) {
parent::exposedFormAlter($form, $form_state);
if (!isset($form['#attributes']['class'])) {
$form['#attributes']['class'] = [];
}
$form['#attributes']['class'][] = 'views-exposed-form--views-exposed-group';
if ($this->options['submit_button']) {
$form['submit']['#value'] = $this->options['submit_button'];
}
if ($this->options['exposed_groups_format'] === 'vertical_tabs') {
$form['filters'] = [
'#type' => 'vertical_tabs',
'#weight' => -10,
'#attached' => [
'library' => [
'views_exposed_groups/views_exposed_groups',
],
'drupalSettings' => [
'viewsExposedGroups' => [
'id' => $form['#id'],
'options' => $this->options,
],
],
],
];
}
else {
$form['filters'] = [
'#weight' => -10,
];
}
$groups = $this->options['exposed_groups'];
foreach ($groups as $index => $group) {
// Sets up each group.
if ($group['name'] !== '_none') {
$form['filters'][$group['name']] = [
'#type' => 'fieldset',
'#title' => Xss::filter($group['label']),
'#collapsible' => TRUE,
'#collapsed' => $this->options['exposed_groups_format'] === 'fieldsets_collapsed',
'#weight' => $group['weight'],
];
}
else {
$form['filters'][$group['name']] = [
'#weight' => $group['weight'],
];
}
$element =& $form['filters'][$group['name']];
foreach ($group['filters'] as $id => $filter_info) {
// Adds each filter into the group.
if (isset($form[$id]) && is_array($form[$id])) {
// Copies the exposed filter form element.
$element[$id] = $form[$id] + [
'#weight' => $filter_info['#weight'],
];
if (isset($form[$id . '_op']) && is_array($form[$id . '_op'])) {
// @todo Copies the exposed operator form element.
unset($form[$id . '_op']);
}
unset($form[$id]);
}
}
}
if (!empty($this->options['reset_button'])) {
$form['reset'] = [
'#value' => $this->options['reset_button_label'],
'#type' => 'submit',
];
}
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
ExposedFormPluginBase:: |
protected | property |
Denotes whether the plugin has an additional options form. Overrides PluginBase:: |
|
ExposedFormPluginBase:: |
public | function |
Submits the exposed form. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function |
Validates the exposed form submission. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function |
The cache contexts associated with this object. Overrides CacheableDependencyInterface:: |
|
ExposedFormPluginBase:: |
public | function |
The maximum age for which this object may be cached. Overrides CacheableDependencyInterface:: |
|
ExposedFormPluginBase:: |
public | function |
The cache tags associated with this object. Overrides CacheableDependencyInterface:: |
|
ExposedFormPluginBase:: |
public | function |
Runs after the view has been executed. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function |
Runs after the view has been rendered. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function |
Runs before the view has been executed. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function |
Runs before the view is rendered. Overrides ExposedFormPluginInterface:: |
1 |
ExposedFormPluginBase:: |
public | function |
Add anything to the query that we might need to. Overrides PluginBase:: |
1 |
ExposedFormPluginBase:: |
public | function |
Renders the exposed form. Overrides ExposedFormPluginInterface:: |
|
ExposedFormPluginBase:: |
public | function | Resets all the states of the exposed form. | |
ExposedGroups:: |
public | function |
Provide a form to edit options for this plugin. Overrides ExposedFormPluginBase:: |
|
ExposedGroups:: |
protected | function |
Information about options for all kinds of purposes will be held here. Overrides ExposedFormPluginBase:: |
|
ExposedGroups:: |
public | function |
Alters the exposed form. Overrides ExposedFormPluginBase:: |
|
ExposedGroups:: |
public | function |
Handle any special handling on the validate form. Overrides PluginBase:: |
|
ExposedGroups:: |
public | function | Validate the groups text area. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
public | property | Plugins's definition. | |
PluginBase:: |
public | property | The display object this plugin is for. | |
PluginBase:: |
public | property | Options for this plugin will be held here. | |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
protected | property | Stores the render API renderer. | 3 |
PluginBase:: |
public | property | The top object of a view. | 1 |
PluginBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: |
14 |
PluginBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
63 |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Clears a plugin. Overrides ViewsPluginInterface:: |
2 |
PluginBase:: |
protected | function | Do the work to filter out stored options depending on the defined options. | |
PluginBase:: |
public | function |
Filter out stored options depending on the defined options. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns an array of available token replacements. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
2 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function |
Returns the plugin provider. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
protected | function | Returns the render API renderer. | 1 |
PluginBase:: |
public | function |
Adds elements for available core tokens to a form. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns a string with any core tokens replaced. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
constant | Include entity row languages when listing languages. | ||
PluginBase:: |
constant | Include negotiated languages when listing languages. | ||
PluginBase:: |
public | function |
Initialize the plugin. Overrides ViewsPluginInterface:: |
6 |
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginBase:: |
protected | function | Makes an array of languages, optionally including special languages. | |
PluginBase:: |
public | function |
Return the human readable name of the display. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function |
Moves form elements into fieldsets for presentation purposes. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function |
Flattens the structure of form elements. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public static | function | Returns substitutions for Views queries for languages. | |
PluginBase:: |
protected | function | Fills up the options of the plugin with defaults. | |
PluginBase:: |
public | function |
Returns the summary of the settings in the display. Overrides ViewsPluginInterface:: |
6 |
PluginBase:: |
public | function |
Provide a full list of possible theme templates used by this style. Overrides ViewsPluginInterface:: |
1 |
PluginBase:: |
public static | function |
Lists the trusted callbacks provided by the implementing class. Overrides TrustedCallbackInterface:: |
6 |
PluginBase:: |
public | function |
Unpack options over our existing defaults, drilling down into arrays
so that defaults don't get totally blown away. Overrides ViewsPluginInterface:: |
|
PluginBase:: |
public | function |
Returns the usesOptions property. Overrides ViewsPluginInterface:: |
8 |
PluginBase:: |
public | function |
Validate that the plugin is correct and can be saved. Overrides ViewsPluginInterface:: |
6 |
PluginBase:: |
public | function |
Validate the options form. Overrides ViewsPluginInterface:: |
15 |
PluginBase:: |
protected | function | Replaces Views' tokens in a given string. The resulting string will be sanitized with Xss::filterAdmin. | 1 |
PluginBase:: |
constant | Query string to indicate the site default language. | ||
PluginBase:: |
public | function |
Constructs a PluginBase object. Overrides PluginBase:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TrustedCallbackInterface:: |
constant | Untrusted callbacks throw exceptions. | ||
TrustedCallbackInterface:: |
constant | Untrusted callbacks trigger silenced E_USER_DEPRECATION errors. | ||
TrustedCallbackInterface:: |
constant | Untrusted callbacks trigger E_USER_WARNING errors. |