2012-08-01 17 views
6

mam todolist gdzie mogę wyświetlać trzy formy typu zadaniaJak przesłać wiele form tego samego typu za pomocą jednego przycisku w Symfony2

$task1 = new Task(); 
$form1 = $this->createForm(new MyForm('f1'), $task1); 

$task2 = new Task('fo'); 
$form2 = $this->createForm(new MyForm('f2'), $task2); 

$task3 = new Task(); 
$form3 = $this->createForm(new MyForm('f3'), $task3); 

Teraz jest problem mam tylko jeden przycisk wysyłania. Jak mogę utrzymać te trzy zadania w jednym kontrolerze. a użytkownik może również dynamicznie dodawać kolejne formularze.

więc co sposobem rozwiązania tego

+0

warto pomyśleć o użyciu 'jQuery 'do takich zadań. Pozwala na składanie wszystkich formularzy. –

+0

Kup to, co ma jquery do czynienia z doktryną i upieranie się. Czy możesz podać mi link, dzięki któremu mogę zobaczyć, co masz na myśli – user825904

Odpowiedz

5

Tworzenie Form Model Class - jak TaskList - która przechowuje zbiór Task s. Następnie utwórz TaskListType, który ma s. W ten sposób będziesz miał jedną formę z tylu zadań, ile chcesz.

5

Aby uzyskać kompletność, znajdź poniżej pełny przykład.

Powinieneś utworzyć nowy Model, który reprezentuje żądany formularz. Chodzi o to, że prawdopodobnie nie chcesz wpływać na Doctrine (np. Zobacz doktrynę: polecenie schema: update). Może spróbować utworzyć tabelę dla istoty, która tak naprawdę nie istnieje. Aby tego uniknąć, wystarczy umieścić klasę modelu w folderze Model (\ src \ Acme \ Bundle \ DemoBundle \ Model \ TaskList.php).

Załóżmy, że po to TaskType klasa forma:

<?php 

namespace Acme\Bundle\DemoBundle\Form; 

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

class TaskType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('id', null, array('read_only' => true)) 
      ->add('name'); 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(
      array(
       'data_class' => 'Acme\Bundle\DemoBundle\Entity\Task' 
      ) 
     ); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'acme_demo_task'; 
    } 
} 

powinno to być tasklist klasa model:

<?php 

namespace Acme\Bundle\DemoBundle\Model; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* Class TaskList 
* @package Acme\Bundle\DemoBundle\Model 
* 
* @ORM\Entity() 
*/ 
class TaskList 
{ 
    /** 
    * @var \Doctrine\Common\Collections\ArrayCollection 
    * @ORM\ManyToMany(targetEntity="\Acme\Bundle\DemoBundle\Entity\Task") 
    */ 
    private $tasks; 

    public function __construct() 
    { 
     $this->tasks = new ArrayCollection(); 
    } 

    /** 
    * @param \Acme\Bundle\DemoBundle\Entity\Task $task 
    * @return $this 
    */ 
    public function addTask(\Acme\Bundle\DemoBundle\Entity\Task $task) 
    { 
     $this->tasks[] = $task; 

     return $this; 
    } 

    /** 
    * @param \Acme\Bundle\DemoBundle\Entity\Task $task 
    * @return $this 
    */ 
    public function removeTask(\Acme\Bundle\DemoBundle\Entity\Task $task) 
    { 
     $this->tasks->remove($task); 

     return $this; 
    } 

    /** 
    * @return ArrayCollection 
    */ 
    public function getTasks() 
    { 
     return $this->tasks; 
    } 

    /** 
    * @param \Doctrine\Common\Collections\Collection $tasks 
    * @return $this 
    */ 
    public function setTasks(\Doctrine\Common\Collections\Collection $tasks) 
    { 
     $this->tasks = $tasks; 

     return $this; 
    } 

    /** 
    * @param \Knp\Component\Pager\Pagination\PaginationInterface $pagination 
    * @return $this 
    */ 
    public function setFromPagination(\Knp\Component\Pager\Pagination\PaginationInterface $pagination) 
    { 
     foreach ($pagination as $task) { 
      $this->addTask($task); 
     } 

     return $this; 
    } 
} 

I znaleźć poniżej klasy TaskListType:

<?php 

namespace Acme\Bundle\DemoBundle\Form; 

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

class TaskListType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add(
       'tasks', 
       'collection', 
       array(
        'type' => new \Acme\Bundle\DemoBundle\Form\TaskType(), 
       ) 
      ) 
      ->add('save', 'submit'); 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(
      array(
       'data_class' => 'Acme\Bundle\DemoBundle\Model\TaskList' 
      ) 
     ); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'acme_demo_task_list'; 
    } 
} 

I twoje services.yml (opcjonalnie):

