i want to edit my Category entity based on Test ID in the form in Twig and bind it to database,
when i open my edit it displays me the forms i edit them but they don't bind the id test from database , i can't understand why, may be something i wrote wrong :(
my controller :
class DefaultController extends Controller
{
function editAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$test = $em->getRepository('LadelaOdeskTesterBundle:Test')->find($id);
if (!$test) {
throw $this->createNotFoundException('Unable to find Advertiser entity.');
}
return array(
'test' => $test,
);
}
/**
* #Route("/new/{id}/update", name="test.update", requirements={"id" = "\d+"})
* #Method("Post")
* #Template("LadelaOdeskTesterBundle:Default:edit.html.twig")
*/
public function updateAction($id)
{
$test =
$this->getDoctrine()->getRepository('LadelaOdeskTesterBundle:Test')->find($id);
if (!$test) {
throw $this->createNotFoundException('Unable to find Test entity.');
}
$success = 0;
$categoryList = array_map('trim', $this->getRequest()->get('category-new'));
$currentCats = $test->getCategories();
foreach ($currentCats as $current){
$test->removeCategorie($current);
}
$em = $this->getDoctrine()->getEntityManager();
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$test->addCategorie($categoryName);
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
}
}
$em->flush();
return $this->redirect($this->generateUrl('test.edit',array('id' => $id)));
return array(
'test' => $test,
);
}
}
my twig file :
{% extends '::base.html.twig' %}
{% block body %}
{#<div class="wrap">#}
<ul id="breadcrumb">
<li><a href="{{path('homepage')}}" title="Home"><img src="{{ \
asset('bundles/ladelaodesktester/images/home.png') }}" alt="Home" class="home"
/></a> </li>
<li> Please add data to new test </li>
</ul>
<h2>Edit Test </h2>
{% for test in tests %}
<form action="{{ path('test.update',{'id': test.id }) }}" method="post">
Category 1<input type="text" name="category-new[]" >
<div id="customWidget">
<div id="colorSelector1"><div style="background-color: #00ff00"></div>
</div>
<div id="colorpickerHolder1"></div>
</div>
Category 2<input type="text" name="category-new[]" ><br>
Category 3<input type="text" name="category-new[]" ><br>
Category 4<input type="text" name="category-new[]" ><br>
Category 5<input type="text" name="category-new[]" ><br>
Category 6<input type="text" name="category-new[]" ><br>
Category 7<input type="text" name="category-new[]" ><br>
Category 8<input type="text" name="category-new[]" ><br>
Category 9<input type="text" name="category-new[]" ><br>
<input type="submit" value="Add">
</form>
{% endfor %}
</div>
Back to Test
{#</div>#}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/ladelaodesktester/js/new.js') }}"
type="text/javascript"></script>
<script src="{{ asset('bundles/ladelaodesktester/js/colorpicker.js') }}"
type="text/javascript"></script>
{% endblock %}
Category entity:
class Category
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string $color
*
* #ORM\Column(name="color", type="string", length=255)
*/
private $color;
/**
* #var Category category
*
* #ORM\ManyToOne(targetEntity="Test",inversedBy="categories")
* #ORM\JoinColumn(name="test_id", referencedColumnName="id")
*
*/
protected $test;
public function __construct()
{
$this->color = 'rgb(255,255,0)';
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set color
*
* #param string $color
* #return Category
*/
public function setColor($color)
{
$this->color = $color;
return $this;
}
/**
* Get color
*
* #return string
*/
public function getColor()
{
return $this->color;
}
/**
* Set test
*
* #param Ladela\OdeskTesterBundle\Entity\Test $test
* #return Category
*/
public function setTest(\Ladela\OdeskTesterBundle\Entity\Test $test )
{
$this->test = $test;
return $this;
}
/**
* Get test
*
* #return Ladela\OdeskTesterBundle\Entity\Test
*/
public function getTest()
{
return $this->test;
}
}
Test entity:
class Test
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \DateTime $created_at
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(length=128,unique=true)
*/
private $slug;
/**
* #ORM\ManyToMany(targetEntity="Question")
* #ORM\JoinTable(name="test_questions",
* joinColumns={#ORM\JoinColumn(name="test_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="question_id",
referencedColumnName="id")}
* )
* #var Collection $questions
**/
protected $questions;
/**
* #ORM\ManyToMany(targetEntity="Result")
* #ORM\JoinTable(name="test_results",
* joinColumns={#ORM\JoinColumn(name="test_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="result_id",
referencedColumnName="id")}
* )
* #var Collection $results
**/
protected $results;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="test")
*/
private $categories;
/**
* #var \DateTime $updated_at
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updated_at;
public function __construct()
{
$this->questions = new \Doctrine\Common\Collections\ArrayCollection();
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Test
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getSlug()
{
return $this->slug;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return Test
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
return $this;
}
/**
* Get created_at
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set updated_at
*
* #param \DateTime $updatedAt
* #return Test
*/
public function setUpdatedAt($updatedAt)
{
$this->updated_at = $updatedAt;
return $this;
}
/**
* Get updated_at
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
*
*/
public function getQuestions()
{
return $this->questions;
}
public function addQuestion( Question $question )
{
$this->questions[] = $question;
}
/**
* Set slug
*
* #param string $slug
* #return Test
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Remove questions
*
* #param Question $questions
*/
public function removeQuestion( Question $questions)
{
$this->questions->removeElement($questions);
}
/**
* Add results
*
* #param Result $results
* #return Test
*/
public function addResult(Result $results)
{
$this->results[] = $results;
return $this;
}
/**
* Remove results
*
* #param Result $results
*/
public function removeResult(Result $results)
{
$this->results->removeElement($results);
}
/**
* Get results
*
* #return Collection
*/
public function getResults()
{
return $this->results;
}
public function countResults()
{
return $this->results->count();
}
public function countQuestions()
{
return $this->questions->count();
}
/**
* Add categories
*
* #param Ladela\OdeskTesterBundle\Entity\Category $categories
* #return Test
*/
public function addCategorie(\Ladela\OdeskTesterBundle\Entity\Category $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* #param Ladela\OdeskTesterBundle\Entity\Category $categories
*/
public function removeCategorie(\Ladela\OdeskTesterBundle\Entity\Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* #return Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
}
in the foreach loop > if you never add the $test to the category object.
add this:
$categoryName->setTest($test);
the foreach loop should look like this:
$em = $this->getDoctrine()->getManager(); // <---- Changed this
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
} else {
$success = 'Test category-new may not be empty';
}
}
$em->flush(); // <---- Changed this
Add this before the foreach loop:
$currentCats = $test->getCategories();
foreach ($currentCats as $current){
$test->removeCategorie($current);
}
FINAL EDIT :
Instead of setting test for the category add the category to test, like this:
$em = $this->getDoctrine()->getManager();
foreach ($categoryList as $category) {
if (!empty($category)) {
$categoryName = new Category();
$categoryName->setName($category);
$categoryName->setTest($test);
$test->addCategorie($categoryName); // <---- This is added
$em->persist($categoryName);
$success = ' Category ' . $category . ' was created';
} else {
$success = 'Test category-new may not be empty';
}
}
$em->flush();
Related
How can I successfully embed a running image upload form inside a classified form with OneToOne relationship ?
first post ever on Stackoverflow so please be gentle (and I'm french ...^^)
I have a Symfony 3.3 project, running great. I use VichUploaderBundle for upload and LiipImagine for rendering. Currently, NO PROBLEM for a single image File upload !
I have an uploadtest page, I show one image file upload form, I upload the file ... it goes throught the controller and everything is fine. File uploaded and moved in directory, page shows new image, with all filters. Great !
My real problem comes when embedding the form inside another form.
I would like to embed my "image form" inside a classified form. I started by creating the field mainImage inside this classified form. The relation from the classified is OneToOne, and of course it has cascade="persist" & "remove".
But on validation, nothing is triggered and I got the following error on the image_name :
--- An exception occurred while executing 'INSERT INTO vehicle_ad (createdAt, updatedAt, published, publishedAt, friendsPriority,
friendsPriorityStart, purchaseDate, sellPrice, currency, odometerType,
currentOdometer, energy, gearbox, mainColor, nickname, description,
creator_id, vehicle_brand_id, vehicle_model_id, main_image_id,
vehicle_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?)' with params ["2018-01-23 17:15:39", "2018-01-23
17:15:39", 0, null, 0, null, null, 2650, "eur", "kilometers", 17340,
null, null, null, null, null, 1, 3, 1, null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Le champ
'main_image_id' ne peut être vide (null)
File is empty, vichuploader namer not triggered ... and I am stuck with it since a few days. I did a lot of research ... so any help will be greatly appreciated.
I try to give my code as clearly as possible. First, what is OK (single image upload) :
Image class
<?php
namespace Gac\MediasBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Image
*
* #ORM\Table(name="image")
* #ORM\Entity(repositoryClass="Gac\MediasBundle\Repository\ImageRepository")
* #Vich\Uploadable
*/
class Image
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* ----------------------------------------------------------------------
--------- Connection with other entities
------------------------------------------------------------------------- */
/**
* #ORM\ManyToOne(targetEntity="Gac\UserBundle\Entity\User", inversedBy="images")
* #ORM\JoinColumn(nullable=false)
*/
private $creator;
/**
* #ORM\ManyToOne(targetEntity="Gac\AdsBundle\Entity\VehicleAd", inversedBy="images")
* #ORM\JoinColumn(nullable=true)
*/
private $vehicleAd;
// -------------------------------------------------------------------------------
/**
* #var string
*
* #ORM\Column(name="imageName", type="string", length=255)
*/
private $imageName;
/**
* #Vich\UploadableField(mapping="users_images", fileNameProperty="imageName")
* #var File
*/
private $imageFile;
/**
* #var \DateTime
*
* #ORM\Column(name="createdAt", type="datetime")
* #Assert\DateTime()
*/
private $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(name="updatedAt", type="datetime")
* #Assert\DateTime()
*/
private $updatedAt;
/**
* #var \DateTime
*
* #ORM\Column(name="hiddenAt", type="datetime", nullable=true)
* #Assert\DateTime()
*/
private $hiddenAt;
public function __construct($thisuser)
{
$this->creator = $thisuser;
$this->createdAt = new \Datetime();
$this->updatedAt = new \Datetime();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set creator
*
* #param \Gac\UserBundle\Entity\User $creator
*
* #return Image
*/
public function setCreator(\Gac\UserBundle\Entity\User $creator)
{
$this->creator = $creator;
return $this;
}
/**
* Get creator
*
* #return \Gac\UserBundle\Entity\User
*/
public function getCreator()
{
return $this->creator;
}
/**
* Set imageName
*
* #param string $imageName
*
* #return Image
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* Get imageName
*
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
// VERY IMPORTANT:
// It is required that at least one field changes if you are using Doctrine,
// otherwise the event listeners won't be called and the file is lost
if ($image) {
$this->updatedAt = new \DateTime();
}
}
/**
* Get imageFile
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
*
* #return Image
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return Image
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set hiddenAt
*
* #param \DateTime $hiddenAt
*
* #return Image
*/
public function setHiddenAt($hiddenAt)
{
$this->hiddenAt = $hiddenAt;
return $this;
}
/**
* Get hiddenAt
*
* #return \DateTime
*/
public function getHiddenAt()
{
return $this->hiddenAt;
}
/**
* Set vehicleAd
*
* #param \Gac\AdsBundle\Entity\VehicleAd $vehicleAd
*
* #return Image
*/
public function setVehicleAd(\Gac\AdsBundle\Entity\VehicleAd $vehicleAd = null)
{
$this->vehicleAd = $vehicleAd;
return $this;
}
/**
* Get vehicleAd
*
* #return \Gac\AdsBundle\Entity\VehicleAd
*/
public function getVehicleAd()
{
return $this->vehicleAd;
}
}
Then the related IMAGE FORM :
<?php
namespace Gac\MediasBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichImageType;
class ImageType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('imageFile', VichImageType::class, [
'label' => false,
'required' => false,
'allow_delete' => false,
]);
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Gac\MediasBundle\Entity\Image'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
//return 'gac_mediasbundle_image';
return 'ImageType';
}
}
And the controller
{% extends 'medias/layout.html.twig' %}
{% block bundle_content %}
<div class="jumbotron text-center">
<h1>Testing user's images UPLOAD</h1>
</div>
<p>-----------------</p>
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form) }}
<button type="submit">Upload</button>
{{ form_end(form) }}
<p>-----------------</p>
{% for picture in pictures %}
<div class="row">
<div class="media">
<div class="media-left media-middle">
<img class="media-object" src="{{ picture.imageName | imagine_filter('tiny_test') }}" alt="{{ 'GearsAndCoffee-'~picture.imageName }}" /><br/>
</div>
<div class="media-body">
<h4 class="media-heading">Filter name :</h4>
<em>tiny_test</em>
</div>
</div>
<div class="media">
<div class="media-left media-middle">
<a href="{{ asset('uploads/images/'~picture.imageName) }}" />
<img class="media-object" src="{{ picture.imageName | imagine_filter('std_display') }}" alt="{{ 'GearsAndCoffee-'~picture.imageName }}" /><br/>
</a>
</div>
<div class="media-body">
<h4 class="media-heading">Filter name :</h4>
<em>std_display</em>
</div>
</div>
<p>
<strong>UPDATE IMAGE</strong>
</p>
<p>
<strong>DELETE IMAGE</strong>
</p>
</div>
<p>-----------------</p>
{% endfor %}
{% endblock bundle_content %}
As an information, the VichUploader Bundle config :
vich_uploader:
db_driver: orm
#templating: true
#twig: true
#form: true
mappings:
users_images:
uri_prefix: '%app.path.users_images%'
upload_destination: '%kernel.root_dir%/../web/uploads/images'
namer: vich_uploader.namer_uniqid
inject_on_load: true
delete_on_update: true
delete_on_remove: true
And now the code of what is NOT RUNNING on my app :
The classified class
<?php
namespace Gac\AdsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* VehicleAd
*
* #ORM\Table(name="vehicle_ad")
* #ORM\Entity(repositoryClass="Gac\AdsBundle\Repository\VehicleAdRepository")
* #ORM\HasLifecycleCallbacks
*/
class VehicleAd
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* ----------------------------------------------------------------------
--------- Connection with other entities
------------------------------------------------------------------------- */
/**
* #ORM\ManyToOne(targetEntity="Gac\UserBundle\Entity\User")
* #ORM\JoinColumn(nullable=false)
*/
private $creator;
/**
* #ORM\ManyToOne(targetEntity="Gac\VehiclesBundle\Entity\VehicleBrand")
* #ORM\JoinColumn(nullable=false)
*/
private $vehicleBrand;
/**
* #ORM\ManyToOne(targetEntity="Gac\VehiclesBundle\Entity\VehicleModel")
* #ORM\JoinColumn(nullable=false)
*/
private $vehicleModel;
/**
* #ORM\OneToOne(targetEntity="Gac\MediasBundle\Entity\Image", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $mainImage;
// -------------------------------------------------------------------------------
// ---------------- General status and dates for the AD -------------
/**
* #var \DateTime
*
* #ORM\Column(name="createdAt", type="datetime")
* #Assert\DateTime()
*/
private $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(name="updatedAt", type="datetime")
* #Assert\DateTime()
*/
private $updatedAt;
// ---------------------- AD main content -----------------------
/**
* #var string
*
* #ORM\Column(name="description", type="text", nullable=true)
* #Assert\Type("string")
*/
private $description;
// ************************* FUNCTIONS ***************************
public function __construct($thisuser)
{
$this->creator = $thisuser;
$this->createdAt = new \Datetime();
$this->updatedAt = new \Datetime();
}
/**
* Change updatedAt field just before ORM update
*
* #ORM\PreUpdate
*/
public function changeUpdatedAt()
{
$this->updatedAt = new \Datetime();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
*
* #return VehicleAd
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return VehicleAd
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set creator
*
* #param \Gac\UserBundle\Entity\User $creator
*
* #return VehicleAd
*/
public function setCreator(\Gac\UserBundle\Entity\User $creator)
{
$this->creator = $creator;
return $this;
}
/**
* Get creator
*
* #return \Gac\UserBundle\Entity\User
*/
public function getCreator()
{
return $this->creator;
}
/**
* Set description
*
* #param string $description
*
* #return VehicleAd
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set vehicleBrand
*
* #param \Gac\VehiclesBundle\Entity\VehicleBrand $vehicleBrand
*
* #return VehicleAd
*/
public function setVehicleBrand(\Gac\VehiclesBundle\Entity\VehicleBrand $vehicleBrand)
{
$this->vehicleBrand = $vehicleBrand;
return $this;
}
/**
* Get vehicleBrand
*
* #return \Gac\VehiclesBundle\Entity\VehicleBrand
*/
public function getVehicleBrand()
{
return $this->vehicleBrand;
}
/**
* Set vehicleModel
*
* #param \Gac\VehiclesBundle\Entity\VehicleModel $vehicleModel
*
* #return VehicleAd
*/
public function setVehicleModel(\Gac\VehiclesBundle\Entity\VehicleModel $vehicleModel)
{
$linkedBrand = $vehicleModel->getModelBrand();
$this->vehicleBrand = $linkedBrand;
$this->vehicleModel = $vehicleModel;
return $this;
}
/**
* Get vehicleModel
*
* #return \Gac\VehiclesBundle\Entity\VehicleModel
*/
public function getVehicleModel()
{
return $this->vehicleModel;
}
/**
* Set mainImage
*
* #param \Gac\MediasBundle\Entity\Image $mainImage
*
* #return VehicleAd
*/
public function setMainImage(\Gac\MediasBundle\Entity\Image $mainImage)
{
$this->mainImage = $mainImage;
return $this;
}
/**
* Get mainImage
*
* #return \Gac\MediasBundle\Entity\Image
*/
public function getMainImage()
{
return $this->mainImage;
}
}
Of course the big one, my Classified Form !
<?php
namespace Gac\AdsBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Gac\MediasBundle\Form\ImageType;
use Gac\VehiclesBundle\Entity\VehicleBrand;
use Gac\VehiclesBundle\Entity\VehicleModel;
class VehicleAdType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$globalDatas = $options['globalDatas'];
$builder->add('vehicleBrand', EntityType::class, array(
'class' => 'GacVehiclesBundle:VehicleBrand',
'choice_label' => 'brandName',
'placeholder' => 'Please select a brand :',
))
->add('vehicleModel', EntityType::class, array(
'class' => 'GacVehiclesBundle:VehicleModel',
'choice_label' => 'modelName',
))
->add('description', TextareaType::class, array('required' => false));
$builder->add('mainImage', ImageType::class);
$formModifier = function (FormInterface $form, VehicleBrand $vehicleBrand = null) {
$models = null === $vehicleBrand ? array() : $vehicleBrand->getVehicleModels();
$form->add('vehicleModel', EntityType::class, array(
'class' => 'GacVehiclesBundle:VehicleModel',
'choice_label' => 'modelName',
'choices' => $models,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be your entity, i.e. Brand
$data = $event->getData();
$formModifier($event->getForm(), $data->getVehicleBrand());
}
);
$builder->get('vehicleBrand')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$vehicleBrand = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $vehicleBrand);
}
);
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Gac\AdsBundle\Entity\VehicleAd',
'globalDatas' => null,
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'gac_adsbundle_vehiclead';
}
}
The classified creation controller
<?php
namespace Gac\AdsBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Gac\MediasBundle\Entity\Image;
use Gac\MediasBundle\Form\ImageType;
use Gac\AdsBundle\Entity\VehicleAd;
use Gac\AdsBundle\Form\VehicleAdType;
use Gac\VehiclesBundle\Entity\Vehicle;
use Gac\VehiclesBundle\Form\VehicleType;
use Gac\VehiclesBundle\Entity\VehicleModel;
use Gac\VehiclesBundle\Entity\VehicleBrand;
class ManageController extends Controller
{
public function sellvehicleAction(Request $request)
{
$this->denyAccessUnlessGranted('ROLE_USER');
$thisuser = $this->get('security.token_storage')->getToken()->getUser();
$em = $this->getDoctrine()->getManager();
// Create new ad and load a "mainImage"
$classified = new VehicleAd($thisuser);
$oneImage = new Image($thisuser);
$classified->setMainImage($oneImage);
$globalDatas = $this->container->get('gac_general.globaldatas'); // Always pass globalDatas VAR to any created form in the application
$form = $this->createForm(VehicleAdType::class, $classified, array(
'globalDatas' => $globalDatas,
));
$form->handleRequest($request);
if ($request->isMethod('POST') && $form->isValid()) {
$em->persist($classified);
$em->flush();
$id = $classified->getId();
return $this->redirectToRoute('gac_ads_previewvehiclead', array('id' => $id));
}
return $this->render('ads/manage/sellvehicle.html.twig', array(
'form' => $form->createView()
));
}
}
And finally the view of my classified form
{% extends 'ads/layout.html.twig' %}
{% block bundle_content %}
<form action="{{ path('gac_ads_sellvehicle') }}" method="post">
<div class="row justify-content-center">
<div class="col-md-8">
{{ form_errors(form) }}
<div class="card mb-3">
<div class="card-body">
<p class="text-primary"><strong>{{ 'mandatory informations'|trans|capitalize }} :</strong></p>
{{ form_row(form.vehicleBrand, {'label': 'Vehicle Brand :'}) }}
{{ form_row(form.vehicleModel, {'label': 'Vehicle Model :'}) }}
</div>
</div>
<div class="card mb-3">
<div class="card-body">
<p class="text-primary">{{ 'image'|trans|capitalize }} :</p>
<div id="toto">
{{ form_row(form.mainImage.imageFile) }}
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-body">
<p class="text-primary">{{ 'other parameters'|trans|capitalize }} ({{ 'optional'|trans }}) :</p>
<p class="text-primary">{{ 'tell us a few words about your vehicle'|trans|capitalize }} ({{ 'optional'|trans }}) :</p>
{{ form_row(form.description, {'label': 'Description :'}) }}
</div>
</div>
</div>
<div class="col-md-4">
<div class="card mb-3">
<div class="card-body">
{{ form_rest(form) }}
</div>
</div>
<button type="submit" class="btn btn-block btn-primary">{{ 'preview your ad'|capitalize }}</button>
</div>
</div>
</form>
{% endblock bundle_content %}
I must say that before asking, I did a lot of searching by myself (tests ...) and tons of google search. I know that there is some tricky stuff with Vich Uploader but I managed everything because ... it works for one file.
So the question is : can you help me make my upload and my form work when embedded in another one ?
Thanks a lot !
Regards
Try to do this in "classified" form: ...add('description', textAreaType::class) ->add('mainImage', ImageType::class); Maybe,using twice FormBuilder instance "$builder" causes problemes. In any case: see here Formulaires Imbriqués. I did so and it works great with embedded forms using vich
I'm trying to get INSERT values from a form into DB, one of my form fields is brand_id which is returning NULL upon submission.
There are two entities having Many to One relationship
Brand
id
name
Model
id
brand_id (FK)
name
image_url
comment
All fields return a value but the brand_id returns NULL
Code and Entitys are as follows:
brand Entity:
<?php
// src/coreBundle/Entity/Brand.php
namespace coreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use coreBundle\Entity\Model;
use Doctrine\Common\Collections\ArrayCollection;
/**
*#ORM\Entity
*#ORM\Table(name="brand")
*/
class brand
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
*#ORM\Column(type="string", length=100)
*/
private $name;
/**
*#ORM\OneToMany(targetEntity="model", mappedBy="brands")
*/
protected $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return brand
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add model
*
* #param \coreBundle\Entity\model $model
*
* #return brand
*/
public function addModel(\coreBundle\Entity\model $model)
{
$this->models[] = $model;
return $this;
}
/**
* Remove model
*
* #param \coreBundle\Entity\model $model
*/
public function removeModel(\coreBundle\Entity\model $model)
{
$this->models->removeElement($model);
}
/**
* Get models
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getModels()
{
return $this->models;
}
}
model Entity :
<?php
// src/coreBundle/Entity/Model.php
namespace coreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use coreBundle\Entity\Brand;
/**
*#ORM\Entity
*#ORM\Table(name="model")
*/
class model
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
*#ORM\Column(type="integer")
*/
public $brand_id;
/**
*#ORM\Column(type="string", length=100)
*/
private $name;
/**
*#ORM\Column(type="string", length=100)
*/
private $image_url;
/**
*#ORM\Column(type="string", length=200)
*/
private $comment;
/**
*#ORM\ManyToOne(targetEntity="brand", inversedBy="models")
*#ORM\JoinColumn(name="brand_id", referencedColumnName="id")
*/
protected $brands;
/**
* #ORM\OneToOne(targetEntity="model_item", mappedBy="models")
*/
private $model_items;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set brandId
*
* #param integer $brandId
*
* #return model
*/
public function setBrandId($brandId)
{
$this->brand_id = $brandId;
return $this;
}
/**
* Get brandId
*
* #return integer
*/
public function getBrandId()
{
return $this->brand_id;
}
/**
* Set name
*
* #param string $name
*
* #return model
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set imageUrl
*
* #param string $imageUrl
*
* #return model
*/
public function setImageUrl($imageUrl)
{
$this->image_url = $imageUrl;
return $this;
}
/**
* Get imageUrl
*
* #return string
*/
public function getImageUrl()
{
return $this->image_url;
}
/**
* Set comment
*
* #param string $comment
*
* #return model
*/
public function setComment($comment)
{
$this->comment = $comment;
return $this;
}
/**
* Get comment
*
* #return string
*/
public function getComment()
{
return $this->comment;
}
/**
* Set brands
*
* #param \coreBundle\Entity\brand $brands
*
* #return model
*/
public function setBrands(\coreBundle\Entity\brand $brands = null)
{
$this->brands = $brands;
return $this;
}
/**
* Get brands
*
* #return \coreBundle\Entity\brand
*/
public function getBrands()
{
return $this->brands;
}
}
My Controller Code:
public function newModelAction(Request $request)
{
$product = $this->getDoctrine()
->getRepository('coreBundle:brand')
->findAll();
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$productId
);
}
$model = new model();
$form = $this->createFormBuilder($model)
->add('brand_id',TextType::class,array('label'=>'Brand Id'))
->add('name',TextType::class,array('label'=>'Model Name'))
->add('comment',TextType::class,array('label'=>'Comments'))
->add('image_url',TextType::class,array('label'=>'Image URL'))
->add('save',SubmitType::class, array('label'=>'Add Model'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($model);
$em->flush();
return $this->render('coreBundle:layouts:newItem.html.twig',
array('form'=>$form->createView(),));
}
// ... do something, like pass the $product object into a template
return $this->render('coreBundle:layouts:newModel.html.twig',
array('form'=>$form->createView(),));
}
Try to remove this:
*#ORM\Column(type="integer")
*/
public $brand_id;
Because you have already the field for brands in this point:
/**
*#ORM\ManyToOne(targetEntity="brand", inversedBy="models")
*#ORM\JoinColumn(name="brand_id", referencedColumnName="id")
*/
protected $brands;
You need also to remove getter and seeter of brandId and remove brand_id from the form and adding this for example:
->add('brand', EntityType::class, array(
// query choices from this entity
'class' => 'AppBundle:Brand',
))
Try this
/**
*#ORM\ManyToOne(targetEntity="brand")
*#ORM\JoinColumn(nullable=false)
*/
protected $brands;
I'm creating a timecard form which has 14 dayslots, one for each day slot.
I have created the entities, controller and formType. In the new action of the controller of the timecard, I create 14 instances of the dayslot and add them to the timecard using the entity function. The form comes up empty - as if the collection is empty. Is there something more I have to do? It seems that the form is not properly bound to the entity collection objects. I have dumped the entity before displaying it seems to be there.
Here is the TimeCard Entity:
<?php
namespace CockpitBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* TCTimeCard
*/
class TCTimeCard
{
/**
* #var integer
*/
private $id;
/**
* #var \DateTime
*/
private $startDate;
/**
* #var \DateTime
*/
private $endDate;
/**
* #var \DateTime
*/
private $approvedDate;
/**
* #var \DateTime
*/
private $processedDate;
/**
* #var \DateTime
*/
private $modifiedDate;
/**
* #var string
*/
private $notes;
/**
* #var \CockpitBundle\Entity\TCStatus
*/
private $status;
/**
* #var \CockpitBundle\Entity\Employee
*/
private $employee;
/**
* #var \CockpitBundle\Entity\Employee
*/
private $approvedBy;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $tcslots;
/**
* #var \DateTime
*/
private $periodBegin;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $tcdayslots;
/**
* Constructor
*/
public function __construct()
{
$this->tcslots = new ArrayCollection();
$this->tcdayslots = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/* Removed some of the getters/setters to save scrolling */
/**
* Set employee
*
* #param \CockpitBundle\Entity\Employee $employee
*
* #return TCTimeCard
*/
public function setEmployee(\CockpitBundle\Entity\Employee $employee = null)
{
$this->employee = $employee;
return $this;
}
/**
* Get employee
*
* #return \CockpitBundle\Entity\Employee
*/
public function getEmployee()
{
return $this->employee;
}
/**
* #ORM\PreUpdate
*/
public function updateModifiedDatetime()
{
// Add your code here
}
/**
* Add tcdayslot
*
* #param \CockpitBundle\Entity\TCDaySlot $tcdayslot
*
* #return TCTimeCard
*/
public function addTcdayslot(\CockpitBundle\Entity\TCDaySlot $tcdayslot)
{
$this->tcdayslots[] = $tcdayslot;
return $this;
}
/**
* Remove tcdayslot
*
* #param \CockpitBundle\Entity\TCDaySlot $tcdayslot
*/
public function removeTcdayslot(\CockpitBundle\Entity\TCDaySlot $tcdayslot)
{
$this->tcdayslots->removeElement($tcdayslot);
}
/**
* Get tcdayslots
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTcdayslots()
{
return $this->tcdayslots;
}
}
Here is the DaySlot entity (TCDaySlot)
<?php
namespace CockpitBundle\Entity;
/**
* TCDaySlot
*/
class TCDaySlot
{
/**
* #var integer
*/
private $id;
/**
* #var \DateTime
*/
private $date;
/**
* #var string
*/
private $reghours;
/**
* #var string
*/
private $othours;
/**
* #var string
*/
private $holidayhours;
/**
* #var string
*/
private $type1hours;
/**
* #var string
*/
private $type2hours;
/**
* #var string
*/
private $type3hours;
/**
* #var string
*/
private $type4hours;
/**
* #var string
*/
private $type5hours;
/**
* #var string
*/
private $note;
/**
* #var \CockpitBundle\Entity\Employee
*/
private $employee;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set date
*
* #param \DateTime $date
*
* #return TCDaySlot
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set reghours
*
* #param string $reghours
*
* #return TCDaySlot
*/
public function setReghours($reghours)
{
$this->reghours = $reghours;
return $this;
}
/**
* Get reghours
*
* #return string
*/
public function getReghours()
{
return $this->reghours;
}
/**
* Set othours
*
* #param string $othours
*
* #return TCDaySlot
*/
public function setOthours($othours)
{
$this->othours = $othours;
return $this;
}
/**
* Get othours
*
* #return string
*/
public function getOthours()
{
return $this->othours;
}
/**
* Set holidayhours
*
* #param string $holidayhours
*
* #return TCDaySlot
*/
public function setHolidayhours($holidayhours)
{
$this->holidayhours = $holidayhours;
return $this;
}
/**
* Get holidayhours
*
* #return string
*/
public function getHolidayhours()
{
return $this->holidayhours;
}
/**
* Set type1hours
*
* #param string $type1hours
*
* #return TCDaySlot
*/
public function setType1hours($type1hours)
{
$this->type1hours = $type1hours;
return $this;
}
/**
* Get type1hours
*
* #return string
*/
public function getType1hours()
{
return $this->type1hours;
}
/**
* Set type2hours
*
* #param string $type2hours
*
* #return TCDaySlot
*/
public function setType2hours($type2hours)
{
$this->type2hours = $type2hours;
return $this;
}
/**
* Get type2hours
*
* #return string
*/
public function getType2hours()
{
return $this->type2hours;
}
/* Again I removed a few getter/setters to minimize size */
/**
* Set note
*
* #param string $note
*
* #return TCDaySlot
*/
public function setNote($note)
{
$this->note = $note;
return $this;
}
/**
* Get note
*
* #return string
*/
public function getNote()
{
return $this->note;
}
/**
* Set employee
*
* #param \CockpitBundle\Entity\Employee $employee
*
* #return TCDaySlot
*/
public function setEmployee(\CockpitBundle\Entity\Employee $employee = null)
{
$this->employee = $employee;
return $this;
}
/**
* Get employee
*
* #return \CockpitBundle\Entity\Employee
*/
public function getEmployee()
{
return $this->employee;
}
}
And here is the controller TCTimeCardController
/**
* Creates a new tCTimeCard entity.
*
* #Route("/new", name="tctimecard_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$tcTimeCard = new TCTimeCard();
$em = $this->getDoctrine()->getManager();
$periodStart = $em->getRepository('CockpitBundle:TCTimeCard')->getBestDate();
$username = $this->getUser()->getUsername();
$employee = $em->getRepository('CockpitBundle:Employee')->findOneByUsername($username);
$status = $em->getRepository('CockpitBundle:TCStatus')->findOneById(1);
$tcTimeCard->setPeriodBegin($periodStart);
$tcTimeCard->setStatus($status);
$tcTimeCard->setEmployee($employee);
$form = $this->createForm('CockpitBundle\Form\TCTimeCardType', $tcTimeCard);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$cnt=0;
foreach($form->get('tcdayslots') as $slotform) {
print "Cnt =". ++$cnt . "<BR>";
}
$em->persist($tcTimeCard);
$em->flush();
die("done");
return $this->redirectToRoute('tctimecard_show', array('id' => $tcTimeCard->getId()));
}
$days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
$headings = ['-2' => 'Regular','-1' => "Overtime", '0' => "Holiday"];
foreach ($em->getRepository('CockpitBundle:TimeOffType')->findAll() as $tot) {
$headings[$tot->getId()] = $tot->getType();
}
$headings['99'] = "Comments";
$date = $periodStart;
for ($i = 1; $i<=2; $i++) {
foreach ($days as $day) {
$tcDaySlot = new \CockpitBundle\Entity\TCDaySlot;
$tcDaySlot->setDate($date->format('Y-m-d'));
//$tcsForm = $this->slotForm($tcDaySlot,$date,$employee)->createView();
//$tcsForms[$date->format('m/d/y')] = $tcsForm;
$dates[$date->format('m/d/y')] = $day;
$date->add(new \DateInterval('P1D'));
$tcTimeCard->addTcdayslot($tcDaySlot);
}
}
$cnt2 =0;
foreach ($tcTimeCard->getTcdayslots() as $dayslot) {
print "Cnt2 = " . ++$cnt2 . " " . $dayslot->getDate() . "<BR>";
}
dump($form->getData());
return $this->render('tctimecard/new.html.twig', array(
'tCTimeCard' => $tcTimeCard,
'form' => $form->createView(),
'headings' => $headings,
'emp' => $employee,
'dates' => $dates,
));
}
Lastly, here is the twig I am using to display the form
{% extends 'base.html.twig' %}
{% block body %}
<div class="status">
<h1>Time Card for {{ emp.displayname }} Period Beginning: {{ dates|keys|first }}</h1>
</div>
keys = {{form|keys|join('|') }}<BR>
{{ form_start(form) }}
{{ form_widget(form) }}
<table class="timecard">
<tr>
<th>Date</th>
{% for id,heading in headings %}
<th class="tcheader">
{{ heading}}
</td>
{% endfor %}
</tr>
Length = {{ form.tcdayslots|length }}
{% for tcdayslot in form.tcdayslots %}
<tr>
{% if day | slice(0,1) == 'S' %}
<td class="weekend">{{ date }} {{ day }}</td>
{% else %}
<td>{{ date }} {{ day }}{{ form_start(tcdayslot) }}</td>
{% endif %}
<td>
{{ form_row(tcdayslot.reghours) }}
</td>
<td>
{{ form_row(tcdayslot.othours) }}
</td>
<td>
{{ form_widget(tcdayslot.holidayhours) }}
</td>
<td>
{{ form_widget(tcdayslot.type1hours) }}
</td>
<td>
{{ form_widget(tcdayslot.type2hours) }}
</td>
<td>
{{ form_widget(tcdayslot.type3hours) }}
</td>
<td>
{{ form_widget(tcdayslot.type4hours) }}
</td>
<td>
{{ form_widget(tcdayslot.type5hours) }}
</td>
<td>
{{ form_widget(tcdayslot.note) }}
{{ form_end(tcdayslots) }}
</td>
</tr>
{% endfor %}
<tr><td>TOTALS</td>
</table>
<input type="submit" value="Create" />
{{ form_end(form) }}
<ul>
<li>
Back to the list
</li>
</ul>
{% endblock %}
I finally figured out what was going on. The following line in the foreach $days loop:
$tcDaySlot = new \CockpitBundle\Entity\TCDaySlot;
does not call the constructor. I changed it to:
$tcDaySlot = TCDaySlot();
and added a use statement for the entity and that seems to have connected the collection properly. I think it is a static class instantiation instead of an instance of the object or was I just missing the parens?
I also had to remove the form_start and form_end for each collection object in the twig, as there is only one form created (duh, you can't have embedded forms in HTML).
I would like to know how to concatenate a date field data and a time field data of a form in Symfony2 to be saved as a datetime data in a database datetime field. The explanation is as below:
I would like to add two new time fields to the form in this screen shot:
This is the code of the form (it is in twig and html):
<html>
<head>
<title> Wkayet </title>
<link rel="shortcut icon" href="{{asset('bundles/ikprojhome/images/icon-WKAYET.png')}}">
<link rel="stylesheet" type="text/css" href="{{asset('bundles/ikprojhome/css2/css.css')}}"/>
<script src='{{asset('bundles/ikprojhome/lib/jquery.min.js')}}'></script>
</head>
<body>
<center>
<div id="container">
<div id="header">
</div>
<div id="content">
<table width="100%" height="100%" align="center">
<tr>
<td>
{% for x in groupe%}
<form id="EventForm" action='{{path('ikproj_groupe_homepaeventsAdd',{id:x['id']})}}' method="POST" {{ form_enctype(form) }} onsubmit="javascript:parent.jQuery.fancybox.close();">
<!--<form id="EventForm" action='{{path('ikproj_groupe_homepaeventsAdd',{id:x['id']})}}' method="POST" {{ form_enctype(form) }} >-->
{% endfor %}
{{ form_errors(form) }}
<table align="center">
<tr>
<td class="separation"><label for="groupname">Titre</label></td>
<td>
<!--<input id="titre" name="titre" required="required" type="text" size="50"/> -->
<div>
{{ form_errors(form.title) }}
{{ form_widget(form.title) }}
</div>
</td>
</tr>
<tr>
<td class="separation"><label for="debut">Début</label></td>
<td><!--<select id="debut" name="debut" class="select"></select>-->
<div>
{{ form_errors(form.startdate ) }}
{{ form_widget(form.startdate ) }}
</div>
</td>
</tr>
<tr>
<td class="separation"><label for="heure_debut">Heure</label></td>
<td>
<div>
{{ form_errors(form.starttime ) }}
{{ form_widget(form.starttime ) }}
</div>
</td>
</tr>
<tr>
<td class="separation"><label for="fin">Fin</label></td>
<td><!--<select id="fin" name="fin" class="select"></select>-->
<div>
{{ form_errors(form.enddate ) }}
{{ form_widget(form.enddate ) }}
</div>
</td>
</tr>
<tr>
<td class="separation"><label for="heure_fin">Heure</label></td>
<td>
<div>
{{ form_errors(form.starttime ) }}
{{ form_widget(form.starttime ) }}
</div>
</td>
</tr>
<tr>
<td class="separation"><label for="lieu">Lieu</label></td>
<td> <!--<select id="lieu" name="lieu" class="select"></select> -->
<div>
{{ form_errors(form.location) }}
{{ form_widget(form.location , {'attr':{'class':'select '}}) }}
</div>
</td>
</tr>
<tr>
<td id="description" valign="top" class="separation"><label for="description">Description</label></td>
<td><textarea id="ikproj_groupebundle_eventsgroupe_description" name="ikproj_groupebundle_eventsgroupe[description]" rows="5" cols="40"></textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center" id="button" valign="bottom"><input class="button" type="submit" value=""/></td>
</tr>
</table>
{{form_widget(form._token)}}
</form>
</td>
</tr>
</table>
</div>
</div>
</center>
</body>
</html>
This is the code of the form class :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ->add('idGroupe')
->add('title','text')
->add('startdate','date',array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',))
->add('starttime', 'time', array(
'input' => 'datetime',
'widget' => 'choice',))
->add('enddate','date',array(
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',))
->add('endtime', 'time', array(
'input' => 'datetime',
'widget' => 'choice',))
->add('location','country')
->add('description','text')
// ->add('partager')
;
}
This is the code of the entity with which I am dealing:
<?php
namespace Ikproj\GroupeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* eventsgroupe
*
* #ORM\Table(name="eventsgroupe")
* #ORM\Entity(repositoryClass="Ikproj\GroupeBundle\Entity\eventsgroupeRepository")
*/
class eventsgroupe
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #var integer
* #ORM\ManyToOne(targetEntity="Groupe", inversedBy="eventsgroupe")
* #ORM\JoinColumn(name="admingroupe_id", referencedColumnName="admingroupe_id", nullable=FALSE)
* #ORM\Column(name="admingroupe_id", type="string", length=255)
*/
private $idGroupe;
/**
*
* #var integer
* #ORM\ManyToOne(targetEntity="Groupe", inversedBy="eventsgroupe")
* #ORM\JoinColumn(name="idgroupe", referencedColumnName="id_groupe", nullable=FALSE)
* #ORM\Column(name="idgroupe", type="string", length=255)
*/
private $idEventGroupe;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var \DateTime
*
* #ORM\Column(name="start", type="datetime")
*/
private $start;
/**
* #var \Date
*/
private $startdate;
/**
* #var \Time
*/
private $starttime;
/**
* #var \DateTime
*
* #ORM\Column(name="end", type="datetime")
*/
private $end;
/**
* #var \Date
*/
private $enddate;
/**
* #var \Time
*/
private $endtime;
/**
* #var string
*
* #ORM\Column(name="location", type="string", length=255)
*/
private $location;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #var boolean
*
* #ORM\Column(name="partager", type="boolean")
*/
private $partager;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function getIdGroupe()
{
return $this->idGroupe;
}
/**
* Set title
*
* #param string $title
* #return eventsgroupe
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get startdate
*
* #return date
*/
public function getStartdate()
{
return $this->startdate;
}
/**
* Set startdate
*
* #param date $startdate
* #return eventsgroupe
*/
public function setStartdate($startdate)
{
$this->startdate = $startdate;
return $this;
}
/**
* Get enddate
*
* #return date
*/
public function getEnddate()
{
return $this->enddate;
}
/**
* Set enddate
*
* #param date $enddate
* #return eventsgroupe
*/
public function setEnddate($enddate)
{
$this->enddate = $enddate;
return $this;
}
/**
* Get starttime
*
* #return time
*/
public function getStarttime()
{
return $this->starttime;
}
/**
* Set starttime
*
* #param time $starttime
* #return eventsgroupe
*/
public function setStarttime($starttime)
{
$this->starttime = $starttime;
return $this;
}
/**
* Get endttime
*
* #return time
*/
public function getEndtime()
{
return $this->endttime;
}
/**
* Set endtime
*
* #param time $endtime
* #return eventsgroupe
*/
public function setEndtime($endtime)
{
$this->endtime = $endtime;
return $this;
}
/**
* Set start
*
* #param \DateTime $start
* #return eventsgroupe
*/
public function setStart($startdate,$starttime)
{
//$this->start = $start;
$this->start.date('yyyy-MM-dd') = $startdate;
$this->start.time() = $starttime;
return $this;
}
/**
* Get start
*
* #return \DateTime
*/
public function getStart()
{
return $this->start;
}
/**
* Set end
*
* #param \DateTime $end
* #return eventsgroupe
*/
public function setEnd($enddate,$endtime)
{
$this->end.date('yyyy-MM-dd') = $enddate;
$this->end.time() = $endtime;
return $this;
}
/**
* Get end
*
* #return \DateTime
*/
public function getEnd()
{
return $this->end;
}
/**
* Set location
*
* #param string $location
* #return eventsgroupe
*/
public function setLocation($location)
{
$this->location = $location;
return $this;
}
/**
* Get location
*
* #return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Set description
*
* #param string $description
* #return eventsgroupe
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set partager
*
* #param boolean $partager
* #return eventsgroupe
*/
public function setPartager($partager)
{
$this->partager = $partager;
return $this;
}
/**
* Get partager
*
* #return boolean
*/
public function getPartager()
{
return $this->partager;
}
public function setIdGroupe($idGroupe)
{
$this->idGroupe = $idGroupe;
return $this;
}
public function setIdEventGroupe($idEventGroupe)
{
$this->idEventGroupe = $idEventGroupe;
return $this;
}
public function getIdEventGroupe()
{
return $this->idEventGroupe;
}
}
And this is the structure of the table with which I am dealing in the database:
field name: Type:
----------- -----
id int
title varchar
start datetime
end datetime
location varchar
description varchar
admingroupe_id int
idgroupe int
partager tinyint
Please, focus on the following part of the entity code:
/**
* #var \DateTime
*
* #ORM\Column(name="start", type="datetime")
*/
private $start;
/**
* #var \Date
*/
private $startdate;
/**
* #var \Time
*/
private $starttime;
/**
* #var \DateTime
*
* #ORM\Column(name="end", type="datetime")
*/
private $end;
/**
* #var \Date
*/
private $enddate;
/**
* #var \Time
*/
private $endtime;
And this one too:
/**
* Get startdate
*
* #return date
*/
public function getStartdate()
{
return $this->startdate;
}
/**
* Set startdate
*
* #param date $startdate
* #return eventsgroupe
*/
public function setStartdate($startdate)
{
$this->startdate = $startdate;
return $this;
}
/**
* Get enddate
*
* #return date
*/
public function getEnddate()
{
return $this->enddate;
}
/**
* Set enddate
*
* #param date $enddate
* #return eventsgroupe
*/
public function setEnddate($enddate)
{
$this->enddate = $enddate;
return $this;
}
/**
* Get starttime
*
* #return time
*/
public function getStarttime()
{
return $this->starttime;
}
/**
* Set starttime
*
* #param time $starttime
* #return eventsgroupe
*/
public function setStarttime($starttime)
{
$this->starttime = $starttime;
return $this;
}
/**
* Get endttime
*
* #return time
*/
public function getEndtime()
{
return $this->endttime;
}
/**
* Set endtime
*
* #param time $endtime
* #return eventsgroupe
*/
public function setEndtime($endtime)
{
$this->endtime = $endtime;
return $this;
}
/**
* Set start
*
* #param \DateTime $start
* #return eventsgroupe
*/
public function setStart($startdate,$starttime)
{
//$this->start = $start;
$this->start.date('yyyy-MM-dd') = $startdate;
$this->start.time() = $starttime;
return $this;
}
/**
* Get start
*
* #return \DateTime
*/
public function getStart()
{
return $this->start;
}
/**
* Set end
*
* #param \DateTime $end
* #return eventsgroupe
*/
public function setEnd($enddate,$endtime)
{
$this->end.date('yyyy-MM-dd') = $enddate;
$this->end.time() = $endtime;
return $this;
}
/**
* Get end
*
* #return \DateTime
*/
public function getEnd()
{
return $this->end;
}
The problem is that when I run the code, the form does't show and this is what I see:
So my question is: what is wrong in my code exactly??..is there anyone who has any idea?
I'm have a problem embedding forms from different entities in one form, my form is being displayed with firstname [input] lastname [input] address - but the address has no input next to it.
Basically I want to create a form where the user can add first name, last name, address1, address2, city, country ect and submit it it as one, although it's different tables.
The main form is no problem the only issue I'm having is with the second embedded form. Any help would be greatly appreciated.
Here is my code:
Member class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Member
*/
class Member
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $firstName
*/
private $firstName;
/**
* #var string $lastName
*/
private $lastName;
/**
* #var Pomc\MembersBundle\Entity\Address
*/
private $address;
/**
* #var Pomc\MembersBundle\Entity\Telephone
*/
private $telephone;
public function __construct()
{
$this->address = new \Doctrine\Common\Collections\ArrayCollection();
$this->telephone = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstName
*
* #param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* #param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* Get lastName
*
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Add address
*
* #param Pomc\MembersBundle\Entity\Address $address
*/
public function addAddress(\Pomc\MembersBundle\Entity\Address $address)
{
$this->address[] = $address;
}
/**
* Get address
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAddress()
{
return $this->address;
}
/**
* Add telephone
*
* #param Pomc\MembersBundle\Entity\Telephone $telephone
*/
public function addTelephone(\Pomc\MembersBundle\Entity\Telephone $telephone)
{
$this->telephone[] = $telephone;
}
/**
* Get telephone
*
* #return Doctrine\Common\Collections\Collection
*/
public function getTelephone()
{
return $this->telephone;
}
}
Here is the address class:
namespace Pomc\MembersBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pomc\MembersBundle\Entity\Address
*/
class Address
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $addressType
*/
private $addressType;
/**
* #var string $firstLine
*/
private $firstLine;
/**
* #var string $secondLine
*/
private $secondLine;
/**
* #var string $city
*/
private $city;
/**
* #var string $postCode
*/
private $postCode;
/**
* #var string $country
*/
private $country;
/**
* #var Pomc\MembersBundle\Entity\Member
*/
private $member;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set addressType
*
* #param string $addressType
*/
public function setAddressType($addressType)
{
$this->addressType = $addressType;
}
/**
* Get addressType
*
* #return string
*/
public function getAddressType()
{
return $this->addressType;
}
/**
* Set firstLine
*
* #param string $firstLine
*/
public function setFirstLine($firstLine)
{
$this->firstLine = $firstLine;
}
/**
* Get firstLine
*
* #return string
*/
public function getFirstLine()
{
return $this->firstLine;
}
/**
* Set secondLine
*
* #param string $secondLine
*/
public function setSecondLine($secondLine)
{
$this->secondLine = $secondLine;
}
/**
* Get secondLine
*
* #return string
*/
public function getSecondLine()
{
return $this->secondLine;
}
/**
* Set city
*
* #param string $city
*/
public function setCity($city)
{
$this->city = $city;
}
/**
* Get city
*
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set postCode
*
* #param string $postCode
*/
public function setPostCode($postCode)
{
$this->postCode = $postCode;
}
/**
* Get postCode
*
* #return string
*/
public function getPostCode()
{
return $this->postCode;
}
/**
* Set country
*
* #param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* Get country
*
* #return string
*/
public function getCountry()
{
return $this->country;
}
/**
* Set member
*
* #param Pomc\MembersBundle\Entity\Member $member
*/
public function setMember(\Pomc\MembersBundle\Entity\Member $member)
{
$this->member = $member;
}
/**
* Get member
*
* #return Pomc\MembersBundle\Entity\Member
*/
public function getMember()
{
return $this->member;
}
}
Here is the memberform:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class MemberType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('firstName');
$builder->add('lastName');
$builder->add('address','collection', array( 'type' => new AddressType(),
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Member');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'member';
}
}
Here is the address form:
namespace Pomc\MembersBundle\Form\Type;
use \Symfony\Component\Form\AbstractType;
use \Symfony\Component\Form\FormBuilder;
class AddressType extends AbstractType
{
public function buildForm(Formbuilder $builder, array $options)
{
$builder->add('firstLine');
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Pomc\MembersBundle\Entity\Address');
}
/**
* Returns the name of this type.
*
* #return string The name of this type
*/
function getName()
{
return 'address';
}
function getIdentifier()
{
return 'address';
}
}
Here is the controller:
namespace Pomc\MembersBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use \Pomc\MembersBundle\Entity\Member;
use \Symfony\Component\HttpFoundation\Request;
use \Pomc\MembersBundle\Form\Type\MemberType;
class DefaultController extends Controller
{
public function indexAction($name)
{
return $this->render('PomcMembersBundle:Default:index.html.twig', array('name' => $name));
}
public function newAction(Request $request)
{
$member = new Member();
$form = $this->get('form.factory')->create(new MemberType());
if($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if($form->isValid())
{
$em = $this->getDoctrine()->getEntityManager();
$em->persist($member);
$em->flush();
}
}
return $this->render('PomcMembersBundle:Default:new.html.twig', array( 'form'=> $form->createView(),));
}
}
Here is the template:
<form action="{{ path('member_new') }}" method="post" {{ form_enctype(form)}}>
{{ form_widget(form) }}
<div>
{{ form_row(form.address)}}
</div>
<input type="submit" />
</form>
Been a long time user of this site, but this is my first question.
Thank you
Oh I faced the same problem, but I found the solution, hope this will help you :-)
You're forgetting to add an Address object to the member entity.
In your action you'll need to do the following:
$member = new Member();
$member->addAddress(new Address());
$form = $this->createForm(new MemberType(), $member);
And then in your template:
{% for address in form.address %}
{{ form_widget(address.firstLine) }}
{% endfor %}
Btw your 'firstline' widget doesn't relate to an entity property.
Btw if you called addAddress two times, you would of course get two 'firstline' widgets in your form.
Hope this works. best of luck.
Llewellyn, do you mean something like thid:
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('imBundle:Inspecciones')->find($id);
$entity_valores = $em->getRepository('imBundle:ValoresInspecciones')->findByInspecciones($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Inspecciones entity.');
}
$entity->setValoresInspecciones($entity_valores);
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('imBundle:Inspecciones:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}