通过实体形式的具体选择

时间:2015-04-21 13:11:28

标签: forms symfony

我试图生成一个特定的表单。

我有两个班,城市和机场。

由于OneToMany关系,每个城市都有一些机场。

当用户选择机场时,我想只显示属于特定城市的机场。有办法吗?

到目前为止,我的表单字段如下所示:

            ->add('departure', 'entity', array(
'class' => 'AOFVHFlyBundle:Airport',
'property' => 'name',
'label' => 'Departure'
))

1 个答案:

答案 0 :(得分:1)

您描述的内容(几乎)正是one of the documentation examples,我已根据您的需要对其进行了调整,但我建议您阅读它。

PRE_SET_DATA事件上添加事件侦听器,以便将Airport字段和POST_SUBMIT侦听器动态添加到此新字段所依赖的字段中。如果向表单子项添加POST_SUBMIT侦听器(例如sport),并将新子项添加到父表单,则表单组件将自动检测新字段并将其映射到提交的客户端数据。

YourGlobalEntityType.php

<?php
// src/AOFVHFlyBundle/Form/Type/YourGlobalEntityType.php
namespace AOFVHFlyBundle\Form\Type;

// ...
use Symfony\Component\Form\FormInterface;
use AOFVHFlyBundle\Entity\City;
use AOFVHFlyBundle\Entity\Airport;

class YourGlobalEntityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('city', 'entity', array(
                'class'    => 'AOFVHFlyBundle:Airport',
                'property' => 'name',
                'label'    => 'Departure'
            ))
        ;

        $formModifier = function (FormInterface $form, City $city = null) {
            $airports = null === $city ? array() : $city->getAvailableAirports();

            $form->add('departure', 'entity', array(
                'class'       => 'AOFVHFlyBundle:Airport',
                'property'    => 'name',
                'choices'     => $airports,
                'label'       => 'Departure',
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. YourGlobalEntity
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getAirport());
            }
        );

        $builder->get('city')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $city = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback functions!
                $formModifier($event->getForm()->getParent(), $city);
            }
        );
    }

    // ...
}

然后在你的Twig中,添加使其动态化所需的javascript:

{# src/AOFVHFlyBundle/Resources/views/YourGlobalEntity/create.html.twig #}
{{ form_start(form) }}
    {{ form_row(form.city, { 'attr': { 'class':'yourglobalentity_city' } } ) }}
    {{ form_row(form.departure, { 'attr': { 'class':'yourglobalentity_departure' } } ) }}
    {# ... #}
{{ form_end(form) }}

<script>
var $city = $('.yourglobalentity_city');
// When city gets selected ...
$city.change(function() {
  // ... retrieve the corresponding form.
  var $form = $(this).closest('form');
  // Simulate form data, but only include the selected city value.
  var data = {};
  data[$city.attr('name')] = $city.val();
  // Submit data via AJAX to the form's action path.
  $.ajax({
    url : $form.attr('action'),
    type: $form.attr('method'),
    data : data,
    success: function(html) {
      // Replace current position field ...
      $('.yourglobalentity_departure').replaceWith(
        // ... with the returned one from the AJAX response.
        $(html).find('.yourglobalentity_departure')
      );
      // Position field now displays the appropriate positions.
    }
  });
});
</script>