2 instances of the same embedded form with Symfony & Twig - php

I'm looking to display 2 instances of the same form inside another form with twig but I can't figure out how.
Here my first form:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// build form
$builder
->add('contenu', 'text', array(
'attr' => array('maxlength' => 255),
'empty_data' => "Question par défaut"
))
->add('file', 'file', array(
'attr' => array('accept' => "image/png, image/jpeg")
))
->add('contenuQuestion', 'collection', array(
'type' => new QuizzReponseType(), // here the embedded form
'allow_add' => true,
'allow_delete' => true,
'cascade_validation' => true,
))
;
}
with in the entity:
/**
* #ORM\ManyToMany(targetEntity="OC\QuizzBundle\Entity\QuizzReponse", cascade={"remove", "persist"})
*/
private $contenuQuestion;
function __construct() {
$this->contenuQuestion = new ArrayCollection();
}
Here the embedded form:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// build form
$builder
->add('contenu', 'text', array(
'attr' => array('maxlength' => 50),
'empty_data' => "Réponse par défaut"
))
->add('file', 'file', array(
'attr' => array('accept' => "image/png, image/jpeg")
))
;
}
The problem is in my view. I want to have 2 instances of the embedded form but the collection seems empty.
It's working well with only one embedded form (NB: my first form is also inside another form but it's not relevant for my question):
// embedded form content field
{{ form_widget(form.contenuQuizz.vars.prototype.contenuQuestion.vars.prototype.contenu) }}
And I'm looking to do something like that:
// embedded form1 content field
{{ form_widget(form.contenuQuizz.vars.prototype.contenuQuestion.0.vars.prototype.contenu) }}
// embedded form2 content field
{{ form_widget(form.contenuQuizz.vars.prototype.contenuQuestion.1.vars.prototype.contenu) }}
It looks like the problem is that the collection is not initialized but I'm not sure.
Is there a way to do that ? (with twig and not JavaScript if possible)
Thanks in advance,
Maugun

Related

Unable to use EntityType with FormFactory

I'm currently working with Symfony but I ran into troubles with forms.
I have an entity named Categories. In my form, I have a request selecting all categories having an attribute gamme corresponding to my variable $gamme.
$categories is an array containing categories, as expected. I want to be able to select a category in my form.
But a the display, I only have one choice available.
Do you know where is the problem ?
This is my code :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('gamme', ChoiceType::class, array('choices' => array('AUT' => 'AUT', 'FFE' => 'FFE', 'FSI' => 'FSI', 'FSE' => 'FSE', 'FME' => 'FME')))
->add('designation')
->add('description')
->add('critereRech1')
->add('critereRech2')
->add('critereRech3')
->add('critereRech4')
->add('taxonomie')
->add('articleAssocie1')
->add('articleAssocie2')
->add('articleAssocie3')
->add('qteMaxCde')
->add('publication')
->add('codeArticle');
$builder->get('gamme')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event){
$form = $event->getForm()->getParent();
$gamme = $event->getData();
$this->addCatgeorieField($form, $gamme);
}
);
}
/**
* Rajoute un champs catégorie au formulaire
* #param FormInterface $form
* #param $gamme
*/
private function addCatgeorieField(FormInterface $form, $gamme){
$categories = $this->em->getRepository('AppBundle:Categories')->findBy(["gamme" => $gamme]);
dump($categories);
$builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
'codeCategorie',
EntityType::class,
null,
[
'class' => 'AppBundle\Entity\Articles',
'placeholder' => 'sélectionnez la catégorie',
'required' => false,
'choices' => $categories,
'auto_initialize' => false
]
);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event){
dump($event->getForm());
}
);
$form->add($builder->getForm());
} </code></pre>
This is my current result. But instead of one categorie I should have 34 categorie:
This is the result of dump($categories) :
I find my mistake. In this code :
[
'class' => 'AppBundle\Entity\Articles',
'placeholder' => 'sélectionnez la catégorie',
'required' => false,
'choices' => $categories,
'auto_initialize' => false
]
At 'class', instead to write 'Articles' I have to write 'Categories' because I want display a different instance of my entity Categories.
Thank you all for your answers.

Get value from EntityType Symfony

