2012-08-01 22 views
6

Tôi có ToDoList nơi tôi hiển thị ba hình thức nhiệm vụ loạiLàm thế nào để gửi nhiều hình thức cùng loại với một nút trong 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); 

Bây giờ vấn đề là tôi có một nút duy nhất nộp. Làm thế nào tôi có thể duy trì ba nhiệm vụ này trong một bộ điều khiển. và người dùng cũng có thể thêm nhiều biểu mẫu động hơn.

vì vậy những gì cách để giải quyết việc này

+0

Bạn nên suy nghĩ về việc sử dụng 'jQuery 'cho các nhiệm vụ như vậy. Nó cho phép bạn gửi tất cả các biểu mẫu. –

+0

Mua những gì có jquery để làm với học thuyết và sự bền bỉ. Bạn có thể cho tôi một số liên kết để tôi có thể thấy ý của bạn – user825904

Trả lời

5

Tạo một lớp Form Model - như TaskList - chứa một bộ sưu tập của Task s. Sau đó, tạo TaskListType giữ một số collection trong số TaskType s. Bằng cách này, bạn sẽ có một biểu mẫu với nhiều tác vụ như bạn muốn.

5

Để tìm hiểu đầy đủ, hãy tìm bên dưới ví dụ hoàn chỉnh.

Bạn nên tạo Mô hình mới đại diện cho biểu mẫu mong muốn. Vấn đề là bạn có thể không muốn ảnh hưởng đến Doctrine (ví dụ: xem doctrine: schema: update command). Nó có thể cố gắng tạo một bảng cho một thực thể không thực sự tồn tại. Để tránh điều đó, chỉ cần đặt lớp mô hình của bạn trong thư mục Model (\ src \ Acme \ Bundle \ DemoBundle \ Model \ TaskList.php).

Giả sử rằng sau đây là TaskType hình thức lớp học của bạn:

<?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'; 
    } 
} 

này nên mô hình lớp tasklist của bạn:

<?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; 
    } 
} 

Và tìm thấy bên dưới lớp 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'; 
    } 
} 

Và services.yml của bạn (tùy chọn):

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

Và một bộ điều khiển mẫu:

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

Tôi hy vọng điều này sẽ giúp!

4

Chúng tôi theo dõi bản exapmle được hiển thị bởi 'Francesco Casula' và nó hoạt động hoàn hảo.

Đối với mục đích orur chúng tôi không cần pagination, vì vậy đây là cách chúng ta điền bộ sưu tập của chúng tôi (trong 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'), 
)); 

Đối với những người cần để tùy chỉnh đầu ra của các bộ sưu tập hình thức, chúng tôi quản lý để truy cập biểu mẫu con bằng cách lặp lại trên {% for form in forms.children.stocks %}. 'Chứng khoán' là tên của lĩnh vực này trong xây dựng mẫu của chúng tôi (trong StockListType):

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

Đây là những gì chúng tôi đã kết thúc sử dụng theo quan điểm của cành lá của chúng tôi:

{{ 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) }} 
Các vấn đề liên quan