Issue #3396887 by lauriii, tim.plunkett: Once is reset for ajax dialog buttons when dialog is opened
parent
57a191160c
commit
9766f13fb8
|
@ -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();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue