Symfony2 自定义表单。小姐的想法

Symfony2 Custom Form. Miss ideas

我有两个实体如下:

成员(名字,名字):OneToMany -> 订阅

订阅 ( numberOfMounth ) : ( ManyToOne -> 成员)

我想创建一个表单来加载成员列表。 对于每个成员,我可以选择订阅月数 (numberOfMounth)。 每个成员前都有一个复选框,以 select 只有那些准备好订阅的人。最后是一个记录一切的按钮。

我首先通过添加字段集合(订阅)来创建表单。 但是我想知道是否要为这个表单创建一个新的实体。

其实我想念点子。

我的实体和表单:

<?php

namespace Jack\AikidoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Jack\AikidoBundle\Member
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Jack\AikidoBundle\Entity\MemberRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Member
{

    /**
    * @var integer $id
    *
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    private $id;

    /**
    * @var string $name
    *
    * @ORM\Column(name="member_name", type="string", length=255)
    */
    private $name;

    /**
    * @var string $firstname
    *
    * @ORM\Column(name="member_firstname", type="string", length=255)
    */
    private $firstname;


    /**
     * @ORM\OneToMany(targetEntity="Jack\AikidoBundle\Entity\Subscription", mappedBy="member", cascade={"persist", "remove"})
     */
    protected $subscriptions;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->subscriptions = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Member
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set firstname
     *
     * @param string $firstname
     * @return Member
     */
    public function setFirstname($firstname)
    {
        $this->firstname = $firstname;

        return $this;
    }

    /**
     * Get firstname
     *
     * @return string 
     */
    public function getFirstname()
    {
        return $this->firstname;
    }



    /**
     * Add subscriptions
     *
     * @param \Jack\AikidoBundle\Entity\Subscription $subscriptions
     * @return Member
     */
    public function addSubscription(\Jack\AikidoBundle\Entity\Subscription $subscriptions)
    {
        $this->subscriptions[] = $subscriptions;

        return $this;
    }

    /**
     * Remove subscriptions
     *
     * @param \Jack\AikidoBundle\Entity\Subscription $subscriptions
     */
    public function removeSubscription(\Jack\AikidoBundle\Entity\Subscription $subscriptions)
    {
        $this->subscriptions->removeElement($subscriptions);
    }

    /**
     * Get subscriptions
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSubscriptions()
    {
        return $this->subscriptions;
    }
}

<?php

namespace Jack\AikidoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Jack\AikidoBundle\Subscription
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Jack\AikidoBundle\Entity\SubscriptionRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Subscription
{
    /**
     * @ORM\ManyToOne(targetEntity="Jack\AikidoBundle\Entity\Member", inversedBy="subscriptions")
     * @ORM\JoinColumn(name="member_id", referencedColumnName="id")
     */
    protected $member;
   /**
    * @var integer $id
    *
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    private $id;


    /**
    * @var datetime $date
    *
    * @ORM\Column(name="date", type="datetime")
    */
      private $date;

    /**
    * @var integer $nbMonth
    *
    * @ORM\Column(name="nbMonth", type="integer")
    */
    private $nbMonth;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }



    /**
     * Set date
     *
     * @param \DateTime $date
     * @return Subscription
     */
    public function setDate($date)
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Get date
     *
     * @return \DateTime 
     */
    public function getDate()
    {
        return $this->date;
    }

    /**
     * Set nbMonth
     *
     * @param integer $nbMonth
     * @return Subscription
     */
    public function setNbMonth($nbMonth)
    {
        $this->nbMonth = $nbMonth;

        return $this;
    }

    /**
     * Get nbMonth
     *
     * @return integer 
     */
    public function getNbMonth()
    {
        return $this->nbMonth;
    }

    /**
     * Set member
     *
     * @param \Jack\AikidoBundle\Entity\Member $member
     * @return Subscription
     */
    public function setMember(\Jack\AikidoBundle\Entity\Member $member)
    {
        $this->member = $member;

        return $this;
    }

    /**
     * Get member
     *
     * @return \Jack\AikidoBundle\Entity\Member 
     */
    public function getMember()
    {
        return $this->member;
    }


}

<?php

