5

次のように要約できる問題に直面しています。次のような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 %}

フィールドnamesurname、および addressesは、サンプルの 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();
    }
}

そして DefaultController で:

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 を持つ方法を取りましたが、「hidden」と「property_path」=> false を入れました。これは、目的のフィールドのみをレンダリングできないため、他のフィールドが原因でエラーが発生するためです。 runtime (they're null) ですが、両方のケースを結合して処理する際に問題が発生します。

すべてのフォームを別のページ (== 別のルート) に配置し、別のコントローラーを使用すると、すべてが正常に機能するため、symfony の基本的な使用に関連する問題ではありません。JQuery UI を使用して単一のページに N 個のフォームを統合することです。泣く。

このタブを使用する必要があることを修正しました。どうすれば解決できますか?

  1. すべてを処理する単一のアクションを作成する必要がありますか?
  2. 単一のフォームを作成する必要がありますか?
  3. 私は何かが恋しいですか?

事前に感謝します。私の問題を明確に説明していただければ幸いです。

4

4 に答える 4

0

異なるフォームに同じ変数を使用しました

<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>
于 2012-05-30T09:09:46.027 に答える
0

他の誰かがこの問題を抱えている場合は、次のように解決できます (これが最もエレガントな解決策かどうかはわかりませんが、すべてに対して 1 つの大きなフォームを作成するよりはましだと思います)。この例では、プロファイルと changePassword の FOSUserBundle フォームが混在しています。

メインのショー テンプレート (私の場合は Profile:show.html.twig) 内:

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

changePassword について繰り返します。

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

コントローラーで (else を追加):

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()));
        }

それに応じて profileForm と passwdForm を追加します。私の場合、変更されたコントローラーは ProfileController と ChangePasswordControllers (FOSUserBundle オーバーライド) でした。

タブに関しては、エラーが見つかった場合は、javascript (または twig) を追加してタブを開くことができます。

お役に立てれば :)

于 2013-03-05T04:28:21.433 に答える
0

単一フォームで試す

{% 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 %}

それからあなたはocontrollerにあります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',
        );
    }
}
于 2012-06-01T14:26:15.117 に答える
0

前に述べたように、すべてのタブを単一のフォームにラップすることを解決しました。どちらのソリューションも問題ありません。お時間をいただきありがとうございます。

Linuxatico

于 2012-06-04T18:03:23.933 に答える