Reputation: 961
I apologize in advance for a noob question. I just started learning symfony and I ran into a roadblock. I created the RequestForEstimate entity and it may have multiple records associated under the RequestForEstimateDetail entity. Now, Im trying to create a form that not only displays fields from the first entity but also from the second one as well. Symfony doesn't return any errors however it doesn't render the "quantity" field from the RequestForEstimateDetail entity. I used the following tutorial to create this code: How to Embed a Collection of Forms
This is an example of my RequestForEstimate entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimate
*
* @ORM\Table(name="request_for_estimate")
* @ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateRepository")
*/
class RequestForEstimate
{
/**
* @var int
*
* @ORM\Column(name="requestId", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="status", type="integer")
*/
private $status;
/**
* @var \DateTime
*
* @ORM\Column(name="createTime", type="datetime")
*/
private $createTime;
/**
* @var \DateTime
*
* @ORM\Column(name="updateTime", type="datetime")
*/
private $updateTime;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="RequestForEstimateDetail", mappedBy="detail", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $details;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set status
*
* @param integer $status
*
* @return RequestForEstimate
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* @return int
*/
public function getStatus()
{
return $this->status;
}
/**
* Set createTime
*
* @param \DateTime $createTime
*
* @return RequestForEstimate
*/
public function setCreateTime($createTime)
{
$this->createTime = $createTime;
return $this;
}
/**
* Get createTime
*
* @return \DateTime
*/
public function getCreateTime()
{
return $this->createTime;
}
/**
* Set updateTime
*
* @param \DateTime $updateTime
*
* @return RequestForEstimate
*/
public function setUpdateTime($updateTime)
{
$this->updateTime = $updateTime;
return $this;
}
/**
* Get updateTime
*
* @return \DateTime
*/
public function getUpdateTime()
{
return $this->updateTime;
}
/**
* Set name
*
* @param string $name
*
* @return RequestForEstimate
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Constructor
*/
public function __construct()
{
$this->details = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add detail
*
* @param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*
* @return RequestForEstimate
*/
public function addDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details[] = $detail;
return $this;
}
/**
* Remove detail
*
* @param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*/
public function removeDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details->removeElement($detail);
}
/**
* Get details
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getDetails()
{
return $this->details;
}
}
This is my RequestForEstimateDetail entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimateDetail
*
* @ORM\Table(name="request_for_estimate_detail")
* @ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateDetailRepository")
*/
class RequestForEstimateDetail
{
/**
* @var int
*
* @ORM\Column(name="requestDetailId", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="RequestForEstimate", inversedBy="details")
* @ORM\JoinColumn(name="requestId", referencedColumnName="requestId")
*/
private $detail;
/**
* @var int
*
* @ORM\Column(name="productId", type="integer")
*/
private $productId;
/**
* @var int
*
* @ORM\Column(name="quantity", type="integer")
*/
private $quantity;
/**
* @var string
*
* @ORM\Column(name="pricePerUnit", type="decimal", precision=2, scale=0)
*/
private $pricePerUnit;
/**
* @var string
*
* @ORM\Column(name="shippingCost", type="decimal", precision=2, scale=0)
*/
private $shippingCost;
/**
* @var string
*
* @ORM\Column(name="otherFees", type="decimal", precision=2, scale=0)
*/
private $otherFees;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set product
*
* @param integer $product
*
* @return RequestForEstimateDetail
*/
public function setProduct($product)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return int
*/
public function getProduct()
{
return $this->product;
}
/**
* Set quantity
*
* @param integer $quantity
*
* @return RequestForEstimateDetail
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* @return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Set pricePerUnit
*
* @param string $pricePerUnit
*
* @return RequestForEstimateDetail
*/
public function setPricePerUnit($pricePerUnit)
{
$this->pricePerUnit = $pricePerUnit;
return $this;
}
/**
* Get pricePerUnit
*
* @return string
*/
public function getPricePerUnit()
{
return $this->pricePerUnit;
}
/**
* Set shippingCost
*
* @param string $shippingCost
*
* @return RequestForEstimateDetail
*/
public function setShippingCost($shippingCost)
{
$this->shippingCost = $shippingCost;
return $this;
}
/**
* Get shippingCost
*
* @return string
*/
public function getShippingCost()
{
return $this->shippingCost;
}
/**
* Set otherFees
*
* @param string $otherFees
*
* @return RequestForEstimateDetail
*/
public function setOtherFees($otherFees)
{
$this->otherFees = $otherFees;
return $this;
}
/**
* Get otherFees
*
* @return string
*/
public function getOtherFees()
{
return $this->otherFees;
}
/**
* Set requestId
*
* @param \SourcingBundle\Entity\RequestForEstimate $requestId
*
* @return RequestForEstimateDetail
*/
public function setRequestId(\SourcingBundle\Entity\RequestForEstimate $requestId = null)
{
$this->requestId = $requestId;
return $this;
}
/**
* Get requestId
*
* @return \SourcingBundle\Entity\RequestForEstimate
*/
public function getRequestId()
{
return $this->requestId;
}
/**
* Set productId
*
* @param \SourcingBundle\Entity\Product $productId
*
* @return RequestForEstimateDetail
*/
public function setProductId(\SourcingBundle\Entity\Product $productId = null)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* @return \SourcingBundle\Entity\Product
*/
public function getProductId()
{
return $this->productId;
}
/**
* Set detail
*
* @param \SourcingBundle\Entity\RequestForEstimate $detail
*
* @return RequestForEstimateDetail
*/
public function setDetail(\SourcingBundle\Entity\RequestForEstimate $detail = null)
{
$this->detail = $detail;
return $this;
}
/**
* Get detail
*
* @return \SourcingBundle\Entity\RequestForEstimate
*/
public function getDetail()
{
return $this->detail;
}
}
This is my RequestForEstimateController:
<?php
namespace SourcingBundle\Controller;
use SourcingBundle\Entity\RequestForEstimate;
use SourcingBundle\Form\Type\RequestForEstimateType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class RequestForEstimateController extends Controller
{
/**
* @Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
These are my form classes:
RequestForEstimateType.php
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class RequestForEstimateType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('details', CollectionType::class, array(
'entry_type' => RequestForEstimateDetailType::class
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimate',
));
}
}
RequestForEstimateDetailType.php:
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RequestForEstimateDetailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('quantity',TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimateDetail',
));
}
}
Now my view:
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Create Request For Estimate</h5>
</div>
<div class="ibox-content">
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_widget(form) }}
</div>
{{ dump(form.details)}}
{% for detail in form.details %}
<li>{{ form_row(detail.quantity) }}</li>
{% endfor %}
{{ form_end(form) }}
</div>
</div>
</div>
</div>
Upvotes: 1
Views: 208
Reputation: 615
You need to create some RequestForEstimateDetail
entities in your controller class and add it to RequestForEstimate
entity. Like this:
class RequestForEstimateController extends Controller
{
/**
* @Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$detail1 = new RequestForEstimateDetail();
$detail2 = new RequestForEstimateDetail();
$RequestForEstimate->addDetail($detail1);
$RequestForEstimate->addDetail($detail2);
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
PS. U can read this doc http://symfony.com/doc/current/form/form_collections.html it's pretty clear =)
Upvotes: 1