Commit 8210ebe0 authored by catch's avatar catch

Issue #2687773 by mikeker, sukanya.ramakrishnan, dawehner, amateescu,...

Issue #2687773 by mikeker, sukanya.ramakrishnan, dawehner, amateescu, mroycroft, Lukas von Blarer, Lendude: Using checkboxes with an is
parent 4f24c916
...@@ -129,6 +129,9 @@ protected function opHelper() { ...@@ -129,6 +129,9 @@ protected function opHelper() {
if (empty($this->value)) { if (empty($this->value)) {
return; return;
} }
// Form API returns unchecked options in the form of option_id => 0. This
// breaks the generated query for "is all of" filters so we remove them.
$this->value = array_filter($this->value, 'static::arrayFilterZero');
$this->helper->addFilter(); $this->helper->addFilter();
} }
......
langcode: en
status: true
dependencies:
config:
- taxonomy.vocabulary.test_exposed_checkboxes
module:
- node
- taxonomy
id: test_exposed_form_checkboxes
label: ''
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_options:
access:
type: none
cache:
type: tag
exposed_form:
options:
reset_button: true
type: basic
filters:
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
operator: in
value: { }
group: 1
exposed: true
expose:
operator_id: type_op
label: 'Content: Type'
description: 'Exposed description'
use_operator: false
operator: ''
identifier: type
required: false
remember: false
multiple: true
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
plugin_id: in_operator
entity_type: node
entity_field: type
tid:
id: tid
table: taxonomy_index
field: tid
relationship: none
group_type: group
admin_label: ''
operator: and
value: { }
group: 1
exposed: true
expose:
operator_id: tid_op
label: 'Has taxonomy term'
description: ''
use_operator: false
operator: tid_op
identifier: tid
required: false
remember: false
multiple: true
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: false
type: select
limit: true
vid: test_exposed_checkboxes
hierarchy: false
error_message: true
plugin_id: taxonomy_index_tid
pager:
type: full
query:
options:
query_comment: ''
type: views_query
style:
type: default
row:
type: 'entity:node'
display_extenders: { }
display_plugin: default
display_title: Master
id: default
position: 0
cache_metadata:
max-age: -1
contexts:
- 'languages:language_interface'
- url
- url.query_args
- user
- 'user.node_grants:view'
tags: { }
page_1:
display_options:
path: test_exposed_form_checkboxes
display_extenders: { }
display_plugin: page
display_title: Page
id: page_1
position: 0
cache_metadata:
max-age: -1
contexts:
- 'languages:language_interface'
- url
- url.query_args
- user
- 'user.node_grants:view'
tags: { }
<?php
namespace Drupal\Tests\views\Functional\Plugin;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
/**
* Tests exposed forms functionality.
*
* @group views
*/
class ExposedFormCheckboxesTest extends ViewTestBase {
use EntityReferenceTestTrait;
/**
* {@inheritdoc}
*/
public static $testViews = ['test_exposed_form_checkboxes'];
/**
* {@inheritdoc}
*/
public static $modules = ['node', 'views_ui', 'taxonomy'];
/**
* Test terms.
*
* @var array
*/
public $terms = [];
/**
* Vocabulary for testing checkbox options.
*
* @var \Drupal\taxonomy\Entity\Vocabulary
*/
public $vocabulary;
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp(FALSE);
// Create a vocabulary and entity reference field so we can test the "is all
// of" filter operator. Must be done ahead of the view import so the
// vocabulary is in place to meet the view dependencies.
$vocabulary = Vocabulary::create([
'name' => 'test_exposed_checkboxes',
'vid' => 'test_exposed_checkboxes',
'nodes' => ['article' => 'article'],
]);
$vocabulary->save();
$this->vocabulary = $vocabulary;
ViewTestData::createTestViews(self::class, ['views_test_config']);
$this->enableViewsTestModule();
// Create two content types.
$this->drupalCreateContentType(['type' => 'article']);
$this->drupalCreateContentType(['type' => 'page']);
// Create some random nodes: 5 articles, one page.
for ($i = 0; $i < 5; $i++) {
$this->drupalCreateNode(['type' => 'article']);
}
$this->drupalCreateNode(['type' => 'page']);
}
/**
* Tests overriding the default render option with checkboxes.
*/
public function testExposedFormRenderCheckboxes() {
// Use a test theme to convert multi-select elements into checkboxes.
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
$this->config('system.theme')
->set('default', 'views_test_checkboxes_theme')
->save();
// Only display 5 items per page so we can test that paging works.
$view = Views::getView('test_exposed_form_checkboxes');
$display = &$view->storage->getDisplay('default');
$display['display_options']['pager']['options']['items_per_page'] = 5;
$view->save();
$this->drupalGet('test_exposed_form_checkboxes');
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]');
$this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.');
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]');
$this->assertEqual(count($actual), 1, 'Page option renders as a checkbox');
// Ensure that all results are displayed.
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.');
$this->clickLink('Page 2');
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.');
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
}
/**
* Tests that "is all of" filters work with checkboxes.
*/
public function testExposedIsAllOfFilter() {
foreach (['Term 1', 'Term 2', 'Term 3'] as $term_name) {
// Add a few terms to the new vocabulary.
$term = Term::create([
'name' => $term_name,
'vid' => $this->vocabulary->id(),
]);
$term->save();
$this->terms[] = $term;
}
// Create a field.
$field_name = Unicode::strtolower($this->randomMachineName());
$handler_settings = [
'target_bundles' => [
$this->vocabulary->id() => $this->vocabulary->id(),
],
'auto_create' => FALSE,
];
$this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
// Add some test nodes.
$this->createNode([
'type' => 'article',
$field_name => [$this->terms[0]->id(), $this->terms[1]->id()],
]);
$this->createNode([
'type' => 'article',
$field_name => [$this->terms[0]->id(), $this->terms[2]->id()],
]);
// Use a test theme to convert multi-select elements into checkboxes.
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
$this->config('system.theme')
->set('default', 'views_test_checkboxes_theme')
->save();
$this->drupalGet('test_exposed_form_checkboxes');
// Ensure that all results are displayed.
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 8, 'All rows are displayed by default on the first page when no options are checked.');
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
// Select one option and ensure we still have results.
$tid = $this->terms[0]->id();
$this->drupalPostForm(NULL, ["tid[$tid]" => $tid], t('Apply'));
// Ensure only nodes tagged with $tid are displayed.
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 2, 'Correct rows are displayed when a tid is selected.');
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
}
}
...@@ -191,48 +191,6 @@ public function testResetButton() { ...@@ -191,48 +191,6 @@ public function testResetButton() {
$this->helperButtonHasLabel('edit-reset', $expected_label); $this->helperButtonHasLabel('edit-reset', $expected_label);
} }
/**
* Tests overriding the default render option with checkboxes.
*/
public function testExposedFormRenderCheckboxes() {
// Make sure we have at least two options for node type.
$this->drupalCreateContentType(['type' => 'page']);
$this->drupalCreateNode(['type' => 'page']);
// Use a test theme to convert multi-select elements into checkboxes.
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
$this->config('system.theme')
->set('default', 'views_test_checkboxes_theme')
->save();
// Set the "type" filter to multi-select.
$view = Views::getView('test_exposed_form_buttons');
$filter = $view->getHandler('page_1', 'filter', 'type');
$filter['expose']['multiple'] = TRUE;
$view->setHandler('page_1', 'filter', 'type', $filter);
// Only display 5 items per page so we can test that paging works.
$display = &$view->storage->getDisplay('default');
$display['display_options']['pager']['options']['items_per_page'] = 5;
$view->save();
$this->drupalGet('test_exposed_form_buttons');
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]');
$this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.');
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]');
$this->assertEqual(count($actual), 1, 'Page option renders as a checkbox');
// Ensure that all results are displayed.
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.');
$this->clickLink('Page 2');
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
$this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.');
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
}
/** /**
* Tests the exposed block functionality. * Tests the exposed block functionality.
*/ */
......
...@@ -11,5 +11,10 @@ ...@@ -11,5 +11,10 @@
* Changes an exposed "type" filter from a multi-select to checkboxes. * Changes an exposed "type" filter from a multi-select to checkboxes.
*/ */
function views_test_checkboxes_theme_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) { function views_test_checkboxes_theme_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) {
$form['type']['#type'] = 'checkboxes'; if (isset($form['type'])) {
$form['type']['#type'] = 'checkboxes';
}
if (isset($form['tid'])) {
$form['tid']['#type'] = 'checkboxes';
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment