diff -u b/core/modules/file/file.js b/core/modules/file/file.js --- b/core/modules/file/file.js +++ b/core/modules/file/file.js @@ -36,10 +36,6 @@ elements = settings.file.elements; Object.keys(elements).forEach(initFileValidation); } - - // Trigger visible state to allow States to react to the loading of - // this element. - $(document).trigger('state:visible'); }, detach: function (context, settings, trigger) { var $context = $(context); @@ -140 +136 @@ -})(jQuery, Drupal); \ No newline at end of file +})(jQuery, Drupal); diff -u b/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php --- b/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -355,15 +355,16 @@ // Add states to ajax wrapper so states.js can potentially attach this // element as a Dependent. - $attributes = ''; + $attributes = new Attribute(['id' => $ajax_wrapper_id]); if (isset($element['#states']) && !empty($element['#states'])) { - $attributes = new Attribute([ - 'data-drupal-states' => json_encode($element['#states']), - ]); + $attributes->offsetSet('data-drupal-states', json_encode($element['#states'])); + + // Add states to the file form element itself. + $element['upload']['#states'] = $element['#states']; } // Prefix and suffix used for Ajax replacement. - $element['#prefix'] = '
'; + $element['#prefix'] = ''; $element['#suffix'] = '
'; return $element; diff -u b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php --- b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php +++ b/core/modules/file/tests/modules/file_test_states/src/Form/FileTestStatesForm.php @@ -39,6 +39,13 @@ 'visible' => [':input[name="toggle"]' => ['checked' => TRUE]], ], ]; + $form['managed_file_initially_optional'] = [ + '#type' => 'managed_file', + '#title' => t('Managed File Initially Optional'), + '#states' => [ + 'required' => [':input[name="toggle"]' => ['checked' => TRUE]], + ], + ]; return $form; } diff -u b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php --- b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php +++ b/core/modules/file/tests/src/FunctionalJavascript/FileManagedStateTest.php @@ -19,13 +19,6 @@ public static $modules = ['file_test_states', 'file']; /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - } - - /** * Tests if managed file is correctly hidden with states. */ public function testFileStateVisible() { @@ -40,6 +33,7 @@ // Now get the fields from the page. $field_initially_visible = $page->findField('files[managed_file_initially_visible]'); $field_initially_hidden = $page->findField('files[managed_file_initially_hidden]'); + $field_initially_optional = $page->findField('files[managed_file_initially_optional]'); // Check that the initially visible managed file is visible. $this->assertTrue($field_initially_visible->isVisible()); @@ -47,6 +41,9 @@ // Check that the initially hidden managed file is hidden. $this->assertFalse($field_initially_hidden->isVisible()); + // Check that the initially optional managed file is optional. + $this->assertFalse($field_initially_optional->hasAttribute('required')); + // Toggle the fields. $page->findField('toggle')->click(); @@ -55,6 +52,9 @@ // Check that the initially hidden managed file is now visible. $this->assertTrue($field_initially_hidden->isVisible()); + + // Check that the initially optional managed file is now required. + $this->assertTrue($field_initially_optional->hasAttribute('required')); } }