I can not get value from EntityType. I have last version 3.3.6.
class BuildType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('title', TextType::class)
->add('save', SubmitType::class, array('label' => 'Create Post'))
->add('team', CollectionType::class, array(
// each entry in the array will be an "email" field
'entry_type' => TeamType::class,
// these options are passed to each "email" type
'entry_options' => array(
'attr' => array('class' => 'form-control'),
),
'label' => false,
'allow_add' => true,
'prototype' => true,
'mapped' => false
));
}
}
class TeamType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('name', EntityType::class, array(
'placeholder' => 'Choice a champ',
'required' => true,
'class' => 'AppBundle:Champions',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
},
'choice_label' => 'name',
'choice_value' => 'id',
'attr' => array('class' => 'dropdown'),
));
}
I tried all but i cannot take value of 'name' of TeamType. After submission form, i do
foreach ($form["team"]->getData() as $value) {
'name' => $value['name']
but the value is empty. If i try dump request and the value is there. The other values i can get it and save in Database. Only EntityType i can not.
Someone know how do?
EntityType returns as the object. You should use model getter functions.
$form->get('name')->getData()->getId(); // getName() vs..
Here is a similar example.
symfony how get selected data from select
I suppose that you are using ManyToOne relationship.
With AJAX
if you are trying get data after submitted, You can do this first in your view:
$('#elementWhereYouAreTEAMType').find('input').each(function (i,v) {
var valTeam = $(this).val(); //take value
// adding data, create an associative array.
formData.append("team["+ i +"]", valTeam);
});
You must put formData like data argument to ajax JQuery
Now, server side:
public function createTeamNow(Request $request) {// ajax
$teams = $request->request->get('team'); // getting array
if(!is_null($teams)) {// if user added team
foreach ($teams as $team) {
// dump($team);
//create an instance for each element, it does not replace a data with the above
$teamType = new TeamType();
$teamName->setName($team);
$this->em->persist($teamType);
}
}
}
Without AJAX
/**
* #Route("/slim/1" , name="data_x")
*/
public function slimExampleAction(Request $request)
{
$form = $this->createForm(TeamType::class);
$form->handleRequest($request);
if ($form->isSubmitted() /*&& $form->isValid()*/) {
// When you've ManyToOne relationship, that field returns ArrayCollection class, it has several method to get data on differents ways, iterate with it, for example toArray is one
$data = $form->getData();
dump($data->getDescription()->toArray());die;
}
return $this->render('AppBundle:view.html.twig', array(
'form' => $form->createView(),
));
}

symfony ajax form dynamically modify

I have the following form that contains data from the database it still WIP ( i'm missing a few fields that i didn't add yet).
The form loads data in the first select and based on that select i use ajax to populate a second select with options based on the first select ( basically the associations to the selected value). And from there again another select with certain options and so on and at the end when i submit the form i want to generate a report from database based on the data.
For the moment i'm stuck with the second field because i always get an error:
This value is not valid.
The form class:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('survey', EntityType::class, [
'class' => SurveyManager::class,
'placeholder' => 'Choose option',
'attr' => [
'class' => 'field-change',
],
])
->add('headquarter', ChoiceType::class, [
'choices' => [],
])
->add('submit', SubmitType::class, [
'label' => 'Save',
])
;
}
I'm not reall sure how to fix the error or how should i handle this type of form. Can you help me out guys ?
Based on the answer i did this
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$form->add('headquarter', EntityType::class, [
'class' => HeadQuarterManager::class,
'query_builder' => function(HeadQuarterManagerRepository $er) {
return $er->getHeadquarter($data['survey']);
},
]);
}
);
But i'm getting this error:
Notice: Undefined variable: data
Not really sure how to pass the data to the getHeadquarter method so i can return an array of id => name for the select.
When you run the function $form->isValid(), it checks against the form it built in the buildForm function. Any extra fields/value that aren't there will cause this error.
You can change this behaviour by using form events.
In the end this is how i did it:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('survey', EntityType::class, [
'class' => SurveyManager::class,
'attr' => [
'class' => 'field-change',
],
])
->add('submit', SubmitType::class, [
])
->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$modifier = $data['survey'];
$form->add('headquarter', EntityType::class, [
'class' => HeadQuarterManager::class,
'query_builder' => function (HeadQuarterManagerRepository $er) use ($modifier) {
return $er->getHeadquarter($modifier);
},
]);
}
);
}

Symfony2 form entity preferred_choices set selected values

