Issue #3398974 by alexpott, Wim Leers, borisson_: Follow-up for #3382510: FormStateInterface::setErrorByName() needs not #name but a variation
parent
13883cc380
commit
97e6267a62
|
@ -137,7 +137,6 @@ abstract class ConfigFormBase extends FormBase {
|
|||
if (is_string($target)) {
|
||||
$target = ConfigTarget::fromString($target);
|
||||
}
|
||||
$target->elementName = $element['#name'];
|
||||
$target->elementParents = $element['#parents'];
|
||||
$map[$target->configName . ':' . $target->propertyPath] = $target;
|
||||
$form_state->set(static::CONFIG_KEY_TO_FORM_ELEMENT_MAP, $map);
|
||||
|
@ -192,7 +191,20 @@ abstract class ConfigFormBase extends FormBase {
|
|||
// will not have the sequence index in it.
|
||||
$property_path = rtrim($property_path, '0123456789.');
|
||||
}
|
||||
$form_element_name = $map["$config_name:$property_path"]->elementName;
|
||||
|
||||
if ($property_path === '') {
|
||||
// There is a map to a non-existing config key. Try to work backwards.
|
||||
$property_path = $violation->getParameters()['@key'] ?? '';
|
||||
}
|
||||
|
||||
if (isset($map["$config_name:$property_path"])) {
|
||||
$form_element_name = implode('][', $map["$config_name:$property_path"]->elementParents);
|
||||
}
|
||||
else {
|
||||
// We cannot determine where to place the violation. The only option
|
||||
// is the entire form.
|
||||
$form_element_name = '';
|
||||
}
|
||||
$violations_per_form_element[$form_element_name][$index] = $violation;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,18 +9,6 @@ namespace Drupal\Core\Form;
|
|||
*/
|
||||
final class ConfigTarget {
|
||||
|
||||
/**
|
||||
* The name of the form element which maps to this config property.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @see \Drupal\Core\Form\ConfigFormBase::storeConfigKeyToFormElementMap()
|
||||
*
|
||||
* @internal
|
||||
* This property is for internal use only.
|
||||
*/
|
||||
public string $elementName;
|
||||
|
||||
/**
|
||||
* The parents of the form element which maps to this config property.
|
||||
*
|
||||
|
|
|
@ -5,3 +5,9 @@ form_test.object:
|
|||
bananas:
|
||||
type: string
|
||||
label: 'Bananas'
|
||||
favorite_vegetable:
|
||||
type: required_label
|
||||
label: 'Favorite vegetable'
|
||||
nemesis_vegetable:
|
||||
type: required_label
|
||||
label: 'Nemesis vegetable'
|
||||
|
|
|
@ -528,3 +528,17 @@ form_test.javascript_states_form:
|
|||
_form: '\Drupal\form_test\Form\JavascriptStatesForm'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
form_test.tree_config_target:
|
||||
path: '/form-test/tree-config-target'
|
||||
defaults:
|
||||
_form: '\Drupal\form_test\Form\TreeConfigTargetForm'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
form_test.incorrect_config_target:
|
||||
path: '/form-test/incorrect-config-target'
|
||||
defaults:
|
||||
_form: '\Drupal\form_test\Form\IncorrectConfigTargetForm'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\form_test\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
class IncorrectConfigTargetForm extends ConfigFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEditableConfigNames() {
|
||||
return ['form_test.object'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'form_test_incorrect_config_target_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['missing_key'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Missing key'),
|
||||
'#config_target' => 'form_test.object:does_not_exist',
|
||||
];
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\form_test\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
class TreeConfigTargetForm extends ConfigFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEditableConfigNames() {
|
||||
return ['form_test.object'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'form_test_tree_config_target_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['vegetables'] = [
|
||||
'#type' => 'details',
|
||||
'#tree' => TRUE,
|
||||
'#input' => TRUE,
|
||||
'#title' => t('Vegetable preferences'),
|
||||
];
|
||||
$form['vegetables']['favorite'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Favorite'),
|
||||
'#default_value' => 'Potato',
|
||||
'#config_target' => 'form_test.object:favorite_vegetable',
|
||||
];
|
||||
$form['vegetables']['nemesis'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Nemesis'),
|
||||
'#default_value' => 'Broccoli',
|
||||
'#config_target' => 'form_test.object:nemesis_vegetable',
|
||||
];
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\system\Functional\Form;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests forms using #config_target.
|
||||
*
|
||||
* @group Form
|
||||
*/
|
||||
class ConfigTargetTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['form_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* Tests #config_target where #tree is set to TRUE.
|
||||
*/
|
||||
public function testTree(): void {
|
||||
$this->drupalGet('/form-test/tree-config-target');
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->fillField('Favorite', '');
|
||||
$page->pressButton('Save configuration');
|
||||
$assert_session = $this->assertSession();
|
||||
$assert_session->statusMessageContains('This value should not be blank.', 'error');
|
||||
$assert_session->elementAttributeExists('named', ['field', 'Favorite'], 'aria-invalid');
|
||||
$assert_session->elementAttributeNotExists('named', ['field', 'Nemesis'], 'aria-invalid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests #config_target with an incorrect key.
|
||||
*/
|
||||
public function testIncorrectKey(): void {
|
||||
$this->drupalGet('/form-test/incorrect-config-target');
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->pressButton('Save configuration');
|
||||
$assert_session = $this->assertSession();
|
||||
$assert_session->statusMessageContains('\'does_not_exist\' is not a supported key.', 'error');
|
||||
$assert_session->elementAttributeExists('named', ['field', 'Missing key'], 'aria-invalid');
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue