как добавить варианты выбора после загрузки страницы в symfony2

После загрузки страницы поле выбора заполняется динамически с помощью jquery, но данные поста не загружаются в $form->getData(). После некоторого поиска можно добавить скрытое поле и добавить значение с помощью javascript. Я хотел бы знать, существует ли другой вариант.

Это действие:

 $form = $this->createFormBuilder()
    ->add('country','file')
    ->add('admcod2','file')
    ->add('isocountry', 'choice', array('empty_value' => 'select country'))
    ->add('iso','hidden')
    ->getForm();

Выбор заполнен jquery

$("#form_isocountry").jeoCountrySelect({
    callback: function () {
    $("#form_isocountry").removeAttr('disabled');
    }
});

//this add the value to a hidden field... 
$("#form_isocountry").change(function() {
    $("#form_iso").val($("#form_isocountry").val());
})

Таким образом, symfony не распознает параметры, загруженные при динамическом выборе. var_dump($form->getData()) показывает заполненное скрытое поле, но не поле выбора.

Спасибо.


person Fernando    schedule 15.04.2013    source источник
comment
Аргггг. Да я вижу. Я добавлю «программно» варианты с Services_GeoNames(Pear) в контроллере.   -  person Fernando    schedule 17.04.2013


Ответы (2)


Я считаю, что choice не является правильным типом поля для этого варианта использования, потому что с точки зрения поля формы список возможных вариантов пуст. Поэтому представленное значение никогда не будет действительным (кроме случаев, когда оно пусто).

Я могу предложить вам либо использовать hidden в качестве типа этого поля, либо указать список вариантов для поля формы с типом choice.

person gatisl    schedule 15.04.2013

Таким образом я использовал ChoiceType полей. Думаю, это логичный выбор. Основная проблема с ним (и по умолчанию EntityToIdTransformer или EntityChoiceList) заключается в том, что он увлажняет все возможные варианты, чтобы выбрать один, что в некоторых случаях излишне. Вам, вероятно, придется написать свой собственный преобразователь, чтобы предотвратить это. Я использую AJAX для загрузки данных в выборку после загрузки страницы. Это делает страницы меньше, ускоряет время обработки страниц и позволяет мне более точно кэшировать каждый набор параметров.

Это для Symfony 2.0. Он отлично работает, и мы разместили кучу полей Chosen на одной странице с более чем 4000 опций в них (хотя элементы Chosen создаются только тогда, когда пользователь взаимодействует с виджетом). Теперь ограничение — память браузера.

ContactEntityType

class ContactEntityType extends AbstractType {    
    public function __construct(EntityManager $em) {
        $this->em = $em;
    }

    public function buildForm(FormBuilder $builder, array $options) 
    {
        $repository = $this->em->getRepository('AcmeContactsBundle:Contact');
        $builder->prependClientTransformer(new ContactToIdTransformer($repository));
    }

    public function buildView(FormView $view, FormInterface $form)
    {
        $contact = $form->getData();

        if($contact instanceof \Acme\ContactsBundle\Entity\Contact) {
            $view->set('choices', array($contact->getId() => $contact->getName()));
        }
    }

    public function getParent(array $options) {
        return 'choice';
    }
}

ContactToIdTransformer

Это разновидность встроенного EntityToIdTransformer.

...
class ContactToIdTransformer implements DataTransformerInterface
{
    private $repository;

    public function __construct(EntityRepository $repository)
    {
        $this->repository = $repository;
    }

    public function transform($entity)
    {            
        if (null === $entity || '' === $entity) {
            return null;
        }

        if (!is_object($entity)) {
            throw new UnexpectedTypeException($entity, 'object');
        }

        if ($entity instanceof Collection) {
            throw new \InvalidArgumentException('Expected an object, but got a collection. Did you forget to pass "multiple=true" to an entity field?');
        }

        return $entity->getId();
    }

    public function reverseTransform($key)
    {
        if ('' === $key || null === $key) {
            return null;
        }

        if (!is_numeric($key)) {
            throw new UnexpectedTypeException($key, 'numeric');
        }

        if (!($entity = $this->repository->find($key))) {
            throw new TransformationFailedException(sprintf('The entity with key "%s" could not be found', $key));
        }
        return $entity;
    }
}
person Ryan    schedule 16.04.2013