Symfony表单实体允许添加

3
我正在使用Symfony 2.3构建一个应用程序。 我有一个Booking实体,它与一个Customer实体通过ManyToOne关系相关联。
在我的表单中,我想能够选择一个现有的客户或创建一个新客户。例如,在我的客户选择中添加一个“新客户”选项,这将显示客户表单。
实际上,我正在尝试构建一个实体表单字段,其中包含类似于集合表单字段中的“allow_add”选项。
有任何想法如何做到这一点吗?
非常感谢。
2个回答

1
感谢您的贡献。我找到了一种实现方法! 解决方案是在客户表单中添加一个字段,并将其映射,同时在客户实体中添加一个实体字段但不进行映射。
$builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event) use ($company) {
            $form = $event->getForm();
            $data = $event->getData();

            $form->add('customer_list', 'entity',
                [
                    'class' => 'SomeBunlde\Entity\Customer',
                    'label'    => 'Client',
                    'property' => 'fullName',
                    'expanded' => false,
                    'multiple' => false,
                    'mapped'   => false,
                    'query_builder' => function(EntityRepository $er) use ($company)
                        {
                            return $er->getByCompanyQueryBuilder($company);
                        },
                ]
            )
            ;

            if ($data->getCustomer() === null) {
                $form->add('customer', new CustomerType());
            }
        }

在实体表单字段中添加额外选项后,通过重载finishView方法:
public function finishView(FormView $view, FormInterface $form, array $options)
{
    array_unshift($view->children['customer_list']->vars['choices'], new SfFormExt\ChoiceView('test', 'new', 'Nouveau client'));
}

然后我添加了两个事件监听器,一个是 pre_submit 用于删除映射的嵌入式客户表单及其数据:

$builder->addEventListener(
        FormEvents::PRE_SUBMIT,
        function(FormEvent $event) use ($em) {
            $data = $event->getData();

            if ($data['customer_list'] !== 'new') {
                unset($data['customer']);
                $event->getForm()->remove('customer');
                  // setting data w/out customer to avoid extra-field error
                $event->setData($data);
            }
        }
    );

并绑定一个事件将现有客户附加到预订中:

$builder->addEventListener(
        FormEvents::BIND,
        function(FormEvent $event) use ($em) {
            $form = $event->getForm();
            $data = $event->getData();

            if (!$form->has('customer')) {
                $existing_customer = $form->get('customer_list')->getData();
                if ($existing_customer instanceof Customer) {
                    $data->setCustomer($existing_customer);
                }
            }
        }
    );

我知道这可能不是最先进的代码,但它运行得非常好。

编辑:我遇到了一个问题,因为当customer_list设置为new时,它会抛出一个错误。我没有找到避免此错误的方法(如果您有任何想法,请告诉我!),因此我决定修改pre_submit,如果我们处于新客户情况下,则将customer_list值的数据设置为'',然后在控制器中检测是否存在新客户表单的表单验证错误,以便正确显示它。


0

我认为用JavaScript管理这个工作流程是最好的方法。

如果用户选择创建一个新客户,你可以在模态框中打开一个创建新客户的表单,并通过Ajax创建新客户。创建操作的响应将返回id,该id将由您用于使用新创建的客户创建预订。

诀窍在于:您将始终从现有客户创建预订。您的用户可以在过程中创建一个新客户,但实际上它将在您创建预订记录之前创建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接