namespace Jack\AikidoBundle\Form;

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

class SubscriptionType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('date')
            ->add('nbMonth')

            ->add('member', 'entity', array(
                'class' => 'JackAikidoBundle:Member',
                'property' => 'name',
                'multiple' => true,
                'expanded' => true,
            ))                 
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Jack\AikidoBundle\Entity\Subscription'
        ));
    }

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

新更新:我的控制器和视图

public function subscriptionAction()
{    
    $entity = new Subscription();

    $repository = $this->getDoctrine()
                       ->getRepository('JackAikidoBundle:Member');

    $members = $repository->findAll();

    $formBuilderPratSub = $this->createFormBuilder();

    //Make a loop for each $member
    foreach($members as $member)
    {
        $formBuilder = $this->get('form.factory')->createNamedBuilder(
                $member->getId(), 
                new SubscriptionType(), 
                $entity
                );
        $formBuilderPratSub->add($formBuilder);
    }
    //Create the form

    $form = $formBuilderPratSub->getForm();
    $form->add('submit', 'submit', array('label' => 'Create'));

    return $this->render('JackAikidoBundle:Aikido:souscription.html.twig', 
        array(
            'entity' => $entity,
            'forms'   => $form->createView(),
            'members' => $members,
    ));

}

我的观点:

    <table class="table">
        <thead>
            <tr>
                <th>Member ID</th>
                <th>Name</th>
                <th>Firstname</th>
                <th>Nb Month</th>
            </tr>
        </thead>
        <tbody>
            {% for member in members %}
                {% for form in forms %}
                    <tr>
                        <td>{{ member.id }}</td>
                        <td>{{ member.nom }}</td>
                        <td>{{ member.prenom }}</td>
                        <td>{{ form_row(form.nbMonth)}}</td>
                    </tr>

                {% endfor %}

            {% endfor %}
        </tbody>
    </table>
   <div>{{ form_row(forms.submit) }}</div> 

错误:

Method "nbMonth" for object "Symfony\Component\Form\FormView" does not exist in JackAikidoBundle:Aikido:souscription.html.twig at line 25 

这一行是:<td>{{ form_row(form.nbMonth)}}</td>

我尝试:{{ form(forms)}} 只显示表格:

我尝试了一些我认为不是好的方法:

在控制器中:

public function subscriptionAction(Request $request)
{    
    $repository = $this->getDoctrine()->getRepository('JackAikidoBundle:Member');
    $members = $repository->findAll();
    $em = $this->getDoctrine()->getManager();

    if ($request->getMethod() == 'POST') {
        $nbMonth = $this->getRequest()->get('nbMonth');
        $selectedMembers = $this->getRequest()->get('selectedMembers');

        for($i =0; $i < count($selectedMembers); $i++){
            $subscription = new Subscription();
            $subscription->setMonth((int)$nbMonth[$i]);
            $member = $repository->find($selectedMembers[$i]);
            $subscription->setMember($member);
            $em->persist($subscription);
        }
        $em->flush();

    } 
    return $this->render('JackAikidoBundle:Aikido:subscription.html.twig', 
        array(
            'members' => $members,
    ));  
}

在视图中:

<form  action='{{path('jack_aikido_subscription')}}' method="post">
    <table class="table table-bordered table-striped table-primary list-table">
        <thead>
            <tr>
                <th>Select</th>
                <th>Name</th>
                <th>Firstname</th>
                <th>Nb Month</th>
            </tr>
        </thead>
        <tbody>
            {% for member in members %}               
                    <tr>
                        <td>
                            <input type="checkbox"  name="selectedMembers[]" value="{{ member.id }}">
                        </td>
                        <td>{{ member.name }}</td>
                        <td>{{ member.firstname }}</td>
                        <td>
                            <select name="nbMonth[]">
                                <option value="0">Select</option>
                            {% for i in 1..12 %}
                                <option value="{{ i }}">{{ i }} month</option>
                            {% endfor %}    
                            </select>
                        </td>
                    </tr>
            {% endfor %}
        </tbody>
    </table>
    <input type="submit" name="save">    
</form> 

有效,但我仍在等待最佳答案。