提交方式坚持一个Symfony形式和可选的嵌套形式? [英] How to submit & persist a Symfony form and optional nested form?

查看:85
本文介绍了提交方式坚持一个Symfony形式和可选的嵌套形式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Symfony项目的一页中使用两种表单类型。我这样做是为了让用户在创建新文档
的两个选项之间做出选择:

I'm using two form types for one page in my Symfony project. I do this to let the user decide between two options of creating a new document

页面的构建方式:有几个文本字段,需要填写。它们都属于我的 DocumentCreateType ,并且还包括您可以在图片中看到的选择的右侧部分(手动选择IATA)。我的第二种表单类型( UploadProfileType )包含相同的三个下拉列表以及一个附加的下拉列表(市场,渠道1和产品),但位于选择的左侧站点(使用上载配置文件)。

How the page is build: there are several text fields, to be filled out. They all belong to my DocumentCreateType and also include the right part of the choice (select IATA(s) manually) you can see in the picture. My second form type (UploadProfileType) contains the same three dropdowns plus an addtional one (markets, channel1 and products) but on the left site of the choice (use upload profile(s)).

因此,根据用户选择的内容,仅需提交DocumentCreateType,或者必须提交并保留两种表单类型。

So depending on what the user has chosen, only the DocumentCreateType has to be submitted, or both form types have to be submitted and persisted.

如何使它在Controller中正常工作?到目前为止,我的Controller看起来像这样,但是它不能正确持久存储数据

How can I make this working in my Controller? So far my Controller looks like that but it's not correctly persisting the data

  $upForm = $this->createForm(UploadProfileType::class, $document, array('user' => $currentuser));
    $form = $this->createForm(DocumentCreateType::class, $document);

      $form->handleRequest($request);
     $upForm->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid())
    {
    ...
    }

用于在上传配置文件和IATA之间进行选择的ChoiceType看起来像这样,并由javascript处理:

The ChoiceType for the choice between upload profile and IATA looks like that and is handled by javascript:

  $builder

        ->add('use_upload_profile', ChoiceType::class, array(
                  'choices' => array(
                      true => 'label.use_upload_profile',
                      false => 'label.select_iatas_manually'
                  ),
                  'mapped' => false,
                  'expanded' => true,
                  'label' => false,
                  'data' => true,
                  'translation_domain' => 'Documents'))

            ;
          }


推荐答案

您不能在以下位置提交两种形式同时,这是一个或另一个。因此,我建议您创建两种不同的形式:

You cannot submit two forms at the same time, it's either one or the other. So I would suggest you create two different forms:


  • 第一个表单将在使用上传个人资料时提交选择

  • The first one will be submitted when "Use upload profile(s)" is selected

选择手动选择IATA时将提交第二个

The second one will be submitted when "Select IATA(s) manually" is selected

在每种表格中,您都需要提交所有数据。如果要避免FormType中的重复代码,则可以创建自定义表单类型(不与实体相关联):

In each of the forms you need all the data to be submitted. If you want to avoid duplicated code in the FormType, you can create a Custom Form Type (not associated to an entity):

<?php
// src/AppBundle/Form/Custom/CustomFormType.php

namespace AppBundle\Form\Custom;

use Symfony\Component\Form\Extension\Core\Type\FormType;

class CustomFormType
{
    /**
     * Create the 'upload profile' custom form (not associated to a class)
     * 
     * @param type $formFactory
     * @param type $defaultData
     * @return type
     */
    public function createUploadProfileCustomForm($formFactory, $defaultData)
    {
        /* Create the 'upload profile' form (not associated to a class) */
        $form = $formFactory->createBuilder(FormType::class, $defaultData, array());

        $this->addMarkets($form);
        $this->addChannel1($form);
        $this->addProducts($form);

        /* Add whatever other field necessary */
        $form->add(...);

        /* Return the form */
        return $form->getForm();
    }

    /**
     * Create the 'select IATA manually' custom form (not associated to a class)
     * 
     * @param type $formFactory
     * @param type $defaultData
     * @return type
     */
    public function createSelectIATAManuallyCustomForm($formFactory, $defaultData)
    {
        /* Create the 'select IATA manually' form (not associated to a class) */
        $form = $formFactory->createBuilder(FormType::class, $defaultData, array());

        $this->addMarkets($form);
        $this->addChannel1($form);
        $this->addProducts($form);

        /* Add whatever other field necessary */
        $form->add(...);

        /* Return the form */
        return $form->getForm();
    }

    protected function addMarkets($form)
    {
        $form->add('markets', ...
            /* To complete */
        );
    }

    protected function addChannel1($form)
    {
        $form->add('channel1', ...
            /* To complete */
        );
    }

    protected function addProducts($form)
    {
        $form->add('products', ...
            /* To complete */
        );
    }
}

要在控制器中处理两种形式:

To handle both forms in the controller:

/* Create the 'upload profile' form (not associated to a class) */
$defaultDataUP = array(...);
$customFormTypeUP = new CustomFormType();
$formUploadProfile = $customFormTypeUP->createUploadProfileCustomForm($this->get('form.factory'), $defaultDataUP);
$formUploadProfile ->handleRequest($request);

/* Create the 'select IATA manually' form (not associated to a class) */
$defaultDataSM = array(...);
$customFormTypeSM = new CustomFormType();
$formSelectManually = $customFormTypeSM->createSelectIATAManuallyCustomForm($this->get('form.factory'), $defaultDataSM);
$formSelectManually ->handleRequest($request);

/* If the user selected 'upload profile' and submitted the associated form */
if ($formUploadProfile->isSubmitted() && $formUploadProfile->isValid()) {

    /* Do some action, persist to database, etc. */

    /* Then redirect the user */
    return new RedirectResponse(...);
}
/* Else, if the user selected 'select manually' and submitted the associated form */
elseif ($formSelectManually->isSubmitted() && $formSelectManually->isValid()) {

    /* Do some action, persist to database, etc. */

    /* Then redirect the user */
    return new RedirectResponse(...);
}

/* Render the page, don't forget to pass the two forms in parameters */
return $this->render('yourPage.html.twig', array(
    'form_upload_profile' => $formUploadProfile->createView(),
    'form_select_iata_manually' => $formSelectManually->createView(),
    /* Add other parameters you might need */
));

然后,使用JavaScript,根据选择的单选按钮,显示第一个表单(带有自己的提交按钮)或第二个(也带有自己的提交按钮)。

Then, with JavaScript, depending on which radio button is selected, you display either the first form (with its own submit button) or the second (also with its own submit button).

这篇关于提交方式坚持一个Symfony形式和可选的嵌套形式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