symfony2 - radio buttons default data overrides actual value - php

I have a simpleform:
public function buildForm(FormBuilderInterface $builder, array $option){
$builder
->setMethod('POST')
->add('isdigital', 'choice', array(
'choices' => array('0' => 'no', '1' => 'yes'),
'expanded' => true,
'multiple' => false,
'data'=> 0
));
}
I populate this form passing in an array key value, without using doctrine entities.
$this->createForm(new PricingType(), $defaultData);
The attribute 'data' should set the value only for the first time, instead overrides the value passed with the array.
If I remove the 'data' attribute, the radio button actually displays the value passed in the array.
Is there any way I can set the default value only for the first time?

In the entity for the data class that related to PricingType add a __construct():
__construct(){
$this->isdigital = 0;
}
Now in your controller when you create the $defaultData item which is form the entity Pricing
$defaultData = new Pricing();
This will have the default value you want and you do not need to have the 'data' => 0 line in your form class.

The only solution I found is You will need to add a form Event Listener POST_SET_DATA to dynamically set the default value if the values aren't set.
For eg:
use Symfony\Component\Form\FormEvents; //Add this line to add FormEvents to the current scope
use Symfony\Component\Form\FormEvent; //Add this line to add FormEvent to the current scope
public function buildForm(FormBuilderInterface $builder, array $option){
//Add POST_SET_DATA Form event
$builder->addEventListener(FormEvents::POST_SET_DATA,function(FormEvent $event){
$form = $event->getForm(); //Get current form object
$data = $event->getData(); //Get current data
//set the default value for isdigital if not set from the database or post
if ($data->getIsdigital() == NULL){ //or $data->getIsDigital() depending on how its setup in your entity class
$form->get('isdigital')->setData(**YOUR DEFAULT VALUE**); //set your default value if not set from the database or post
}
});
$builder
->setMethod('POST')
->add('isdigital', 'choice', array(
'choices' => array('0' => 'no', '1' => 'yes'),
'expanded' => true,
'multiple' => false,
//'data'=> 0 //Remove this line
));
}
Please Note: The above code is not tested, but was rewritten to fit the questions scenario.

Related

Symfony2 FormType add element to entity field (on top)

I have a form whith a entity field like this one :
$builder->add('account', 'entity', [
'label' => 'account',
'class' => Account::class,
'query_builder' => $accountsQueryBuilder,
'choice_label' => 'numberAndName',
]);
I want to add an option "All accounts" to this field, I do it like this :
public function finishView (FormView $view, FormInterface $form, array $options)
{
$new_choice = new ChoiceView(array(), 'all', 'All accounts');
$view->children['account']->vars['choices'][] = $new_choice;
}
My problem is that the added field is on the bottom of the list. Is there a clean way to put it on the top of the list ?
Thanks for your answers !
I don't use Symfony, so I could be way off here, but from your code $view->children['account']->vars['choices'] appears to be an array. So you should be able to use array_unshift to put a new element on the top.
array_unshift($view->children['account']->vars['choices'], $new_choice);

Modifying field options using FormTypeExtensions

I know there's no clean way to do this after the form has been built using FormEvents however is there a way to mainpulate the options passed to a form using FormTypeExtensionInterface::buildForm before it has been completely built?
e.g: I will use this to set multiple options to specific values when another option is set in the form e.g: when the option "helper" is set true set the "label" option to "helper" and set "disabled" option to true
So what you can do is pass the option to your form when you create it. For example, in your controller:
$form = $this->createForm(new YourFormType(), null, array('helper' => true));
Then in your buildForm function:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('myfield', null, array(
'label' => ($options['helper']) ? 'helper' : 'mylabel',
'disabled' => ($options['helper']) ? true : false,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'helper' => false,
));
}
The only thing is, this is a global option for the entire form. Did you mean that you want this option for every individual field?

Symfony2 : How to get a default value from a form in Controller?

I want to get a default value from a form. For example, I rendered a select box form by using the following code:
$form = $this->createFormBuilder()
->add('patient', 'choice', array(
'choices' => $patientArray,
'required' => true,
'label' => false
))
->getForm();
The patientArray values are composed of patient_id and patient_name :
array(
'2' => 'John'
'3' => 'Jane'
);
So, I would like to get the default value which is 2 => John without submit a button and without choosing the select form. What is a proper way to achieve this in a controller?
You need to set default value in your entity. You can use __construct() method for it.
// create a task and give it some dummy data for this example
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->add('save', 'submit')
->getForm();
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
'form' => $form->createView(),
));
In this example task field has Write a blog post value by default. You also can do this in __construct(), and you don't need use setter, but it is't necessary.
But better use __construct instead setter like:
// src/Acme/TaskBundle/Entity/Task.php
namespace Acme\TaskBundle\Entity;
class Task
{
protected $task;
protected $dueDate;
public function __construct() {
$this->task = 'Write a blog post';
}
and you always have default value when create Task object
P.s. You can find more examples in forms documentation

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;

Can you 'extend' form classes?

I am creating form classes for my forms, but cannot figure out how to 'extend' them.
For example, I have a CustomerType form class, and an EmailType form class. I could add the EmailType directly into my CustomerType
$builder->add('emails', 'collection', array(
'type' => new EmailType(),
'allow_add' => true,
'by_reference' => false
));
but I'd prefer to do this in the controller, so that my CustomerType form class contains only customer information. I feel this is more modular and reusable, since sometimes I want my user to be able to edit only Customer details, and others both Customer details as well as Email objects associated with that customer. (For example, in the first case when viewing a customer's work order, and in the second when creating a new customer).
Is this possible? I'm thinking something along the lines of
$form = $this->createForm(new CustomerType(), $customer);
$form->add('emails', 'collection', ...)
in my controller.
You could pass an option (say "with_email_edition") to your form when it's created that would tell if the form should embed the collection or not.
In the Controller:
$form = $this->createForm( new CustomerType(), $customerEntity, array('with_email_edition' => true) );
In the form:
Just add the option in the setDefaultOptions:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'with_email_edition' => null,
))
->setAllowedValues(array(
'with_email_edition' => array(true, false),
));
}
and then check in the "buildForm" the value of this option,and add a field based on it:
public function buildForm(FormBuilderInterface $builder, array $options)
{
if( array_key_exists("with_email_edition", $options) && $options['with_email_edition'] === true )
{
//Add a specific field with $builder->add for example
}
}

Categories