services: 
    acme.demo.form.type.task_list: 
     class: Acme\Bundle\DemoBundle\Form\TaskListType 
     tags: 
      - { name: form.type, alias: acme_demo_task_list } 

i sterownik próbki:

public function indexAction($page) 
{ 
    ini_set('xdebug.max_nesting_level', 300); // this might be useful with deeply nested forms 

    $search = $this->getRequest()->get(
     'search', 
     array(
      'name' => '', 
      'date' => '', 
      'lang' => $this->container->getParameter('acme_core.default_lang') 
     ) 
    ); 

    /** 
    * @var \Doctrine\ORM\EntityManager $em 
    */ 
    $em = $this->getDoctrine()->getManager(); 

    $paginator = $this->get('knp_paginator'); 
    $pagination = $paginator->paginate(
     $em->getRepository('AcmeDemoBundle:Task')->getQueryFilteringByLangNameAndDate(
      $search['lang'], 
      $search['name'], 
      $search['date'] != '' ? new \DateTime($search['date']) : null 
     ), 
     $page, 
     $this->getRequest()->get('elementsPerPage', 10) 
    ); 

    $taskList = new TaskList(); 
    $taskList->setFromPagination($pagination); 

    $form = $this->createForm('acme_demo_task_list', $taskList); // "acme_demo_task_list" has been defined in the services.yml file 
    $form->handleRequest($this->getRequest()); 

    if ($form->isValid()) { 
     foreach ($form->getData() as $task) { 
      $em->merge($task); 
     } 
     $em->flush(); 
    } 

    return $this->render(
     'AcmeDemoBundle:Task:index.html.twig', 
     array(
      'search' => $search, 
      'pagination' => $pagination, 
      'form' => $form->createView() 
     ) 
    ); 
} 

Mam nadzieję, że to pomoże!

4

Podążaliśmy za przykładem pokazanym przez "Francesco Casula" i działało idealnie.

Dla orur celów nie potrzebują paginacji, więc jest to w jaki sposób możemy wypełnić naszą kolekcję (w controller):

$entities = $em->getRepository('AcmeBundle:Stock')->findAll(); 

$stockList = new StockList(); // This is our model, what Francesco called 'TaskList' 

foreach ($entities as $entity) { 
    $stockList->addStock($entity); 
} 

// StockListType() is what Francesco called TaskListType 
$form = $this->createForm(new StockListType(), $stockList, array(
    'action' => $this->generateUrl('stock_take_update'), 
    'method' => 'POST', 
    'attr' => array('class' => 'form-horizontal'), 
)); 

Dla tych, którzy muszą dostosować wyjście zbiorach formy, udało nam aby uzyskać dostęp do podformularza przez iterowanie na {% for form in forms.children.stocks %}. „Zapasy” bycia nazwę pola w naszym formularzu budowniczego (w StockListType):

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add(
      'stocks', 'collection', array(
       'type' => new StockType(), 
      ) 
     ) 
     ->add('submit', 'submit') 
    ; 
} 

To, co skończyło się korzystając z naszego punktu widzenia gałązka:

{{ form_start(forms) }} 
    <table class="table table-stripped table-hover"> 
     <thead> 
      <th>#</th> 
      <th>Name</th> 
      <th>Code</th> 
      <th>Location</th> 
      <th>Total</th> 
      <th>Updated Toal</th> 
     </thead> 
     <tbody> 
      {% set counter = 1 %} 
      {% for form in forms.children.stocks %} 
       <tr> 
        <div class="hidden"> 
         {{ form_widget(form.name) }} 
         {{ form_widget(form.code) }} 
         {{ form_widget(form.location) }} 
         {{ form_widget(form.available) }} 
         {{ form_widget(form.assigned) }} 
         {{ form_widget(form.minLevel) }} 
         {{ form_widget(form.type) }} 
         {{ form_widget(form.colourCode) }} 
        </div> 
        <td>{{ counter }}</td> 
        <td> 
         {% if form.vars.data.name is defined %} 
          {{ form.vars.data.name }} 
         {% endif %} 
        </td> 
        <td> 
         {% if form.vars.data.code is defined %} 
          {{ form.vars.data.code }} 
         {% endif %} 
        </td> 
        <td> 
         {% if form.vars.data.location is defined %} 
          {{ form.vars.data.location }} 
         {% endif %} 
        </td> 
        <td> 
         {% if form.vars.data.total is defined %} 
          {{ form.vars.data.total }} 
         {% endif %} 
        </td> 
        <td>{{ form_widget(form.total) }}</td> 
       </tr> 
       {% set counter = counter + 1 %} 
      {% endfor %} 
     </tbody> 
    </table> 
    {{ form_widget(forms.submit) }} 
{{ form_end(forms) }} 
Powiązane problemy