How to disable radio buttons if one is seleced in Sonata Admin - php

For example I have an entity field which starts null and will show the radio buttons, within the Admin pages once a radio button has been selected and saved into the entity then those radio buttons need to be 'disabled', still visible but not intractable.
protected function configureFormFields(FormMapper $form)
{
$form->add('radio_buttons', ChoiceType::class,
array('choices' => array(
"choice 1" => 'input1',
"choice 2" => 'input2'),
'choices_as_values' => true, 'multiple'=>false, 'expanded'=>true, 'disabled' => false));
}

Your can put a condition in your form to check wether a field is already filled or not.
(Assuming the method is named getRadioButton())
if ($this->getSubject()->getRadioButton() != null) {
$form->add(here tell than you need disabled buttons)
} else {
$form->add(here tell than you need buttons)
}
also, in form field, you can add "html" attribute doing this:
->add('radio_buttons', ChoiceType::class,array(
'what you want'=>'ok',
'attr'=>array("disabled" => true))
so finally it'd give something like
if ($this->getSubject()->getRadioButton() != null) {
$form->add('radio_buttons', ChoiceType::class,
array('choices' => array(
"choice 1" => 'input1',
"choice 2" => 'input2'),
'choices_as_values' => true,
'multiple'=>false,
'expanded'=>true,
'attr' => array('disabled'=>true),
));
} else {
$form->add('radio_buttons', ChoiceType::class,
array('choices' => array(
"choice 1" => 'input1',
"choice 2" => 'input2'),
'choices_as_values' => true,
'multiple'=>false,
'expanded'=>true,
));
}
For more information:
https://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html

Do it in your view.
Check if one of the choice exists, and implement a different code if it does.
I would also recommand to remove the radio buttons if it exists, and replace with a text. That will prevent some smartass to edit the DOM and change the choice.

Related

How can I edit a field of a form in my controller?

I'm having trouble formulating a solution for 'editing' a field of my form in my controller.
Here's what I have:
I have a symfony2 form registered as a service that I call in a function in my controller. I am removing a bunch of fields that aren't necessary for this other form I am directing my users to and then adding a few others.
(I realize I could create another form and create another service and such but for my purpose this would be a bit overkill. I'm doing it this way because the form functions the same, however some fields are not needed and a few new specific ones are.)
I would now like to essentially 'edit' one field in this form... The 'occupation' field. This field is a choice field acting as radio buttons populated by an array of choices. It's required and has no empty_value requirement in its original state.
I would like to edit it in my controller function to have the same exact values however with a required value of false and an empty_value of null.
With the commented out code below the result is a dissapearance of the occupation field in my 'new' form and it is replaced by an empty drop down. I realize it's because I'm overriding the whole field below, but I cannot figure out how to simply edit it.
Code:
/**
* Explanation of addAndRemoveFieldsInRegisterForm function:
* The function gets the 'registration' form and removes any
* fields not needed for the 'in_registration' form
* and then adds the necessary fields to the form.
*/
private function addAndRemoveFieldsInRegisterForm($user)
{
$form = $this->createForm('user_registration', $user);
// http://stackoverflow.com/questions/10920006/pass-custom-options-to-a-symfony2-form ---
// --- use that to help. Look at changing the value of array.
$form->remove('title');
$form->remove('company');
$form->remove('username');
$form->remove('city');
$form->remove('state');
$form->remove('country');
$form->remove('gender');
$form->remove('age');
$form->remove('roles');
// $form->remove('occupation');
// $pr = $form->get('occupation');
// $pr->set('required' => false);
// $form->get('occupation')->add('required'=>false, 'empty_value'=>null);
// $form->add('occupation','choice', array(
// 'required' => false,
// 'empty_value' => null,
// ));
// echo "<pre>";
// var_dump(get_class_methods($form));die;
$form->add('occupation','choice', array(
'required' => false,
'empty_value' => null,
));
$form->add('canEmail', 'checkbox', array(
'label' => 'Can Email?',
'required' => false,
));
$form->add('sendEmail', 'choice', array(
'label' => 'Send Welcome Email? ',
'required' => true,
'mapped' => false,
'expanded' => true,
'choices' => array(
"yes" => "Yes",
"no" => "No"
),
));
return $form;
}
Original Form (the one that's used as a service)
private $requireOccupation;
$this->requireOccupation = true;
->add('occupation','choice', $options['occupation'])
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$occupation = array(
"label" => "Which of these currently describes you best? (Occupation):",
"expanded" => true,
'required'=> $this->requireOccupation,
"choices" => array(
"X" => "X",
"B" => "B",
"C" => "C",
"J" => "J",
),
'constraints' => array(
new NotBlank()
));
$resolver->setDefaults(array(
'occupation' => $occupation,
));
}
I think it is better to create another form. It can herit from your already defined form to change only the field you want
class SomeFormType extends OriginalFormType {
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder
->remove('someField')
->add('someField', 'choice', [
"expanded" => true,
"choices" => $yourArray
]);
}
It has the advantage to be mapped on different object
Firstly, I realize the way I wanted to solve this issue is odd when considering I could have created another form with either the fields I wanted to use or just the one field that needed to change and register the form as a service to use it elsewhere, but I was tasked to complete it this way.
Second, my solution is quite simple. I pass values into my form with a default value set in the form.
In the form:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$requireOccupation = true;
$emptyValue = null;
//whatever other values you want to set here
$resolver->setDefaults(array(
'requireOccupation' => $requireOccupation,
'emptyValue' => $emptyValue,
));
}
and then on the field's properties:
$builder->add('occupation', 'choice', array(
"label" => "Some sort of label",
"required" => $options['requireOccupation'],
"empty_value" => $options['emptyValue'],
...
));
Now in the controller:
$form = $this->createForm('registration', $user, array(
'requireOccupation' => false, 'emptyValue' => null
));
call that where you want to generate your form while passing in the values you want to use for that form.
I am by no means an expert on Symfony and this solution would probably generate some issue with those who are. But it works for me.

Symfony Sonata project: How to add multiple input texts to block?

I would like to add a collection of input text with same name (i.e. name="blabla[]") filed to admin block with add/delete buttons.
I'm using collection form field type but can't see add/delete buttons
public function buildEditForm(FormMapper $formMapper, BlockInterface $block)
{
$formMapper->add('settings', 'sonata_type_immutable_array', array(
'keys' => array(
array('title', 'collection',
array('type' => 'text' ,
'required' => true,
'allow_add' => true,
'data' => array('First' => 'One')
)
)
)
));
}
I get below result without add/delete buttons!
Any idea how to get it working ?
I think you should use sonata_type_collection or sonata_type_native_collection instead of collection.
Here is an extract of the field doc :
14.1.7. SONATA_TYPE_NATIVE_COLLECTION (PREVIOUSLY COLLECTION)
This bundle handle the native Symfony collection form type by adding:
an add button if you set the allow_add option to true. a delete button
if you set the allow_delete option to true.

Displaying index instead of "__name__label__ *"

Using sonata admin Bundle And I have A form to Define the A "Question" model, I have an attribute "choices" which is a collection :
->add('choices', 'collection',
array('allow_add' => true,'allow_delete' => true, 'block_name' => false,
'delete_empty' => true, 'label' => 'choices'))
When I add a choice The label wrote in his top is "_name__label__*", I need to change it to the choice index, anyone found a solution for this ? thank you

Validate ajax dynamic checkbox fields (this value is not valid)

I have a form with tags which have dependencies with a category field
Category 1
tag a
tag b
tag c
Category 2
tag d
tag e
tag f
...
When loading the page, I have "Category 1" and "the list of his tags"
Then when I change the category to "Category 2", I replace the list of tags via ajax.
When I submit the form, I get "This value is not valid". I guess that it's because the fact that the form expect values from the initial list.
So, I don't know how to proceed to get my tags to be validated.
Here is the code which generate the form
->add('category', null, array(
'choices' => $this->cat_tree,
'label' => 'Category',
'required' => true,
'empty_value' => '',
))
->add('tags', 'entity', array(
'class' => 'MyappServicesBundle:Category',
'query_builder' => function(EntityRepository $er) use ($parent_id) {
return $er->createQueryBuilder('c')
->where('c.parent = :parent_id')
->setParameter('parent_id', $parent_id)
->orderBy('c.title', 'ASC');
},
'required' => false,
'multiple' => true,
'expanded' => true,
'label' => 'Tags',
))
And here is the ajax code which replace the tags list
$('#myapp_servicesbundle_category').change(function() {
$.post(
"/tag/ajax/search",
{ parent_id: $(this).val() },
function( data ) {
var newtags = '';
jQuery.each( data, function( i, val ) {
newtags += ' <input type="checkbox" value="'+val.id+'" name="myapp_servicesbundle[tags][]" id="myapp_servicesbundle_tags_'+val.id+'">';
newtags += ' <label for="myapp_servicesbundle_tags_'+val.id+'">'+val.label+'</label>';
});
$('#myapp_servicesbundle_tags').html(newtags);
}, "json"
);
});
Thanks in advance for your help
from my experience you have to use an eventListener in Symfony. There is a quite clear example in the doc (more detailed in english than in french, be careful).
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data

Zend Form Radio Default Checked

I have the next radio button group:
$enabled = $this->createElement('radio', 'enabled')
->setLabel('Enabled')
->setMultiOptions(array('1'=>'yes', '0'=>'no'))
->setValue($rank_values['enabled'])
->setAttrib('id', 'enabled')
->setAttrib('class', $action . '_enabled')
->setSeparator('');
How can I set a checked radio? Now, when I open my script, there are not selected radio. I want to select 'yes'. How?
Thank you.
it is much more easier :)
$enabled = $this->createElement('radio', 'enabled')
->setLabel('Enabled')
->setMultiOptions(array('1'=>'yes', '0'=>'no'))
->setValue($rank_values['enabled'])
->setAttrib('id', 'enabled')
->setAttrib('class', $action . '_enabled')
->setSeparator('')
->setValue("1");
In case somebody wonders, I'm using the array notation to declare all my elements in my forms and in zend framework 2 to have a default option selected in a radio button you have to add the attribute value and make it have the key of the value_options you want to be selected by default:
// Inside your constructor or init method for your form //
$this->add(
[
'type' => 'Radio',
'name' => 'some_radio',
'options' => [
'value_options' => [
'opt1' => 'Radio option 1',
'opt2' => 'Radio option 2'
]
],
'attributes' => [
'value' => 'opt1' // This set the opt 1 as selected when form is rendered
]
]
);
I found some examples a little confusing because they were using numeric keys in the value options (0, 1) so when I saw 'value' => 1 it wasn't obvious for me that this was the key in the value_options array. Hope this helps someone.
Use this:
->setAttrib("checked","checked")
So that your complete code looks like this:
$enabled = $this->createElement('radio', 'enabled')
->setLabel('Enabled')
->setMultiOptions(array('0'=>'no', '1'=>'yes'))
->setAttrib("checked","checked")
->setValue($rank_values['enabled'])
->setAttrib('id', 'enabled')
->setAttrib('class', $action . '_enabled')
->setSeparator('');
[EDIT] Using setValue:
You can alternatively use this:
->setValue('1')
This will check the option represented by value 1 which is yes.
According to the manual, you would do it this way if you were to use array notation: link to manual
$this->add(
[
'name' => 'someRadioMethod',
'type' => 'radio',
'options' => [
'label' => 'Some descriptive label',
'value_options' => [
[
'value' => '1',
'label' => 'Label for 1',
'selected' => true,
],
[
'value' => '2',
'label' => 'Label for 2',
'selected' => false,
]
],
],
]
);
I found that if you have a filter set then ->setvalue('X') does not work.
I removed ->addFilter('StringToLower')
and added ->setSeparator('')->setValue('N');
Worked a treat
Yeah. I have resolved it using jQuery:
jQuery(document).ready(function(){
var $radios = $('input:radio[name=enabled]');
if($radios.is(':checked') === false) {
$radios.filter('[value=1]').attr('checked', true);
}
});

Categories