Php 如何在Symfony 3中使用嵌套表单处理程序
我正在学习Symfony将一个旧网站从平面PHP移动到一个框架 在旧网站中,我有一个包含两级表单的页面:第一级只是一个按钮,用户可以通过它接受一些条件,而第二级则向网站管理员发送消息。当用户单击第一个表单中的按钮时,页面将刷新,并显示第二个表单。重要的是,用户不按第一个按钮就无法访问第二个表单 现在,行动方法是这样的:Php 如何在Symfony 3中使用嵌套表单处理程序,php,forms,symfony,Php,Forms,Symfony,我正在学习Symfony将一个旧网站从平面PHP移动到一个框架 在旧网站中,我有一个包含两级表单的页面:第一级只是一个按钮,用户可以通过它接受一些条件,而第二级则向网站管理员发送消息。当用户单击第一个表单中的按钮时,页面将刷新,并显示第二个表单。重要的是,用户不按第一个按钮就无法访问第二个表单 现在,行动方法是这样的: /** * @Route("/ask-consultation", name="ask_consultation") */ public function askConsul
/**
* @Route("/ask-consultation", name="ask_consultation")
*/
public function askConsultationAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $form = $this->createFormBuilder()
->add('submit', SubmitType::class, array('label' => 'Confermo'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$consultation = new Consultation;
$form = $this->createForm(AskConsultationType::class, $consultation);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$consultation = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($consultation);
$em->flush();
return $this->redirectToRoute('homepage');
}
return $this->render('visitor/consultation/ask_step2.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'sidebars' => $em->getRepository('AppBundle:Sidebar')->findAllOrderedBySortingPosition(),
'form' => $form->createView(),
]);
}
当我进入/询问咨询
时,它会显示接受特定条件的按钮;当我单击按钮时,它会显示要发送消息的表单,但当我发送它时,我不会被重定向到主页
,而是再次重定向到/ask consultation
的第一页
我明白为什么这个代码不起作用,但我不明白如何使它起作用。一种解决方案可以是第一种形式的某种模态对话框,但如果可能的话,我更愿意用PHP处理所有的段落。是否可以在不更改路线的情况下拆分表单处理
在我的例子中,最重要的一点是,如果用户没有首先单击第一个按钮,就无法访问第二个表单。在单个表单中呈现所有内容,但使用javascript(jQuery)隐藏表单的询问咨询部分。当用户单击“确认”时,取消隐藏表单。这避免了控制器进行确认步骤。不管怎样,您似乎没有记录这个确认,所以让客户端来处理事情。您仍然可以检查(表单提交时)是否接受“确认”,例如通过javascript设置隐藏变量。在单个表单中呈现所有内容,但使用javascript(jQuery)隐藏表单的询问咨询部分。当用户单击“确认”时,取消隐藏表单。这避免了控制器进行确认步骤。不管怎样,您似乎没有记录这个确认,所以让客户端来处理事情。您仍然可以(在表单提交时)检查“确认”是否被接受,例如通过javascript设置一个隐藏变量。结果证明答案非常简单 在我看来,我必须在第一个
if($form->isSubmitted()&&&$form->isValid())
中处理第二个表单,但这当然不是PHP采用的路径。每次加载路由时,askConsultationAction()
从其第一条指令开始运行。我只需初始化两个表单(显然,使用不同的变量名),然后一个接一个地处理表单,而不是一个接一个地处理表单
此代码就像一个符咒:
/**
* @Route("/ask-consultation", name="ask_consultation")
*/
public function askConsultationAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$consultation = new Consultation;
$conditions_form = $this->createFormBuilder()
->add('submit', SubmitType::class, array('label' => 'Confermo'))
->getForm();
$consultation_form = $this->createForm(AskConsultationType::class, $consultation);
$consultation_form->handleRequest($request);
$conditions_form->handleRequest($request);
if ($conditions_form->isSubmitted() && $conditions_form->isValid()) {
return $this->render('visitor/consultation/ask_step2.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'sidebars' => $em->getRepository('AppBundle:Sidebar')->findAllOrderedBySortingPosition(),
'form' => $consultation_form->createView(),
]);
}
if ($consultation_form->isSubmitted() && $consultation_form->isValid()) {
$consultation = $consultation_form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($consultation);
$em->flush();
return $this->redirectToRoute('homepage');
}
return $this->render('visitor/consultation/ask_step1.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'sidebars' => $em->getRepository('AppBundle:Sidebar')->findAllOrderedBySortingPosition(),
'form' => $conditions_form->createView(),
]);
}
也许,如果我用
的话会更好。。。如果…
结果是答案很简单
在我看来,我必须在第一个if($form->isSubmitted()&&&$form->isValid())
中处理第二个表单,但这当然不是PHP采用的路径。每次加载路由时,askConsultationAction()
从其第一条指令开始运行。我只需初始化两个表单(显然,使用不同的变量名),然后一个接一个地处理表单,而不是一个接一个地处理表单
此代码就像一个符咒:
/**
* @Route("/ask-consultation", name="ask_consultation")
*/
public function askConsultationAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$consultation = new Consultation;
$conditions_form = $this->createFormBuilder()
->add('submit', SubmitType::class, array('label' => 'Confermo'))
->getForm();
$consultation_form = $this->createForm(AskConsultationType::class, $consultation);
$consultation_form->handleRequest($request);
$conditions_form->handleRequest($request);
if ($conditions_form->isSubmitted() && $conditions_form->isValid()) {
return $this->render('visitor/consultation/ask_step2.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'sidebars' => $em->getRepository('AppBundle:Sidebar')->findAllOrderedBySortingPosition(),
'form' => $consultation_form->createView(),
]);
}
if ($consultation_form->isSubmitted() && $consultation_form->isValid()) {
$consultation = $consultation_form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($consultation);
$em->flush();
return $this->redirectToRoute('homepage');
}
return $this->render('visitor/consultation/ask_step1.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
'sidebars' => $em->getRepository('AppBundle:Sidebar')->findAllOrderedBySortingPosition(),
'form' => $conditions_form->createView(),
]);
}
也许,如果我用
的话会更好。。。如果…
您想过创建吗?这在你的例子中似乎是恰当的。Once类可以是条件
表单,其他咨询
表单。使用类是更好的做法-我以前在控制器中使用过,但代码可能会变得混乱。我将每个表单都作为一个类编写,但我将第一个表单保留在控制器中,因为它包含一个简单的按钮。然而,你是对的:保持一致并将每个表单作为一个类来编写更有意义。你想过创建吗?这在你的例子中似乎是恰当的。Once类可以是条件
表单,其他咨询
表单。使用类是更好的做法-我以前在控制器中使用过,但代码可能会变得混乱。我将每个表单都作为一个类编写,但我将第一个表单保留在控制器中,因为它包含一个简单的按钮。然而,你是对的:保持一致并将每个表单作为一个类来编写更有意义。这当然是一个解决方案。然而,由于它在客户端可能会失败,所以我希望在这类任务中至少依赖Javascript。这肯定是一个解决方案。然而,由于它在客户端可能会失败,因此我希望在这类任务中至少依赖Javascript。