diff --git a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php index e5a48e65751e49f06b6e02b965982a25ca2dbf1a..c97a4d20b389cf051a8981cf9d71103d50c46625 100644 --- a/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php +++ b/core/modules/file/src/Plugin/Field/FieldWidget/FileWidget.php @@ -318,10 +318,18 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo */ public static function value($element, $input, FormStateInterface $form_state) { if ($input) { - // Checkboxes lose their value when empty. - // If the display field is present make sure its unchecked value is saved. if (empty($input['display'])) { - $input['display'] = $element['#display_field'] ? 0 : 1; + // Updates the display field with the default value because + // #display_field is invisible. + if (empty($input['fids'])) { + $input['display'] = $element['#display_default']; + } + // Checkboxes lose their value when empty. + // If the display field is present, make sure its unchecked value is + // saved. + else { + $input['display'] = $element['#display_field'] ? 0 : 1; + } } } diff --git a/core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetClaroThemeTest.php b/core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetClaroThemeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..69bbaf3bf1ede574fec450036d6e6b2ba3f20ae0 --- /dev/null +++ b/core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetClaroThemeTest.php @@ -0,0 +1,104 @@ +<?php + +namespace Drupal\Tests\file\FunctionalJavascript; + +use Drupal\Core\Url; + +/** + * Tests the widget visibility settings for the Claro theme. + * + * The widget is intentionally tested with Claro as the default theme to test + * the changes added in _claro_preprocess_file_and_image_widget(). + * + * @see _claro_preprocess_file_and_image_widget() + * + * @group file + */ +class FileFieldWidgetClaroThemeTest extends FileFieldWidgetTest { + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'claro'; + + /** + * Tests that the field widget visibility settings are respected on the form. + */ + public function testWidgetDefaultVisibilitySettings(): void { + // Set up an article node with all field storage settings set to TRUE. + $type_name = 'article'; + $field_name = 'test_file_field_1'; + $field_storage_settings = [ + 'display_field' => TRUE, + 'display_default' => TRUE, + ]; + $field_settings = []; + $widget_settings = []; + $field_storage = $this->createFileField($field_name, 'node', $type_name, $field_storage_settings, $field_settings, $widget_settings); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + $test_file = current($this->getTestFiles('text')); + $test_file_path = \Drupal::service('file_system')->realpath($test_file->uri); + + // Fill out the form accordingly. + $this->drupalGet("node/add/$type_name"); + $title = 'Fake Article Name 01'; + $page->findField('title[0][value]')->setValue($title); + $page->attachFileToField('files[' . $field_name . '_0]', $test_file_path); + $remove_button = $assert_session->waitForElementVisible('css', '[name="' . $field_name . '_0_remove_button"]'); + $this->assertNotNull($remove_button); + $type = $assert_session->fieldExists("{$field_name}[0][display]")->getAttribute('type'); + $this->assertEquals($type, 'checkbox'); + $assert_session->checkboxChecked("{$field_name}[0][display]"); + + // Now, submit the same form and ensure that value is retained. + $this->submitForm([], 'Save'); + $node = $this->drupalGetNodeByTitle($title, TRUE); + $this->assertEquals(1, $node->get($field_name)->getValue()[0]['display'], 'The checkbox is enabled.'); + $this->drupalGet(Url::fromRoute('entity.node.edit_form', ['node' => $node->id()])); + $assert_session->checkboxChecked("{$field_name}[0][display]"); + + // Submit the form again with the disabled value of the checkbox. + $this->submitForm([ + "{$field_name}[0][display]" => FALSE, + ], 'Save'); + $node = $this->drupalGetNodeByTitle($title, TRUE); + $this->assertEquals(0, $node->get($field_name)->getValue()[0]['display'], 'The checkbox is disabled.'); + $this->drupalGet(Url::fromRoute('entity.node.edit_form', ['node' => $node->id()])); + $assert_session->checkboxNotChecked("{$field_name}[0][display]"); + + // Disable the field settings and ensure that the form is updated. + $field_storage->setSetting('display_default', FALSE); + $field_storage->save(); + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + $this->drupalGet("node/add/$type_name"); + $title = 'Fake Article Name 02'; + $page->findField('title[0][value]')->setValue($title); + $page->attachFileToField('files[' . $field_name . '_0]', $test_file_path); + $remove_button = $assert_session->waitForElementVisible('css', '[name="' . $field_name . '_0_remove_button"]'); + $this->assertNotNull($remove_button); + $type = $assert_session->fieldExists("{$field_name}[0][display]")->getAttribute('type'); + $this->assertEquals($type, 'checkbox'); + $assert_session->checkboxNotChecked("{$field_name}[0][display]"); + + // Submit the same form and ensure that value is retained. + $this->submitForm([], 'Save'); + $node = $this->drupalGetNodeByTitle($title, TRUE); + $this->assertEquals(0, $node->get($field_name)->getValue()[0]['display'], 'The checkbox is disabled.'); + $this->drupalGet(Url::fromRoute('entity.node.edit_form', ['node' => $node->id()])); + $assert_session->checkboxNotChecked("{$field_name}[0][display]"); + + // Check the checkbox and ensure that it is submitted properly. + $this->submitForm([ + "{$field_name}[0][display]" => TRUE, + ], 'Save'); + $node = $this->drupalGetNodeByTitle($title, TRUE); + $this->assertEquals(1, $node->get($field_name)->getValue()[0]['display'], 'The checkbox is disabled because display_default option is marked as false.'); + $this->drupalGet(Url::fromRoute('entity.node.edit_form', ['node' => $node->id()])); + $assert_session->checkboxChecked("{$field_name}[0][display]"); + } + +} diff --git a/core/themes/claro/claro.theme b/core/themes/claro/claro.theme index 4540cb9f9b36fd44d8ed0076f1ef241e4782640c..f33e425c16591d616cb5b4e4b2a8c3c0b581fecb 100644 --- a/core/themes/claro/claro.theme +++ b/core/themes/claro/claro.theme @@ -1382,6 +1382,11 @@ function _claro_preprocess_file_and_image_widget(array &$variables) { $variables['has_meta'] = $alt_is_visible || $title_is_visible || $display_is_visible || $description_is_visible; $variables['display'] = $display_is_visible; + // Handle the default checkbox display after the file is uploaded. + if (array_key_exists('display', $element)) { + $variables['data']['display']['#checked'] = $element['display']['#value']; + } + // Render file upload input and upload button (or file name and remove button, // if the field is not empty) in an emphasized div. foreach ($variables['data'] as $key => $item) {