How to render a checkbox that is checked by default with the symfony2 Form Builder? - checkbox

I have not found any easy way to accomplish to simply check a Checkbox by default. That can not be that hard, so what am i missing?

You can also just set the attr attribute in the form builder buildForm method:
$builder->add('isPublic', CheckboxType::class, array(
'attr' => array('checked' => 'checked'),
));

In Symfony >= 2.3 "property_path" became "mapped".
So:
$builder->add('checkboxName', 'checkbox', array('mapped' => false,
'label' => 'customLabel',
'data' => true, // Default checked
));

You would simply set the value in your model or entity to true and than pass it to the FormBuilder then it should be checked.
If you have a look at the first example in the documentation:
A new task is created, then setTask is executed and this task is added to the FormBuilder. If you do the same thing with your checkbox
$object->setCheckboxValue(true);
and pass the object you should see the checkbox checked.
If it's not working as expected, please get back with some sample code reproducing the error.

Setting the 'data' option works for me. I'm creating a non entity based form:
$builder->add('isRated','checkbox', array(
'data' => true
));

In TWIG
If you wish to do this in the template directly:
{{ form_widget(form.fieldName, { 'attr': {'checked': 'checked'} }) }}

Use the FormBuilder::setData() method :
$builder->add('fieldName', 'checkbox', array('property_path' => false));
$builder->get('fieldName')->setData( true );
"property_path" to false cause this is a non-entity field (Otherwise you should set the default value to true using your entity setter).
Checkbox will be checked by default.

To complete a previous answer, with a multiple field you can do that to check all choices :
'choice_attr' => function ($val, $key, $index) {
return ['checked' => true];
}
https://symfony.com/doc/3.3/reference/forms/types/choice.html#choice-attr

You should make changes to temporary object where entity is stored before displaying it on form. Something like next:
<?php
namespace KPI\AnnouncementsBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class AnnouncementType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
if ($options['data']->getDisplayed() === null) {
$options['data']->setDisplayed(true);
}
// ...
$builder
->add('displayed', 'checkbox', array(
'required' => false
));
}
}

As per documentation:
http://symfony.com/doc/current/reference/forms/types/checkbox.html#value
To make a checkbox or radio button checked by default, use the data option.

UserBundle\Entity\User
let's assume that you have an entity called ( User ) and it has a member named isActive, You can set the checkbox to be checked by default by setting up isActive to true:
$user = new User();
// This will set the checkbox to be checked by default
$user->setIsActive(true);
// Create the user data entry form
$form = $this->createForm(new UserType(), $user);

I had the same problem as you and here is the only solution I found:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$entity= $event->getData();
$form = $event->getForm();
$form->add('active', CheckboxType::class, [
'data' => is_null($entity) ? true : $entity->isActive(),
]);
});

This works as well, but aware of persistent "checked" state
$builder->add('isPublic', 'checkbox', array(
'empty_data' => 'on',
));

This is how you can define the default values for multiple and expanded checkbox fields. Tested in Symfony4, but it has to work with Symfony 2.8 and above.
if you want to active the 1st and the 2nd checkboxes by default
class MyFormType1 extends AbstractType
{
CONST FIELD_CHOICES = [
'Option 1' => 'option_1',
'Option 2' => 'option_2',
'Option 3' => 'option_3',
'Option 4' => 'option_4',
'Option 5' => 'option_5',
];
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->addSettingsField('my_checkbox_field', ChoiceType::class, [
'label' => 'My multiple checkbox field',
'choices' => self::FIELD_CHOICES,
'expanded' => true,
'multiple' => true,
'data' => empty($builder->getData()) ? ['option_1', 'option_2'] : $builder->getData(),
]);
}
}
if you want to active every checkbox by default
class MyFormType2 extends AbstractType
{
CONST FIELD_CHOICES = [
'Option 1' => 'option_1',
'Option 2' => 'option_2',
'Option 3' => 'option_3',
'Option 4' => 'option_4',
'Option 5' => 'option_5',
];
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->addSettingsField('my_checkbox_field', ChoiceType::class, [
'label' => 'My multiple checkbox field',
'choices' => self::FIELD_CHOICES,
'expanded' => true,
'multiple' => true,
'data' => empty($builder->getData()) ? array_values(self::FIELD_CHOICES) : $builder->getData(),
]);
}
}

