我在Symfony项目中为一个页面使用了两种表单类型。我这样做是为了让用户在创建新文档的两个选项之间做出决定
如何构建页面:有几个文本字段要填写。它们都属于我的DocumentCreateType,并且还包括您可以在图片中看到的选择的右侧部分(手动选择IATA)。我的第二种表单类型(UploadProfileType)包含相同的三个下拉列表和一个附加的下一个(市场,渠道1和产品),但在选择的左侧站点(使用上传配置文件)。
因此,根据用户选择的内容,只需提交DocumentCreateType,或者必须提交和保留两种表单类型。
如何在Controller中使用它?到目前为止,我的控制器看起来像这样,但它没有正确持久化数据
$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处理:
$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'))
;
}
提前致谢
多种形式
在HTTP中,您只能在请求中提交一个表单。
为每个表单提交创建一个端点,您只需提交一个表单。
创建文档A - > createADocumentAction()
创建文档B - > createBDocumentAction()
一切形式与一切
如果您将表单调用到一组数据但所有内容都通过单个请求进行提交,则应创建一个Symfony From(Type),其中包含您计划提交的两个symfony表单的所有数据。
您不能同时提交两个表格,它可以是一个或另一个。所以我建议你创建两种不同的形式:
在每个表单中,您都需要提交所有数据。如果要避免FormType中的重复代码,可以创建自定义表单类型(不与实体关联):
<?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 */
);
}
}
要在控制器中处理这两种形式:
/* 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,根据选择的单选按钮,您可以显示第一个表单(带有自己的提交按钮)或第二个表单(也有自己的提交按钮)。