Symfony2集合为每个元素选择不同的选项

时间:2017-02-14 17:29:03

标签: symfony

经过多次搜索和尝试后,我不知道如何解决我的问题。

我发现了这个:Symfony2 Form Collection Field with Different Choices但解决方案没有给出搜索路径,我没有找到如何在我的情况下调整解决方案。

本地化与地域之间存在多对多的关系,在部门与部门之间存在多对多的关系,本地化与城市之间存在多对多的关系。

要创建本地化,我有以下形式:

class LocalizationType extends AbstractType{


private $manager;

public function __construct(ObjectManager $manager)
{
    $this->manager = $manager;
}

public function buildForm(FormBuilderInterface $builder, array $options){


    $builder->add('regions', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                            'allow_add' => true,
                                                            'allow_delete' => true,
                                                            'required' => false,
                                                            'entry_options' => array(
                                                                'choices' => (array_key_exists('regions', $options['localization_value']) ? $options['localization_value']['regions'] : array('' => '')),
                                                                'multiple' => false,
                                                                'expanded' => false,
                                                                'attr' => array('class' => 'region input'),

                                                                ),
                                                            'data' => (array_key_exists('regions', $options['localization_data']) ? $options['localization_data']['regions'] : null),
                                                            ))
            ->add('departments', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                                'allow_add' => true,
                                                                'allow_delete' => true,
                                                                'required' => false,
                                                                'entry_options' => array(
                                                                'choices' => (array_key_exists('departments', $options['localization_value']) ? $options['localization_value']['departments'] : array('' => '')),
                                                                    'multiple' => false,
                                                                    'expanded' => false,
                                                                    'attr' => array('class' => 'department input')
                                                                    ),
                                                                'data' => (array_key_exists('departments', $options['localization_data']) ? $options['localization_data']['departments'] : null),
                                                                ))
            ->add('cities', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                            'allow_add' => true,
                                                            'allow_delete' => true,
                                                            'required' => false,
                                                            'entry_options' => array(
                                                                'choices' => (array_key_exists('cities', $options['localization_value']) ? $options['localization_value']['regions'] : array('' => '')),
                                                                'multiple' => false,
                                                                'expanded' => false,
                                                                'attr' => array('class' => 'city input')
                                                                ),
                                                            'data' => (array_key_exists('cities', $options['localization_data']) ? $options['localization_data']['cities'] : null),
                                                            ))
    ;

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event){

        $data = $event->getData();

        if(!empty($data['regions']) && is_array($data['regions'])){

            $regions = array();

            foreach($data['regions'] as $region){

                $regions[] = $region;

            }

            $data['regions'] = $this->manager->getRepository('LocalizationBundle:Region')->findRegionsForCreateEntity($regions);

        }

        if(!empty($data['departments']) && is_array($data['departments'])){

            $departments = array();

            foreach($data['departments'] as $department){

                $departments[] = $department;

            }

            $data['departments'] = $this->manager->getRepository('LocalizationBundle:Departments')->findDepartmentsForCreateEntity($departments);

        }

        if(!empty($data['cities']) && is_array($data['cities'])){

            $cities = array();

            foreach($data['cities'] as $city){

                $cities[] = $city;

            }

            $data['cities'] = $this->manager->getRepository('LocalizationBundle:City')->findCitiesForCreateEntity($cities);

        }

        $form = $event->getForm();

        $form->add('regions', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                            'allow_add' => true,
                                                            'allow_delete' => true,
                                                            'required' => false,
                                                            'entry_options' => array(
                                                                'choices' => $data['regions'],
                                                                'multiple' => false,
                                                                'expanded' => false,
                                                                'attr' => array('class' => 'region input')
                                                                )
                                                            ));


                $form->add('departments', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                                    'allow_add' => true,
                                                                    'allow_delete' => true,
                                                                    'required' => false,
                                                                    'entry_options' => array(
                                                                        'choices' => $data['departments'],
                                                                        'multiple' => false,
                                                                        'expanded' => false,
                                                                        'attr' => array('class' => 'department input')
                                                                        )
                                                                    ))
                ->add('cities', CollectionType::class, array('entry_type' => ChoiceType::class,
                                                                'allow_add' => true,
                                                                'allow_delete' => true,
                                                                'required' => false,
                                                                'entry_options' => array(
                                                                    'choices' => $data['cities'],
                                                                    'multiple' => false,
                                                                    'expanded' => false,
                                                                    'attr' => array('class' => 'city input')
                                                                    )
                                                                ))
    ;


    });

}

public function configureOptions(OptionsResolver $resolver){

    $resolver->setDefaults(array(
        'data_class' => Localization::class,
        'localization_data' => array('regions' => '', 'departments' => '', 'cities' => ''),
        'localization_value' => array('regions' => '', 'departments' => '', 'cities' => ''),
    ));

}

我选择一个ChoiceType为空,因为我有几个City例如(更多25k)所以我更喜欢在我的视图中用AJAX加载其中几个并在select2中渲染它,它适用于添加动作但是对于编辑动作我有一个问题我希望我的收藏品的每个字段都有不同的价值。

为了说明我的故事,我想要这个结果:

<label>Region n°1</label>
<select id="" name="">
    <option value="foo1">bar1</option>
</select>

<label>Region n°2</label>
<select id="" name="">
    <option value="foo2">bar2</option>
</select>

我目前的结果是:

<label>0</label>
<select id="" name="">
    <option value="foo1" selected="selected">bar1</option>
    <option value="foo2">bar2</option>
</select>

<label>1</label>
<select id="" name="">
    <option value="foo1">bar1</option>
    <option value="foo2" selected="selected">bar2</option>
</select>

如果我理解我需要创建自己的模板,更改标签,好的但是只显示选择的选项而不显示其他选项我认为我需要在PRE_SET_DATA上使用FormEventListener,但我不知道如何实现它。所以,如果有人有解决方案,我会接受它。

1 个答案:

答案 0 :(得分:0)

我回答我自己的问题,在PRE_SET_DATA上使用FormEventListener,在POST_SET_DATA上尝试,或者使用choice_loader,似乎不可能用Symfony方式做我想要的,但我不太明白为什么。我感觉回到Jquery的方式来删除未使用以下代码选择的选项,我不喜欢但我没有看到其他解决方案:

<script type="text/javascript">

    $.each($('.region'), function(i, val){

        $(val).find('option:not(:selected)').remove();

    })

    $.each($('.department'), function(i, val){

        $(val).find('option:not(:selected)').remove();

    })

    $.each($('.city'), function(i, val){

        $(val).find('option:not(:selected)').remove();

    })
</script>

如果我错了,我不会传递解决的主题