diff --git a/src/Field/Configurator/AssociationConfigurator.php b/src/Field/Configurator/AssociationConfigurator.php index c30b90b339..09e9603b7c 100644 --- a/src/Field/Configurator/AssociationConfigurator.php +++ b/src/Field/Configurator/AssociationConfigurator.php @@ -430,10 +430,20 @@ private function configureCrudForm(FieldDto $field, EntityDto $entityDto, string $crudPageName = Crud::PAGE_EDIT; } - $field->setFormTypeOption( - 'entityDto', - $this->createEntityDto($targetEntityFqcn, $targetCrudControllerFqcn, $targetCrudControllerAction, $targetCrudControllerPageName, $crudPageName), - ); + $embeddedEntityDto = $this->createEntityDto($targetEntityFqcn, $targetCrudControllerFqcn, $targetCrudControllerAction, $targetCrudControllerPageName, $crudPageName); + $field->setFormTypeOption('entityDto', $embeddedEntityDto); + + // The assets declared by the embedded controller's fields (e.g. TextEditorField, + // FileField, a nested CollectionField...) live on the embedded EntityDto, not on + // the parent AssociationField. Propagate them up so that + // AbstractCrudController::getFieldAssets(), which only walks top-level fields, + // picks them up and outputs the required CSS/JS on the form page that hosts the + // embedded CRUD form. See #6127. + $assets = $field->getAssets(); + foreach ($embeddedEntityDto->getFields() ?? [] as $embeddedField) { + $assets = $assets->mergeWith($embeddedField->getAssets()); + } + $field->setAssets($assets); } /** diff --git a/src/Field/Configurator/CollectionConfigurator.php b/src/Field/Configurator/CollectionConfigurator.php index 5b9b47ebce..6add33a426 100644 --- a/src/Field/Configurator/CollectionConfigurator.php +++ b/src/Field/Configurator/CollectionConfigurator.php @@ -214,6 +214,19 @@ private function configureEntryType(FieldDto $fieldDto, EntityDto $entityDto, Ad $fieldDto->setFormTypeOption('prototype_options.entityDto', $newEntityDto); $fieldDto->setFormTypeOptionIfNotSet('prototype_data', $createEntryEntity()); $fieldDto->setFormTypeOptionIfNotSet('entry_options.empty_data', $createEntryEntity); + + // The assets declared by entry fields (e.g. TextEditorField, FileField, a nested + // CollectionField...) live on the entry EntityDto, not on the parent CollectionField. + // Propagate them up so that AbstractCrudController::getFieldAssets(), which only + // walks top-level fields, picks them up and outputs the required CSS/JS on the + // form page that hosts the embedded CRUD form. See #6127. + $assets = $fieldDto->getAssets(); + foreach ([$editEntityDto, $newEntityDto] as $entryEntityDto) { + foreach ($entryEntityDto->getFields() ?? [] as $entryField) { + $assets = $assets->mergeWith($entryField->getAssets()); + } + } + $fieldDto->setAssets($assets); } /**