【问题标题】:Symfony2 form in modal is not handled未处理模态中的 Symfony2 表单
【发布时间】:2015-02-11 05:43:33
【问题描述】:

我将表单类中的表单渲染为基于模式的表单,然后根据按下的按钮执行不同的操作。表单的目的是编辑实体。

当我在模式中显示表单时,无论我按下哪个按钮,它都不会处理它,但是当我在新选项卡中呈现表单时,所有操作都会正确执行。

奇怪的是,即使现在在我的代码中禁用了将用户推回到完整资源列表的重定向,但当我单击模式按钮时页面仍然会刷新。

解决方案:

我需要手动将表单操作添加到模态中的表单,以便它调用正确的控制器操作进行处理。为了达成这个解决方案没有太多讨论,所以为了其他人的方便,我们开始吧:

{{ form_start(form, {'action': path('sfi_teacher_manage_resource', { 'id': resource.id, 'action': user_action })}) }}

我的表单类:

<?php
namespace SFI\MainBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ManageResourceType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
      ->add('name', 'text', array(
        'required' => true,
        'attr' => array(
          'class' => 'form-control',
          'placeholder' => 'Resource name',
        ),
      ))
      ->add('type', 'choice', array(
        'required' => true,
        'empty_value' => 'Choose a type',
        'choices' => array('w' => 'Website', 'v' => 'Video', 'a' => 'Audio'),
        'attr' => array(
          'class' => 'form-control',
        ),
      ))
      ->add('link', 'text', array(
        'required' => true,
        'attr' => array(
          'class' => 'form-control',
          'placeholder' => 'Add a link',
        ),
      ))
      ->add('description', 'textarea', array(
        'required' => true,
        'attr' => array(
          'class' => 'textarea',
          'style' => 'width: 100%; height: 200px; font-size: 14px; line-height: 18px; border: 1px solid #dddddd; padding: 10px;',
          'placeholder' => 'Write a description...',
        ),
      ))
      ->add('save', 'submit', array(
        'attr' => array(
          'class' => 'btn btn-success',
        ),
      ))
      ->add('remove', 'submit', array(
        'attr' => array(
          'class' => 'btn btn-danger',
        ),
      ));

  }

  public function getName()
  {
    return 'modifyResource';
  }

  public function setDefaultOptions(OptionsResolverInterface $resolver)
  {
    $resolver->setDefaults(array(
      'data_class' => 'SFI\MainBundle\Entity\Resource',
    ));
  }
}

我的行动路线:

sfi_teacher_manage_resource:
    path:     /teacher/resource/manage/{action}/{id}
    defaults: { _controller: SFIMainBundle:Teacher:manageResource }

我的控制器操作:

public function manageResourceAction($id, $action, Request $manage_request)
{
  $logger = $this->get('logger');

  $em = $this->getDoctrine()->getManager();

  $managedResource = $em->getRepository('SFIMainBundle:Resource')->find($id);
  $logger->info('Started the manage action');

  $manageResourceForm = $this->createForm(new ManageResourceType(), $managedResource);
  $logger->info('Loaded managedResource into FormType.');

  $manageResourceForm->handleRequest($manage_request);

  if ($manageResourceForm->isValid())
  {

    $logger->info('Form was valid.');

    if ($manageResourceForm->get('save')->isClicked()) {
      $logger->info('Save was clicked, editing resource.');
      $managedResource->setStatus("1");
      $logger->info('Status set to approved.');
      $em->persist($managedResource);
      $logger->info('Resource was persisted.');
    } elseif ($manageResourceForm->get('remove')->isClicked()) {
      $logger->info('Remove / Decline was clicked');
      $em->remove($managedResource);
      $logger->info('Resource removed.');
    }

    $em->flush();
    $logger->info('Flushing...');
    $logger->info("Redirecting to teacher's resources...");
    //return $this->redirect($this->generateUrl('sfi_teacher_resources'));
  }

  return $this->render('SFIMainBundle:Teacher:manageResource.html.twig', array(
    'user_action' => $action,
    'form' => $manageResourceForm->createView(),
  ));
}

如您所见,我必须在一些控制台日志记录中进行烘焙才能确定操作在什么时候停止工作。

