T
T
Think With Your Head2016-08-30 02:08:35
symfony
Think With Your Head, 2016-08-30 02:08:35

Why fields are not rendered when using form collection in symfony?

There are two entities - user and company.

the code:

Entity User
<?php

namespace TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="TestBundle\Repository\UserRepository")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

    /**
     * @ORM\OneToMany(targetEntity="Company", mappedBy="user")
     */
    private $companies;

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

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

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

        return $this;
    }

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

    /**
     * Set email
     *
     * @param string $email
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

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

    /**
     * Add companies
     *
     * @param \TestBundle\Entity\Company $companies
     * @return User
     */
    public function addCompany(\TestBundle\Entity\Company $companies)
    {
        $this->companies[] = $companies;

        return $this;
    }

    /**
     * Remove companies
     *
     * @param \TestBundle\Entity\Company $companies
     */
    public function removeCompany(\TestBundle\Entity\Company $companies)
    {
        $this->companies->removeElement($companies);
    }

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

Company entity
<?php

namespace TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Company
 *
 * @ORM\Table(name="company")
 * @ORM\Entity(repositoryClass="TestBundle\Repository\CompanyRepository")
 */
class Company
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="companies")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

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

    /**
     * Set companyName
     *
     * @param string $companyName
     * @return Company
     */
    public function setCompanyName($companyName)
    {
        $this->companyName = $companyName;

        return $this;
    }

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

    /**
     * Set yearFinished
     *
     * @param \DateTime $yearFinished
     * @return Company
     */
    public function setYearFinished($yearFinished)
    {
        $this->yearFinished = $yearFinished;

        return $this;
    }

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

    /**
     * Set user
     *
     * @param \TestBundle\Entity\User $user
     * @return Company
     */
    public function setUser(\TestBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \TestBundle\Entity\User 
     */
    public function getUser()
    {
        return $this->user;
    }
}

Formbuilders respectively
<?php 


namespace TestBundle\Form\Type;

use TestBundle\Entity\Company;

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

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');
        $builder->add('email');

        $builder->add('companies', 'collection', array(
            'type' => new CompanyType(),
            'allow_add' => true,
//                'delete_empty' => true,
               'prototype' => true,
//                'allow_delete' => true,
            'by_reference' => false,
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TestBundle\Entity\User',
        ));
    }


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


<?php 


namespace TestBundle\Form\Type;

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


class CompanyType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('companyName');
        $builder->add('yearFinished');

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TestBundle\Entity\Company',
        ));
    }

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

Controller:
<?php

namespace TestBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

use TestBundle\Form\Type\UserType;
use TestBundle\Entity\User;
use TestBundle\Entity\Company;

class DefaultController extends Controller
{

    /**
     * @Route("/")
     */
    public function indexAction(Request $request)
    {   

        $user = new User();

        $form = $this->createForm(new UserType(), $user);

        return $this->render('TestBundle:Default:index.html.twig', array(
          'form' => $form->createView(),
        ));
    }
}

Sample
{{ form_start(form) }}
{{ form_widget(form) }}

<input type="submit">
{{ form_end(form) }}


As planned, the result should be a form in which there are two fields of the User entity (name, email) and two fields of the Company entity (companyName, yearFinished)
But the result is this:
3246d5927cb3429986ad961b678e4e0d.png
Where did I miss?
PS: on stackoverflow, I found a crutch referring to the official documentation symfony.com/doc/current/form/form_collections.html...
The essence of which is to take data from the prototype (that very subform of the entity) through jQuery and add it to the DOM. I don't think this is a good solution

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander, 2016-09-08
@neokortex

Well, either in your case it is more correct to use EntityType instead of collection

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question