我有一个表单,其中包含一个未指定数量的子表单的集合。我希望有一些功能允许用户向Collection中添加一个新的空白项目以供他们填写.Symfony文档告诉我们如何使用Javascript客户端添加新的空白表单控件,然后将其提交并保存为是的,但是我想在没有Javascript的情况下在控制器中执行它。
我遇到的问题与Symfony Forms的工作方式有关。我有一个"添加"按钮添加到我的主窗体,我打算检测是否是已单击的按钮,以便我可以将空白项添加到集合并重新呈现窗体。但要检测点击,我需要调用$ this-> createForm,此时表单已使用原始项目集修复,但添加额外的项目为时已晚。
//Symfony Action
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
$form->handleRequest($request);
//Ideally I'd somehow do this test earlier, but I need $form to do it...
if ($form->get('add')->isClicked() )
{
//TOO LATE!
$person->getSelections()->add(new Selection() );
}
if ($form->isValid())
{
if ($form->get('save')->isClicked() )
{
//Persist
}
}
//Render page etc
我曾经想过的事情:
如何以正确的Symfony方式实现这一目标?
编辑刚刚看到这个:https://github.com/symfony/symfony/issues/5231,这本质上是一个功能请求,允许我之后的内容。评论者提出的一个建议是在收藏中添加一个空白项目,如果不需要则将其删除 - 我不知道如何做到这一点,但听起来很有希望。
另一个编辑我发现,因为我需要创建$ form的两个不同方面,我可以只创建$ form,使用它来处理请求,检测按钮点击,以及然后扔掉那个$ form,然后改变我的模型并创建另一个$ form。我不知道这是否会以某种方式违反关于处理提交两次的一些规则。
答案 0 :(得分:0)
我不是100%,但我认为你可以做到以下几点......
//Symfony Action with (Request $request, ...)
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->get('add')->isClicked()) {
// Add thing
} elseif ($form->isValid()) {
// or
// } elseif ($form->get('save')->isClicked() && $form->isValid()) {
// Persist and what not
}
}
//Render page etc
我还没有测试过,所以我不知道它是否会触发表单错误(或者它是否真的有效)所以如果它确实(或者它没有)我道歉。
答案 1 :(得分:0)
我最后做的是让我的添加按钮点击一个单独的动作,然后用一个标志代表主动作说"添加一个新的选择",如下所示:
public function selectionsAddAction(Request $request, $id)
{
return $this->selectionsAction($request, $id, true);
}
public function selectionsAction(Request $request, $id, $addNew = false)
{
$person = $this->getPerson($id);
//Also use "add mode" if we just deleted the last one!
if (!$person->getSelections()->count())
{
$addNew = true;
}
//$addNew is set by a separate action, hit by a different form with the Add button in
if ($addNew)
{
$person->getSelections()->add(new Selection() );
}
//We now have the right number of items, and can build the form!
$form = $this->createForm(new SelectionsType($lookups), $person);
//...
}