如果我将表单作为新标签打开,一切都很好,但不是在模式中。有人向我建议,某些 JavaScript 可能会妨碍提交按钮正常工作,但我不知道从哪里开始调试。

如果您需要更多信息,请告诉我!

编辑 1:根据要求,我将包括我如何定义和创建模式。

在加载资源列表的 resources.html.twig 上,每个实体都有几个这样的链接:

{% if r.status == "0" %}
  <a href="{{ path('sfi_teacher_manage_resource', { 'id': r.id, 'action': 'review' }) }}" data-target="#manageResource" data-toggle="modal" class="btn btn-info bold" id="review"><i class="fa fa-fw fa-check-circle"></i>Review</a>
{% elseif r.status == "1" %}
  <a href="{{ path('sfi_teacher_manage_resource', { 'id': r.id, 'action': 'edit' }) }}" data-target="#manageResource" data-toggle="modal" class="btn btn-info" id="edit"><i class="fa fa-fw fa-edit"></i>Edit</a>
{% endif %}

模态本身是在同一个模板中预先构建的,因为 Symfony 在使用 Bootstrap 模态时要求这样做(我以前使用过模态 un SF,这是我能想到的让它们工作的唯一方法将数据或表单加载到其中时):

<div class="modal fade" id="manageResource" tabindex="-1" role="dialog" aria-labelledby="Manage resource" aria-hidden="true">
 <div class="modal-dialog">
  <div class="modal-content">
   Loading...
  </div>
 </div>
</div>

一旦对象被检索并加载到表单中,modal-content 将被替换为 ma​​nageResources.html.twig 的内容:

{{ form_start(form) }}
<div class="modal-header">
  <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  <h4 class="modal-title" id="myModalLabel">Manage resource</h4>
</div>
<div class="modal-body">
  {{ form_errors(form) }}
  <div class="form-group">
    {{ form_errors(form.name) }}
    {{ form_widget(form.name) }}
  </div>
  <div class="form-group">
    {{ form_errors(form.type) }}
    {{ form_widget(form.type) }}
  </div>
  <div class="form-group">
    {{ form_errors(form.link) }}
    {{ form_widget(form.link) }}
  </div>
    {{ form_errors(form.description) }}
    {{ form_widget(form.description) }}
</div>
<div class="modal-footer">
  <div class="pull-left">
    {% if user_action == "review" %}
    {{ form_widget(form.save, { 'label': 'Approve' }) }}
  {{ form_widget(form.remove, { 'label': 'Decline' }) }}
    {% elseif user_action == "edit" %}
    {{ form_widget(form.save, { 'label': 'Save' }) }}
    {{ form_widget(form.remove, { 'label': 'Remove' }) }}
    {% endif %}
  </div>
  <div class="pull-right">
    <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
  </div>
</div>
{{ form_end(form) }}

这大约涵盖了此操作中涉及的所有代码。

【问题讨论】:

  • manageResource.html.twig 是什么样的?你如何构建模态?
  • 我会将此信息添加到我最初的问题中,因为它需要一些代码,而我无法将其全部放在此处。

标签: jquery forms twitter-bootstrap symfony


【解决方案1】:

感谢您发布您的模板代码,我会尽快仔细查看。 一个想法:我会尝试在 ma​​nageResources.html.twig 中明确设置表单的操作 尝试这样的事情(使用正确的参数进行调整):

{{ form_start(form, {'action': path('sfi_teacher_manage_resource', { 'id': resource.id, 'action': user_action })}) }}

【讨论】:

  • 那里似乎有一个标点符号错误,就像第一个冒号一样,但我没有尝试过。另外,我真的需要将我的变量与操作一起传回吗?这是因为我期待它们出现在我的控制器中吗?
  • 感谢 paulgv,这是我最终使用的语法,它可以正常工作。您的提案存在封装问题,但这有效:{{ form_start(form, {'action': path('sfi_teacher_manage_resource', { 'id': resource.id, 'action': user_action })}) }}。再次感谢您!
  • 嘿抱歉!感谢您的编辑,我已经开始忘记 Twig 是如何工作的 :D 很高兴知道您解决了问题 :)
  • 如果你没有指出正确的方向,我不会有。再次感谢!附言当心一桶啤酒掉在你附近哈哈,这让我疯了好几天。
猜你喜欢
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 2023-03-28
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多