Issue #3076054 by godotislate, joaopauloc.dev, smustgrave, nod_, nayana_mvr, larowlan, alexpott, lauriii, quietone, benjifisher, anup.singh, bnjmnm: Existing field items should not be validated when adding another item in widget for unlimited cardinality field
parent
cdf03eab78
commit
716a102849
|
@ -5,6 +5,9 @@ namespace Drupal\Core\Field;
|
|||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\SortArray;
|
||||
use Drupal\Core\Ajax\AjaxResponse;
|
||||
use Drupal\Core\Ajax\FocusFirstCommand;
|
||||
use Drupal\Core\Ajax\InsertCommand;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
@ -280,7 +283,7 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface,
|
|||
'#name' => strtr($id_prefix, '-', '_') . '_add_more',
|
||||
'#value' => t('Add another item'),
|
||||
'#attributes' => ['class' => ['field-add-more-submit']],
|
||||
'#limit_validation_errors' => [array_merge($parents, [$field_name])],
|
||||
'#limit_validation_errors' => [],
|
||||
'#submit' => [[static::class, 'addMoreSubmit']],
|
||||
'#ajax' => [
|
||||
'callback' => [static::class, 'addMoreAjax'],
|
||||
|
@ -349,10 +352,18 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface,
|
|||
|
||||
// Add a DIV around the delta receiving the Ajax effect.
|
||||
$delta = $element['#max_delta'];
|
||||
$element[$delta]['#prefix'] = '<div class="ajax-new-content">' . ($element[$delta]['#prefix'] ?? '');
|
||||
// Construct an attribute to add to div for use as selector to set the focus on.
|
||||
$button_parent = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
|
||||
$focus_attribute = 'data-drupal-selector="field-' . $button_parent['#field_name'] . '-more-focus-target"';
|
||||
$element[$delta]['#prefix'] = '<div class="ajax-new-content" ' . $focus_attribute . '>' . ($element[$delta]['#prefix'] ?? '');
|
||||
$element[$delta]['#suffix'] = ($element[$delta]['#suffix'] ?? '') . '</div>';
|
||||
|
||||
return $element;
|
||||
// Turn render array into response with AJAX commands.
|
||||
$response = new AjaxResponse();
|
||||
$response->addCommand(new InsertCommand(NULL, $element));
|
||||
// Add command to set the focus on first focusable element within the div.
|
||||
$response->addCommand(new FocusFirstCommand("[$focus_attribute]"));
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -169,4 +169,45 @@ class MultipleValueWidgetTest extends WebDriverTestBase {
|
|||
$this->assertSame('', $field_1->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that no validation occurs on field on "Add more" click.
|
||||
*/
|
||||
public function testFieldMultipleValueWidgetAddMoreNoValidation() {
|
||||
// Set unlimited field to be required.
|
||||
$field_name = 'field_unlimited';
|
||||
$field = FieldConfig::loadByName('entity_test', 'entity_test', $field_name);
|
||||
$field->setRequired(TRUE);
|
||||
$field->save();
|
||||
|
||||
$this->drupalGet('entity_test/add');
|
||||
$assert_session = $this->assertSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
// Add another item with the first item being empty, even though the field
|
||||
// is required.
|
||||
$add_more_button = $page->findButton('field_unlimited_add_more');
|
||||
$add_more_button->click();
|
||||
$field_1 = $assert_session->waitForField('field_unlimited[1][value]');
|
||||
$this->assertNotEmpty($field_1, 'Successfully added another item.');
|
||||
// Confirm the new item has focus.
|
||||
$this->assertHasFocusByAttribute('name', 'field_unlimited[1][value]');
|
||||
// The first item should not be in error state.
|
||||
$assert_session->elementNotExists('css', 'input[name="field_unlimited[0][value]"].error');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts an element specified by an attribute value has focus.
|
||||
*
|
||||
* @param string $name
|
||||
* The attribute name.
|
||||
* @param string $value
|
||||
* The attribute value.
|
||||
*
|
||||
* @todo Replace with assertHasFocus() in https://drupal.org/i/3041768.
|
||||
*/
|
||||
private function assertHasFocusByAttribute(string $name, string $value): void {
|
||||
$active_element = $this->getSession()->evaluateScript('document.activeElement');
|
||||
$this->assertSame($value, $active_element->attribute($name));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -151,14 +151,14 @@ class ContentEntityFormFieldValidationFilteringTest extends BrowserTestBase {
|
|||
$assert_session->elementExists('css', 'input#edit-test-file-0-remove-button');
|
||||
|
||||
// Make the 'Test multiple' field required and check that adding another
|
||||
// item throws a validation error.
|
||||
// item does not throw a validation error.
|
||||
$field_config = FieldConfig::loadByName($this->entityTypeId, $this->entityTypeId, $this->fieldNameMultiple);
|
||||
$field_config->setRequired(TRUE);
|
||||
$field_config->save();
|
||||
|
||||
$this->drupalGet($this->entityTypeId . '/add');
|
||||
$this->submitForm([], 'Add another item');
|
||||
$assert_session->pageTextContains('Test multiple (value 1) field is required.');
|
||||
$assert_session->pageTextNotContains('Test multiple (value 1) field is required.');
|
||||
|
||||
// Check that saving the form without entering any value for the required
|
||||
// field still throws the proper validation errors.
|
||||
|
|
Loading…
Reference in New Issue