Symfony2在不同的JQuery UI选项卡中使用多个表单,但单个页面


Symfony2 multiple forms in different JQuery UI tabs but single page

我遇到了一个问题,我可以总结如下:我有一个这样的TWIG模板页面(reg.html.twig):

{% extends "::base.html.twig" %}
{% block body %}
<ul class="tabs">
    <li class="left"><a href="#tab1">tab1</a></li>
    <li class="left"><a href="#tab2">tab2</a></li>
    <li class="left"><a href="#tab3">tab3</a></li>
    <li class="right"><a href="#tab4">tab4</a></li>
</ul>
<div class="tabs_container">
    <div id="tab1" class="blocco-tab">
        <form action="{{ path('AAA') }}" method="post" {{ form_enctype(form) }}>
            <div id="name_field">
                {{ form_row(form.name) }}
            </div><!-- /name_field -->
            <div id="address">
                 {{ form_row(form.addresses[0].road) }}
            </div><!-- /address_field -->
        </form>
    </div>
    <div id="tab2" class="blocco-tab">
        <form action="{{ path('BBB') }}" method="post" {{ form_enctype(form) }}>
            <div id="surname_field">
                {{ form_row(form.surname) }}
            </div><!-- /surname_field -->
        </form>
    </div>
</div> <!-- contenitore_tabs -->
{% endblock %}

字段名称姓氏地址属于示例Symfony2实体Person。地址是地址集合的第一个也是唯一的元素(出于其他原因,我需要将其作为集合)

工作JS文件是:

jQuery(document).ready(function() {
    $(".blocco-tab").hide();
    $("ul.tabs li:first").addClass("active").show();
    $(".blocco-tab:first").show();
    $("ul.tabs li").click(function() {
        $("ul.tabs li").removeClass("active");
        $(this).addClass("active");
        $(".blocco-tab").hide();
        var activeTab = $(this).find("a").attr("href");
        $(activeTab).fadeIn();
        return false;
    });
});

实体文件:

class Person {
    protected $name;
    protected $surname;
    protected $addresses;
    public function __construct(){
        $this->addresses = new ArrayCollection();
    }
}

在默认控制器中:

public function tab1Action(Request $request){
    $person = new Person();
    $address = new Address();
    $addr_coll = new ArrayCollection();
    $addr_coll->add($address);
    $tab1_type = new Tab1Type();
    $person->setAddresses($addr_coll);
    $form = $this->createForm($tab1_type, $person);
    if ($request->getMethod() == 'POST')
    {
        $form->bindRequest($request);
        if ($form->isValid())
    /*ecc ecc ecc*/
}
public function tab2Action(Request $request){
    $person = new Person();
    $tab2_type = new Tab2Type();
    $form = $this->createForm($tab2_type, $person);
    if ($request->getMethod() == 'POST')
    {
        $form->bindRequest($request);
        if ($form->isValid())
    /*ecc ecc ecc*/
}

实际上,我的做法是让每个 FormType 都具有我不需要渲染的所有字段,但将"隐藏"和"property_path"=> false,因为我不能只渲染我想要的字段,因为其他字段会导致运行时错误(它们是空的),但我仍然在以连接方式处理这两种情况时遇到问题。

将每个表单放在不同的页面(==不同的路由)中,使用不同的控制器,一切正常,所以这不是与symfony的基本使用有关的问题,而是将N个表单集成到一个页面中与JQuery UI让我哭泣。

修复了我必须使用此选项卡的问题,如何解决?

  1. 我是否必须执行一个操作来处理所有内容?
  2. 我必须制作一个表格吗?
  3. 我错过了什么吗?

提前感谢,我希望我已经清楚地解释了我的问题。

您只是对不同的表单使用相同的变量

<div id="tab1" class="blocco-tab">
    <form action="{{ path('AAA') }}" method="post" {{ form_enctype(**form1**) }}>
        <div id="name_field">
            {{ form_row(**form1**.name) }}
        </div><!-- /name_field -->
        <div id="address">
             {{ form_row(**form1**.addresses[0].road) }}
        </div><!-- /address_field -->
    </form>
</div>
<div id="tab2" class="blocco-tab">
    <form action="{{ path('BBB') }}" method="post" {{ form_enctype(**form2**) }}>
        <div id="surname_field">
            {{ form_row(**form2**.surname) }}
        </div><!-- /surname_field -->
    </form>
</div>

尝试使用单个表单

{% extends "::base.html.twig" %}
{% block body %}
<form action="{{ path('AAA') }}" method="post" {{ form_enctype(form) }}>
<ul class="tabs">
    <li class="left"><a href="#tab1">tab1</a></li>
    <li class="left"><a href="#tab2">tab2</a></li>
    <li class="left"><a href="#tab3">tab3</a></li>
    <li class="right"><a href="#tab4">tab4</a></li>
</ul>
<div class="tabs_container">
    <div id="tab1" class="blocco-tab">
            <div id="name_field">
                {{ form_row(form.name) }}
            </div><!-- /name_field -->
            <div id="address">
                 {{ form_row(form.addresses[0].road) }}
            </div><!-- /address_field -->
    </div>
    <div id="tab2" class="blocco-tab">
            <div id="surname_field">
                {{ form_row(form.surname) }}
            </div><!-- /surname_field -->
    </div>
</div> <!-- contenitore_tabs -->
 </form>
{% endblock %}

然后你就有了控制器aaaAction()

public function aaaAction(Request $request){
    $person = new Person();
    $address = new Address();
    $addr_coll = new ArrayCollection();
    $addr_coll->add($address);
    $person->setAddresses($addr_coll);
    $form = $this->createForm(new PersonType(), $person);
    if ($request->getMethod() == 'POST')
    {
        $form->bindRequest($request);
        if ($form->isValid())
    /*ecc ecc ecc*/
}

和表单构建器的类,例如

class PersonType extends AbstractType {
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
                ->add('name', null, array())
                ->add('surname', null, array())
                ->add('addresses', null, array())
        ;
    }
    public function getName()
    {
        return 'person';
    }
    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'Acme'YourBundle'Entity'Person',
        );
    }
}

正如我在解决将所有选项卡包装在一个表单中之前提到的。您的两个解决方案都可以,感谢您的时间。

Linuxatico

如果其他人有这个问题,你可以这样解决(我不确定这是否是最优雅的解决方案,但我认为它比为所有内容制作一个大形式要好)。此示例混合了配置文件和更改密码 FOSUserBundle 表单:

在您的主节目模板中(在我的情况下是个人资料:显示.html.twig):

        {% if profileForm is defined %}
            {% include 'MyBundle:Profile:edit.html.twig' with {'form':profileForm} %}
        {% else %}
            {% render 'MyBundle:Profile:edit' %}
        {% endif %}

对更改密码重复此操作:

        {% if passwdForm is defined %}
            {% include 'MyBundle:ChangePassword:changePassword.html.twig' with {'form':passwdForm} %}
        {% else %}
            {% render 'FOSUserBundle:ChangePassword:changePassword' %}
        {% endif %}

在控制器中(添加其他):

if ($form->isValid()) {
    .....
else {
    return $this->container->get('templating')->renderResponse('FOSUserBundle:Profile:show.html.'.$this->container->getParameter('fos_user.template.engine'),
                     array('user' => $user, 'profileForm' => $form->createView()));
        }

相应地添加配置文件窗体和传递窗体。在我的例子中,修改后的控制器是ProfileController 和 ChangePasswordControllers(FOSUserBundle overrides)。

至于您的选项卡,您可以添加javascript(或twig)以在发现任何错误时打开选项卡。

希望这对:)有所帮助