6

I've got two choice fields, one depending on the other.

When building the form the depending field got an empty choices' array.

I then fill this field in JavaScript requesting some datas from an action.

The issue comes from validation. Of course it doesn't pass because single or multiples values can't be valid against empty value. To solve that I've created a PRE_BIND listener which basically remove then recreate the choice field with the right values, but it still doesn't pass validation.

$form->getErrors() returns nothing but $form->getErrorsAsString() returns me an error on my choice field.

My form:

<?php

namespace Foo\BarBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BarFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // other fields

        // This field is filled in ajax
        $builder->add('stores', 'choice', array(
            'label' => 'form.label.stores',
            'translation_domain' => 'FooBarBundle',
            'choices' => $options['storesList'],
            'required' => false,
            'multiple' => true,
            'auto_initialize' => false,
            'attr' => array(
                'class' => 'chzn-select',
                'placeholder' => 'form.placeholder.stores'
        )));

        $func = function (FormEvent $e) use ($options) {
            $data = $e->getData();
            $form = $e->getForm();
            if ($form->has('stores')) {
                $form->remove('stores');
            }

            $brand = isset($data['brand']) ? $data['brand'] : null;

            if ($brand !== null) {
                $choices = $options['miscRepo']->getStoresNameIndexedById($brand);
                $choices = array_keys($choices);
                $choices = array_map('strval', $choices);
            } else {
                $choices = array();
            }

            $form->add('stores', 'choice', array('choices' => $choices, 'multiple' => true, 'attr' => array('class' => 'chzn-select')));
        };

        $builder->addEventListener(FormEvents::PRE_SUBMIT, $func);
    }

    public function getName()
    {
        return 'bar_form_campaign';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setRequired(array(
            'storesList',
            'miscRepo',
        ));
    }
}
4

1 回答 1

0

我遇到了和你一样的问题:通过 javascript 更新字段,但没有通过验证。在 PRE_SUBMIT 事件中,读取您使用 javascript 添加的值,查询并获取具有该 ID 的对象,并更新字段选择。

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
    $data = $event->getData();
    $form = $event->getForm();
    $pageId = $data['page_id'];

    $page = $this->myManager->getPage($pageId);
    $options = array($page->getId() => $page->getTitle());

    $form->add('page_id', 'choice', array(
        'label'         => 'Select page',
        'choices'       => $options,
        'required'      => true,
        'placeholder'   => 'Select page'
    ));

    $form->getData()->setPageId($pageId);
});
于 2015-01-16T16:31:18.150 回答