EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
4.04k stars 1.02k forks source link

Collection field validation errors not placed correctly #5637

Open skyferix opened 1 year ago

skyferix commented 1 year ago

Collection fields validation error are not being rendered in proper location. Could there be the case that error fields are not being rendered for the custom form fields at all? If yes what could code look like? Do i need to define whole form template or field template for single error is enough?

Using easy admin 4.5.1. Basically using custom form type to render colletion field and errors are not beeign mapped correctly. Tried set error_bubbling to false and using error_mapping bouth to parent field 'agents' and sub-form field 'name' but it did not help.

Field: image

FormType: image

Data class: image

Profiler validator tab output: image

Profiler forms tab output: image

skyferix commented 1 year ago

Took a second look at the problem. The issue lies in collection starting at index 1 and assert asserting at index 0. Still searching to solutions how to make them match

skyferix commented 1 year ago

After investigation find the same problem over here -> https://github.com/symfony/symfony/issues/7468#issuecomment-213411710

And after modifing the code end up with this code in my crud controller: Hope it helps someone because it was big pain for me. I don't know how this bundle handles Field related logic but it whould be nice to add Colletion field access to form in order to add listener. Then creating custom Field with listener defined in it could be really nice.

`public function createNewFormBuilder( EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context ): FormBuilderInterface { $formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context);

    return $this->buildForm($formBuilder);
}

public function createEditFormBuilder(
    EntityDto $entityDto,
    KeyValueStore $formOptions,
    AdminContext $context
): FormBuilderInterface {
    $formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context);

    return $this->buildForm($formBuilder);
}

public function buildForm(FormBuilderInterface $builder): FormBuilderInterface
{
    return $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}

public function onPreSubmit(FormEvent $event)
{
    $data = $event->getData();
    $object = $event->getForm()->getData();

    // Loop on form fields
    foreach ($event->getForm()->all() as $field) {
        $fieldName = $field->getName();
        if ($field->getConfig()->getType()->getInnerType() instanceof CollectionType) {
            if (isset($data[$fieldName]) && $object) {
                $collection = $data[$fieldName];
                $data[$fieldName] = [];
                $k = -1;
                foreach ($object->{'get' . ucfirst($fieldName)}() as $k => $item) {
                    // Search
                    foreach ($collection as $i => $c) {
                        $cId = is_array($c) && isset($c['id']) ? $c['id'] : $c;
                        if ($item->getId() == $cId) {
                            $data[$fieldName][$k] = $c;
                            unset($collection[$i]);
                            break;
                        }
                    }
                }
                // Added items
                foreach ($collection as $c) {
                    $data[$fieldName][++$k] = $c;
                }
            }
        }
    }

    $event->setData($data);
}`
skyferix commented 1 year ago

Have pressed the wrong button again. Reopening to dev investigation

wehostadm commented 11 months ago

same problem for me, errors are not set to the right place when using _errormapping and _errorbubbling = false