I'm having dificulties trying to set on my form the selected values on the preferred choices.
I have a class calendar that can have multiple taxes:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('possibledigits')
->add('notes')
->add('autogenerateyear', 'checkbox', array('required' => false))
->add('calendartaxes', null, array(
'required' => false,
'multiple' => true,
'expanded' => true
))
;
}
The relation is many to many:
/**
* #ORM\ManyToMany(targetEntity="CalendarTax", indexBy="name", inversedBy="calendarios")
* #ORM\JoinTable(name="contable_schedule_taxes_relation")
*/
private $calendartaxes;
What I was going to do is to try to get the entity of the form and try to get the selected taxes. But I don't know if that is the correct way to do it.
Is there a more elegant way to do it?
I'm using symfony 2.3.
Regards.
I am assuming you have a relationship set up betwween Calendarios and CalendarTax
so before you create the form ... do
$calendarios = new CalendarIOS();
$calendartax = $this->getDoctrine()->getManager()->getRepository('NamBundle:CalendarTax')->find($calendar_tax_id);
$calendarios->addCalendarTax($calendartax);
now when you send the entity over to the formbuilder...you will have that perticular calendartax checked... :)
Finally I use the preferred_choices of the choice.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$calendario = $builder->getData();
$taxesId = array();
foreach($calendario->getCalendartaxes() as $tax){
$taxesId[] = $tax;
}
$builder
->add('name')
->add('possibledigits')
->add('notes')
->add('autogenerateyear', 'checkbox', array('required' => false))
->add('calendartaxes', null, array(
'required' => false,
'multiple' => true,
'expanded' => true,
'preferred_choices' => $taxesId,
))
;
}
Making one more query and getting the calendar of the form builder.
The comment given by #Hakim was the one that put me on the right path.
Thanks!

Set Default value of choice field Symfony FormType

I want from the user to select a type of questionnaire, so I set a select that contains questionnaires types.
Types are loaded from a an entity QuestionType .
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'))
->add('type', 'hidden')
;
What am not able to achieve is to set a default value to the resulted select.
I have googled a lot but I got only preferred_choice solution which works only with arrays
I made it by setting a type in the newAction of my Controller I will get the seted type as default value.
public function newAction($id)
{
$entity = new RankingQuestion();
//getting values form database
$em = $this->getDoctrine()->getManager();
$type = $em->getRepository('QuizmooQuestionnaireBundle:QuestionType')->findBy(array('name'=>'Ranking Question'));
$entity->setQuestionType($type); // <- default value is set here
// Now in this form the default value for the select input will be 'Ranking Question'
$form = $this->createForm(new RankingQuestionType(), $entity);
return $this->render('QuizmooQuestionnaireBundle:RankingQuestion:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'id_questionnaire' =>$id
));
}
You can use data attribute if you have a constant default value (http://symfony.com/doc/current/reference/forms/types/form.html)
but it wont be helpful if you are using the form to edit the entity ( not to create a new one )
If you are using the entity results to create a select menu then you can use preferred_choices.
The preferred choice(s) will be rendered at the top of the list as it says on the docs and so the first will technically be the default providing you don't add an empty value.
class MyFormType extends AbstractType{
public function __construct($foo){
$this->foo = $foo;
}
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'
'data' => $this->foo))
->add('type', 'hidden')
;
}
In controller
$this->createForm(new MyFormType($foo));
The accepted answer of setting in the model beforehand is a good one. However, I had a situation where I needed a default value for a certain field of each object in a collection type. The collection has the allow_add and allow_remove options enabled, so I can't pre-instantiate the values in the collection because I don't know how many objects the client will request. So I used the empty_data option with the primary key of the desired default object, like so:
class MyChildType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('optionalField', 'entity', array(
'class' => 'MyBundle:MyEntity',
// Symfony appears to convert this ID into the entity correctly!
'empty_data' => MyEntity::DEFAULT_ID,
'required' => false,
));
}
}
class MyParentType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('children', 'collection', array(
'type' => new MyChildType(),
'allow_add' => true
'allow_delete' => true,
'prototype' => true, // client can add as many as it wants
));
}
}
Set a default value on the member variable inside your entity (QuestionType), e.g.
/**
* default the numOfCourses to 10
*
* #var integer
*/
private $numCourses = 10;

Categories