Issue #3396887 by lauriii, tim.plunkett: Once is reset for ajax dialog buttons when dialog is opened

merge-requests/5009/merge
nod_ 2023-10-27 23:54:48 +02:00
parent 57a191160c
commit 9766f13fb8
No known key found for this signature in database
GPG Key ID: 76624892606FA197
3 changed files with 45 additions and 18 deletions

View File

@ -94,6 +94,7 @@
buttons.push({
text: $originalButton.html() || $originalButton.attr('value'),
class: $originalButton.attr('class'),
'data-once': $originalButton.data('once'),
click(e) {
// If the original button is an anchor tag, triggering the "click"
// event will not simulate a click. Use the click method instead.
@ -104,8 +105,8 @@
.trigger('mousedown')
.trigger('mouseup')
.trigger('click');
e.preventDefault();
}
e.preventDefault();
},
});
});

View File

@ -2,6 +2,8 @@
namespace Drupal\ajax_test\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\MessageCommand;
use Drupal\Core\Url;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
@ -39,26 +41,44 @@ class AjaxTestForm extends FormBase {
'#value' => $this->t('Do it'),
];
$form['actions']['preview'] = [
'#title' => 'Preview',
'#type' => 'link',
'#url' => Url::fromRoute('ajax_test.dialog_form'),
'#attributes' => [
'class' => ['use-ajax', 'button'],
'data-dialog-type' => 'modal',
],
];
$form['actions']['hello_world'] = [
'#type' => 'submit',
'#value' => $this->t('Preview'),
'#value' => $this->t('Hello world'),
// No regular submit-handler. This form only works via JavaScript.
'#submit' => [],
'#ajax' => [
// This means the ::preview() method on this class would be invoked in
// case of a click event. However, since Drupal core's test runner only
// is able to execute PHP, not JS, there is no point in actually
// implementing this method, because we can never let it be called from
// JS; we'd have to manually call it from PHP, at which point we would
// not actually be testing it.
// Therefore we consciously choose to not implement this method, because
// we cannot meaningfully test it anyway.
'callback' => '::preview',
'callback' => '::helloWorld',
'event' => 'click',
],
];
return $form;
}
/**
* An AJAX callback that prints "Hello World!" as a message.
*
* @param array $form
* The form array to remove elements from.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response.
*/
public function helloWorld(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$response->addCommand(new MessageCommand('Hello world!'));
return $response;
}
/**
* {@inheritdoc}
*/

View File

@ -145,26 +145,32 @@ class DialogTest extends WebDriverTestBase {
$preview = $form_dialog->findButton('Preview');
$this->assertNotNull($preview, 'The dialog contains a "Preview" button.');
// When a form with submit inputs is in a dialog, the form's submit inputs
// are copied to the dialog buttonpane as buttons. The originals should have
// their styles set to display: none.
$hidden_buttons = $this->getSession()->getPage()->findAll('css', '.ajax-test-form [type="submit"]');
$this->assertCount(2, $hidden_buttons);
// Form submit inputs, link buttons, and buttons in dialog are copied to the
// dialog buttonpane as buttons. The originals should have their styles set
// to display: none.
$hidden_buttons = $this->getSession()->getPage()->findAll('css', '.ajax-test-form .button');
$this->assertCount(3, $hidden_buttons);
$hidden_button_text = [];
foreach ($hidden_buttons as $button) {
$styles = $button->getAttribute('style');
$this->assertStringContainsStringIgnoringCase('display: none;', $styles);
$hidden_button_text[] = $button->getAttribute('value');
$hidden_button_text[] = $button->hasAttribute('value') ? $button->getAttribute('value') : $button->getHtml();
}
// The copied buttons should have the same text as the submit inputs they
// were copied from.
$moved_to_buttonpane_buttons = $this->getSession()->getPage()->findAll('css', '.ui-dialog-buttonpane button');
$this->assertCount(2, $moved_to_buttonpane_buttons);
$this->assertCount(3, $moved_to_buttonpane_buttons);
foreach ($moved_to_buttonpane_buttons as $key => $button) {
$this->assertEquals($hidden_button_text[$key], $button->getText());
}
// Press buttons in the dialog to ensure there are no AJAX errors.
$this->assertSession()->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Hello world');
$this->assertSession()->assertWaitOnAjaxRequest();
$this->assertSession()->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Preview');
$this->assertSession()->assertWaitOnAjaxRequest();
// Reset: close the form.
$form_dialog->findButton('Close')->press();