I changed the assigned string in the progress bar id attribute to the escaped strings.
And, I checked the work using javascript similar to the steps to reproduce, no dialog appeared.
The test fails, but it doesn't seem to be related to the changes.
https://git.drupalcode.org/issue/drupal-3426514/-/jobs/1233839#L778
Please review it.
magaki β made their first commit to this issueβs fork.
The cause seems that the triggered element refers to a different than the actually pressed element.
A #submit
callbacks will be set to $form_state
in the FormBuilder::doBuildForm()
, line:1111-1113.
if (isset($triggering_element['#submit'])) {
$form_state->setSubmitHandlers($triggering_element['#submit']);
}
This $triggering_element
is the value got from $form_state->getTriggeringElement();
, and the triggered element will be set for form_state
in the FormBuilder::handleInputElement()
, line:1300-1305.
$buttons = $form_state->getButtons();
$buttons[] = $element;
$form_state->setButtons($buttons);
if ($this->buttonWasClicked($element, $form_state)) {
$form_state->setTriggeringElement($element);
}
A triggered buttons is determined using the FormBuilder::buttonWasClicked()
.
The function determines whether the element's #value
value exists in the input
of $form_state
.
However, if a button that is translated by the browser is pressed, input
has the translated value, so buttonWasClicked
returns FALSE
.
protected function buttonWasClicked($element, FormStateInterface &$form_state) {
// First detect normal 'vanilla' button clicks. Traditionally, all standard
// buttons on a form share the same name (usually 'op'), and the specific
// return value is used to determine which was clicked. This ONLY works as
// long as $form['#name'] puts the value at the top level of the tree of
// \Drupal::request()->request data.
$input = $form_state->getUserInput();
// The input value attribute is treated as CDATA by browsers. This means
// that they replace character entities with characters. Therefore, we need
// to decode the value in $element['#value']. For more details see
// http://www.w3.org/TR/html401/types.html#type-cdata.
if (isset($input[$element['#name']]) && $input[$element['#name']] == Html::decodeEntities($element['#value'])) {
return TRUE;
}
// When image buttons are clicked, browsers do NOT pass the form element
// value in \Drupal::request()->Request. Instead they pass an integer
// representing the coordinates of the click on the button image. This means
// that image buttons MUST have unique $form['#name'] values, but the
// details of their \Drupal::request()->request data should be ignored.
elseif (!empty($element['#has_garbage_value']) && isset($element['#value']) && $element['#value'] !== '') {
return TRUE;
}
return FALSE;
}
If the button was not found in the above process, the first button among the elements registered as buttons will be set as the triggered element in the FormBuilder::doBuildForm()
.
$buttons = $form_state->getButtons();
if (!$form_state->isProgrammed() && !$form_state->getTriggeringElement() && !empty($buttons)) {
$form_state->setTriggeringElement($buttons[0]);
}
As a result, when a translated button is pressed,
- if there are one or more buttons, it will refer to the first button and set in $form_state
, and the #submit
will be executed.
- if there is no button, nothing happens.
As a solution, since #element[#value]
will be rewritten by the browser, it may be possible to solve the problem by defining any identifiable values and using them to determine the triggered element.
I checked the work using the following Form class.
Normally, pressing buttons 1, 2, and 3 each show a different message.
However, pressing buttons 2, and 3 will show the message for button 1 when the element has been translated by the browser.
<?php
namespace Drupal\sandbox\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class SandboxForm extends FormBase {
public function getFormId(): string {
return 'sandbox_form';
}
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['button1'] = [
'#type' => 'submit',
'#value' => 'This is button 1',
'#submit' => [
'::callback1',
],
];
$form['button2'] = [
'#type' => 'submit',
'#value' => 'This is button 2',
'#submit' => [
'::callback2',
],
];
$form['button3'] = [
'#type' => 'submit',
'#value' => 'This is button 3',
'#submit' => [
'::callback3',
],
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state): array {
return $form;
}
public function callback1(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button1 was pressed (callback1)');
}
public function callback2(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button2 was pressed (callback2)');
}
public function callback3(array $form, FormStateInterface $form_state): void {
\Drupal::service('messenger')->addStatus('Button3 was pressed (callback3)');
}
}
- Added documentation about the deprecation of the Locale
class.
- Removed unnecessary periods.
- About using $localConfigManager
as a temporary variable of Locale::config()
- Removed $localConfigManager
if it was only used once.
- Renamed to $locale_config_manager
if it was used more than once.
Please review it
Thank you for confirming my account.
I could create a new change records.
https://www.drupal.org/node/3437110 β
I made a mistake in rebase once, so I force pushed the pre-rebase, updated the 11.x branch of the repository to the latest, and rebased the branch to on top of that.
I modified the deprecated version to 10.3 and removal version to 11.0.
I could not create change records because I have no permissions.
I modified the documentation according to Drupal deprecation policy and added its test.
Please review it.
The test fails, but it doesn't seem to be related to the changes.
https://git.drupalcode.org/issue/drupal-3422915/-/pipelines/133015/test_...β‘%EF%B8%8F%20PHPUnit%20Unit
magaki β made their first commit to this issueβs fork.