The only watertight solution for me in Symfony 4, 2022 is:
OPTION 1:
First, set it default to "true" on the entity parameter itself:
class MyEntity {
/**
* #ORM\Column(name="my_param", type="boolean", nullable=true)
*/
private $myParameter = true;
...
}
Secondly, in the form, first see if you can get it from the entity itself. If Not, set the default
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** #var MyEntity $entity */
$entity = $builder->getData();
$builder->add('myParameter', CheckboxType::class, [
'required' => false,
'data' => $entity ? $entity->getMyParameter() : true,
]);
}
This way the real value (coming from the database) has precedence over the default value.
Also good to know is: Submitted data has precedence over the 'data' => true but initially loaded data before submit gets overridden by 'data' => true
OPTION 2:
An alternative way of setting it default true on the MyEntity Class you can choose to set it as default only just before creating the form.
But then you always need the object to create the form with. So you then may not create a form without a given object
if (empty($entity)) {
// Warning: Only if it's a new object, set the default
$entity = new MyEntity();
$entity->setMyParameter(true);
}
// For this option you must always give the form an entity
$form = $this->createForm(MyType::class, $entity);
$form->handleRequest($request);
So for this option you don't need to do anything special in the FormType
$builder->add('myParameter', CheckboxType::class, [
'required' => false,
]);

Related

sonata_type_model - Set value to empty

Is there a way to allow to set an empty value in the sonata_type_model?
This is my current configuration:
->add('location', 'sonata_type_model', [
'class' => Location::class,
'property' => 'name',
'label' => 'Herkunft',
])
Simply add 'empty_value' => '' to the array.
Same problem here. I solved it with the help of Saving Hooks: preUpdate()
public function preUpdate($object)
{
if (!$this->getRequest()->request->get($this->getForm()->getName())['location']) {
$object->setLocation(null);
}
}
// Changed sonata_type_model to symfony entity type field
// Then add placeholder option witch recognized as empty value option in select box.
...
->add('location', null, [
'class' => Location::class,
'property' => 'name',
'label' => 'Herkunft',
'placeholder' => 'Your empty option label',
])

How to add custom CSS class to required input label?

I would like to add a CSS class to labels which are before my required inputs field. I can do it via JavaScript but I would like to do it in CakePHP.
Is there some options to tell CakePHP to do it automatically?
For one input, you can simply do this:
$this->Form->input('myfield', [
'label' => [
'text' => 'My Field',
'class' => 'my-label-class'
]
]);
If you need to add it to all required inputs, you could instead create your own FormHelper:
App::import('Helper', 'Form') ;
class MyFormHelper extends FormHelper {
protected function _inputLabel($fieldName, $label, $options) {
// Extract the required option from the $options array.
$required = $this->_extractOption('required', $options, false)
|| $this->_introspectModel($this->model(), 'validates', $fieldName);
// If the input is required, first force the array version for $label,
// then add the custom class.
if ($required) {
if (!is_array($label)) {
$label = array('text' => $label) ;
}
$label = $this->addClass($label, 'my-label-class') ;
}
// Then simply call the parent function.
return parent::_inputLabel($fieldName, $label, $options) ;
}
}
And then in your controller:
public $helpers = array(
'Form' => array('className' => 'MyForm')
);
See FormHelper.php for informtion about _introspectModel, basically:
$this->_introspectModel ($model, 'validates', $fieldName)
...will return true if $fieldName is a required field in your Model::validates array.

Adding a default option "Please Select" in cakephp dropdown

I am new to cakephp. I need to add a default
<option value="0">--Please Select--</option>
in my following select field :
$attributes = array("empty"=>false,"Selected" => 'Select City',"id" => "location");
echo $form->select("gal_location_id", $gal_locations,null,$attributes);
I tried to add
$gal_locations[0] = "--Select City--";
$attributes = array("empty"=>false,"default" => 0,"id" => "location");
but the option coming at the bottom of the list. What is the proper way to add the default option ?
You're looking for the "empty" attribute:
$this->Form->input('gal_location_id', array(
'type' => 'select',
'options' => $gal_locations,
'empty' => 'Select City', // <-- Shows as the first item and has no value
'id' => 'location'
));
See the equivalent in CakePHP3 from this post
CakePHP3
With the following option you dont get a notification to choose a dropdown item.
So if you're just looking for a default value and force the user to pick another, just replace the assign a string to 'empty'.
echo $this->Form->input('db_field', [
'label' => 'My Drop Down',
'empty' => [$default => $default], //Your default options
'options' => $my_options //Your array /list'
]);
echo $this->Form->input('country_id',[
`enter code here`'options' =>$country,
'label' => false,
'class'=>'form-control select2',
'empty'=> 'Select...',
'value' => ''
]);

Custom Template in Sonata Admin

