2012-05-25 1 views
5

Я столкнулся с проблемой, что я могу резюмировать, как это следующим образом: У меня есть страница TWIG шаблон, как это (reg.html.twig):Symfony2 несколько форм в различных вкладках JQuery UI, но одной страницы

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

Файл Entity:

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 имеет все поля, которые мне не нужны, но поместил «hidden» и «property_path» => false, потому что я не могу отображать только мои желаемые поля, потому что другие будут вызывают ошибки во время выполнения (они равны нулю), но у меня все еще возникают проблемы с обработкой обоих случаев в объединенной форме.

Помещение каждой формы на другую страницу (== другой маршрут), с разными контроллерами, все работает отлично, поэтому это не проблема, связанная с основным использованием symfony. Это интеграция N форм на одной странице с помощью JQuery Пользовательский интерфейс, который заставляет меня плакать.

Исправлено, что я должен использовать эти вкладки, как я могу решить?

  1. Должен ли я сделать одно действие, обрабатывающее все?
  2. Должен ли я создать единую форму?
  3. Я что-то пропустил?

Заранее спасибо, я надеюсь, что я ясно объяснил свою проблему.

+0

Мне больше не нужна эта информация, я помещаю каждую вкладку в тег одной формы – linuxatico

ответ

0

Как я уже говорил, я решил обернуть все вкладки в одной форме. Оба ваших решения в порядке, спасибо за ваше время.

Linuxatico

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> 
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', 
     ); 
    } 
} 
0

В случае, если кто-то имеет эту проблему, вы можете решить, как это (я не уверен, если это самое элегантное решение, но я думаю, что его лучше, чем сделать одну большую форму для всего). Этот пример смешивает профиль и Changepassword FOSUserBundle формы:

Внутри основного шоу шаблона (профиль: show.html.twig в моем случае):

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

Repeat для Changepassword:

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

Добавить профильForm и passwdForm соответственно. В моем случае модифицированными контроллерами были ProfileController и ChangePasswordControllers (FOSUserBundle переопределяет).

Что касается ваших вкладок, вы можете добавить javascript (или twig), чтобы открыть вкладку, если обнаружена какая-либо ошибка.

Надеюсь, что это поможет :)