Commit 40004e3d authored by alexpott's avatar alexpott

Issue #2500523 by tim.plunkett, effulgentsia, dawehner: Rewrite...

Issue #2500523 by tim.plunkett, effulgentsia, dawehner: Rewrite views_ui_add_ajax_trigger() to not rely on /system/ajax
parent 8ec58745
......@@ -496,15 +496,18 @@ public static function getSelected(FormStateInterface $form_state, $parents, $de
}
// If there is a user-submitted value for this element that matches one of
// the currently available options attached to it, use that. We need to check
// FormState::$input rather than $form_state->getValues() here because the
// triggering element often has the #limit_validation_errors property set to
// prevent unwanted errors elsewhere on the form. This means that the
// $form_state->getValues() array won't be complete. We could make it complete
// by adding each required part of the form to the #limit_validation_errors
// property individually as the form is being built, but this is difficult to
// do for a highly dynamic and extensible form. This method is much simpler.
$user_input = &$form_state->getUserInput();
// the currently available options attached to it, use that. However, only
// perform this check during the form rebuild. During the initial build
// after #ajax is triggered, we need to rebuild the form as it was
// initially. We need to check FormState::getUserInput() rather than
// $form_state->getValues() here because the triggering element often has
// the #limit_validation_errors property set to prevent unwanted errors
// elsewhere on the form. This means that the $form_state->getValues() array
// won't be complete. We could make it complete by adding each required part
// of the form to the #limit_validation_errors property individually as the
// form is being built, but this is difficult to do for a highly dynamic and
// extensible form. This method is much simpler.
$user_input = $form_state->isRebuilding() ? $form_state->getUserInput() : [];
if (!empty($user_input)) {
$key_exists = NULL;
$submitted = NestedArray::getValue($user_input, $parents, $key_exists);
......
......@@ -196,7 +196,7 @@ function testTaggedWithByNodeType() {
$this->drupalPostForm('admin/structure/views/add', $view, t('Update "of type" choice'));
$this->assertFieldByXpath($tags_xpath);
$view['show[type]'] = $this->nodeTypeWithoutTags->id();
$this->drupalPostForm(NULL, $view, t('Update "of type" choice'));
$this->drupalPostForm(NULL, $view, t('Update "of type" choice (2)'));
$this->assertNoFieldByXpath($tags_xpath);
// If we add an instance of the tagging field to the second node type, the
......@@ -225,7 +225,7 @@ function testTaggedWithByNodeType() {
$this->drupalPostForm('admin/structure/views/add', $view, t('Update "of type" choice'));
$this->assertFieldByXpath($tags_xpath);
$view['show[type]'] = $this->nodeTypeWithoutTags->id();
$this->drupalPostForm(NULL, $view, t('Update "of type" choice'));
$this->drupalPostForm(NULL, $view, t('Update "of type" choice (2)'));
$this->assertFieldByXpath($tags_xpath);
}
......
<?php
/**
* @file
* Contains \Drupal\Tests\views\Unit\WizardPluginBaseTest.
*/
namespace Drupal\Tests\views\Unit;
use Drupal\Core\Form\FormState;
use Drupal\Tests\UnitTestCase;
use Drupal\views\Plugin\views\wizard\WizardPluginBase;
/**
* @coversDefaultClass \Drupal\views\Plugin\views\wizard\WizardPluginBase
*
* @group views
*/
class WizardPluginBaseTest extends UnitTestCase {
/**
* @covers ::getSelected
*
* @dataProvider providerTestGetSelected
*/
public function testGetSelected($expected, $element = [], $parents = [], $user_input = [], $not_rebuilding_expected = NULL) {
$not_rebuilding_expected = $not_rebuilding_expected ?: $expected;
$form_state = new FormState();
$form_state->setUserInput($user_input);
$actual = WizardPluginBase::getSelected($form_state, $parents, 'the_default_value', $element);
$this->assertSame($not_rebuilding_expected, $actual);
$this->assertSame($user_input, $form_state->getUserInput());
$form_state->setRebuild();
$actual = WizardPluginBase::getSelected($form_state, $parents, 'the_default_value', $element);
$this->assertSame($expected, $actual);
$this->assertSame($user_input, $form_state->getUserInput());
}
/**
* Provides test data for testGetSelected().
*/
public function providerTestGetSelected() {
$data = [];
// A form element with an invalid #type.
$data['invalid_type'] = [
'the_default_value',
[
'#type' => 'checkbox',
],
];
// A form element with no #options.
$data['no_options'] = [
'the_default_value',
[
'#type' => 'select',
],
];
// A valid form element with no user input.
$data['no_user_input'] = [
'the_default_value',
[
'#type' => 'select',
'#options' => [
'option1' => 'Option 1',
],
],
];
// A valid form element with user input that doesn't correspond to it.
$data['mismatched_input'] = [
'the_default_value',
[
'#type' => 'select',
'#options' => [
'option1' => 'Option 1',
],
],
['foo', 'bar'],
['foo' => ['foo' => 'value1']],
];
// A valid form element with a valid dynamic value that matches the default
// value.
$data['matching_default'] = [
'the_default_value',
[
'#type' => 'select',
'#options' => [
'the_default_value' => 'Option 1',
],
],
['foo', 'bar'],
['foo' => ['bar' => 'the_default_value']],
];
// A valid form element with a valid dynamic value that does not match the
// default value.
$data['mismatched_value'] = [
'option1',
[
'#type' => 'select',
'#options' => [
'option1' => 'Option 1',
],
],
['foo', 'bar'],
['foo' => ['bar' => 'option1']],
'the_default_value',
];
return $data;
}
}
......@@ -52,10 +52,6 @@ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_pa
$triggering_element = &$wrapping_element[$trigger_key];
$triggering_element['#ajax']['callback'] = 'views_ui_ajax_update_form';
// Specify the #ajax URL in order to retain form caching.
// @todo Remove this in https://www.drupal.org/node/2500523.
$triggering_element['#ajax']['url'] = Url::fromRoute('system.ajax');
// We do not use \Drupal\Component\Utility\Html::getUniqueId() to get an ID
// for the AJAX wrapper, because it remembers IDs across AJAX requests (and
// won't reuse them), but in our case we need to use the same ID from request
......@@ -117,9 +113,6 @@ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_pa
'wrapper' => $triggering_element['#ajax']['wrapper'],
'trigger_key' => $trigger_key,
'refresh_parents' => $refresh_parents,
// Keep track of duplicate wrappers so we don't add the same wrapper to the
// page more than once.
'duplicate_wrapper' => !empty($seen_ids[$triggering_element['#ajax']['wrapper']]),
);
$seen_ids[$triggering_element['#ajax']['wrapper']] = TRUE;
$triggering_element['#views_ui_ajax_data'] = $ajax_data;
......@@ -166,29 +159,25 @@ function views_ui_add_limited_validation($element, FormStateInterface $form_stat
* submit button form element.
*/
function views_ui_add_ajax_wrapper($element, FormStateInterface $form_state) {
// Don't add the wrapper <div> if the same one was already inserted on this
// form.
if (empty($element['#views_ui_ajax_data']['duplicate_wrapper'])) {
// Find the region of the complete form that needs to be refreshed by AJAX.
// This was earlier stored in a property on the element.
$complete_form = &$form_state->getCompleteForm();
$refresh_parents = $element['#views_ui_ajax_data']['refresh_parents'];
$refresh_element = NestedArray::getValue($complete_form, $refresh_parents);
// Find the region of the complete form that needs to be refreshed by AJAX.
// This was earlier stored in a property on the element.
$complete_form = &$form_state->getCompleteForm();
$refresh_parents = $element['#views_ui_ajax_data']['refresh_parents'];
$refresh_element = NestedArray::getValue($complete_form, $refresh_parents);
// The HTML ID that AJAX expects was also stored in a property on the
// element, so use that information to insert the wrapper <div> here.
$id = $element['#views_ui_ajax_data']['wrapper'];
$refresh_element += array(
'#prefix' => '',
'#suffix' => '',
);
$refresh_element['#prefix'] = '<div id="' . $id . '" class="views-ui-ajax-wrapper">' . $refresh_element['#prefix'];
$refresh_element['#suffix'] .= '</div>';
// The HTML ID that AJAX expects was also stored in a property on the
// element, so use that information to insert the wrapper <div> here.
$id = $element['#views_ui_ajax_data']['wrapper'];
$refresh_element += array(
'#prefix' => '',
'#suffix' => '',
);
$refresh_element['#prefix'] = '<div id="' . $id . '" class="views-ui-ajax-wrapper">' . $refresh_element['#prefix'];
$refresh_element['#suffix'] .= '</div>';
// Copy the element that needs to be refreshed back into the form, with our
// modifications to it.
NestedArray::setValue($complete_form, $refresh_parents, $refresh_element);
}
// Copy the element that needs to be refreshed back into the form, with our
// modifications to it.
NestedArray::setValue($complete_form, $refresh_parents, $refresh_element);
return $element;
}
......
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