I am using Sonata Admin to manage CRUD tasks in my application. In one Admin called Multimedia, which has one-to-many relations with Files and Weblinks, both of which are embedded in the Multimedia form. I have a custom template that renders the fields horizontally and with titles. My question is, do I have to specify two different templates for Files and Weblinks because using a single file has failed, Files renders the embed form how I want it but weblink ignores directive.
Here's the Admin Code
class MultimediaAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('name')
->add('publish_date')
->add('keywords')
->add('copyright')
->end()
->with('Files')
->add('files','sonata_type_collection',
array('label' => 'Multimedia Files',
'btn_add' => 'Add File',
'by_reference' => 'false',
'type_options' => array('delete' => false)
), array(
'edit' => 'inline',
'template' => 'MyMultimediaBundle:Multimedia:horizontal.fields.html.twig'
)
)
->end()
->with('Tags')
->add('tags')
->end()
->with('Weblinks')
->add('weblinks','sonata_type_collection',
array('label' => 'External Videos',
'btn_add' => 'Add Video',
'by_reference' => 'false',
'type_options' => array('delete' => false)
), array(
'edit' => 'inline',
'template' => 'MyMultimediaBundle:Multimedia:horizontal.fields.html.twig'
)
)
->end()
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('name')
->add('publish_date')
->add('keywords')
->add('copyright')
->add('_action','actions',array('actions'=>(array('edit'=>array(),'view'=>array(),'delete'=>array()))))
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('name')
->add('publish_date')
->add('keywords')
->add('copyright')
;
}
public function prePersist($multimedia)
{
$this->preUpdate($multimedia);
}
public function preUpdate($multimedia)
{
$multimedia->setFiles($multimedia->getFiles());
}
public function getFormTheme()
{
return array_merge(
parent::getFormTheme(),
array('MyMultimediaBundle:Multimedia:horizontal.fields.html.twig')
);
}

Symfony 2 : Access database inside FormBuilder

I'm building a form which contains a category field. I need a choice list to do that, but I don't find out how to fill this choice list with the several categories stored in the database.
public function buildForm(FormBuilder $builder, array $options) {
$builder->add('item', 'text', array('label' => 'Item'));
$builder->add('category', 'choice', array(
'choices' => ???,
'label' => 'Category'
));
}
How can I get the categories from the database?
(I can't seem to access $this->getDoctrine() inside this class.)
Use type entity instead of choice
$builder
->add('entity_property', 'entity', array(
'class' => 'Namespace\\To\\Entity',
'query_builder' => function(EntityRepository $repository) {
return $repository->createQueryBuilder('q')
->where('q.a_field = yourvalue');
}
));
Edit:
Two ways for using custom parameters in your query. In both situations, the parameters are injected from outside, so your FormType don't need any references to the session or request objects or whatever.
1- Pass required parameters to your constructor
class TaskType extends AbstractType
{
private $custom_value;
public function __construct($custom_value) {
$this->custom_value = $custom_value;
}
// ...
}
in your buildForm() you must copy the value to local variable and make it available for the query_builder callback:
public function buildForm(/*...*/) {
$my_custom_value = $this->custom_value;
// ...
'query_builder' => function(EntityRepository $repository) use ($my_custom_value) {
return $repository->createQueryBuilder('q')
->where('q.a_field = :my_custom_value')
->setParameter('my_custom_value', $my_custom_value);
}
// ...
}
2- use the $options parameter of the buildForm method.
First you have to define a default value by overriding getDefaultOptions:
public function getDefaultOptions(array $options)
{
return array(
'my_custom_value' => 'defaultvalue'
);
}
Then you can pass it from your controller in the third argument of the createForm method.
$this->createForm(new YourFormType(), $entity, array('my_custom_value' => 'custom_value'));
Now the value should be available through the $options parameter of youru buildForm method. Pass it to the callback as described above.
In Symfony 2.1
You now have to use the OptionsResolverInterface within the setDefaultOptions method. Here is the code you would have to use if you wanted to retrieve the options (using the same example as the accepted answer)
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
public function buildForm(FormBuilderInterface $builder, array $options){
parent::buildForm($builder, $options);
$my_custom_value = $options[custom_value];
// ...
'query_builder' => function(EntityRepository $repository) use ($my_custom_value) {
return $repository->createQueryBuilder('q')
->where('q.a_field = :my_custom_value')
->setParameter('my_custom_value', $my_custom_value);
}
// ...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'my_custom_value' => 'defaultvalue'
));
}
You still pass the options in the same way:
$this->createForm(new YourFormType(), $entity, array('my_custom_value' => 'custom_value'));

Resources