Reputation: 18729
I am struggling with using choice
form fields in Symfony 2.7. The goal is to let the user select some very basic options:
Data Object
class MyDataObj {
protected $option = null;
public function getOption() {
return $this->option;
}
public function setOption($option) {
$this->option = $option;
}
}
Form creation within some controller:
...
$dataObject = new MyDataObject();
$form = $this->createForm('custom_data_type', $dataObject);
$form->handleRequest($request);
if ($form->isValid()) {
...
}
The custom FormType
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('option', 'choice', array(
...
'choices' => array(
'Option A' => 'option_value_1',
'Option B' => 'option_value_2',
'Option C' => 'option_value_3',
),
'choices_as_values' => true,
));
...
}
The rendered Result:
<select id="custom_data_type_option" class="form-control" name="custom_data_type[option]">
<option value="0">Option A</option>
<option value="1">Option B</option>
<option value="2">Option C</option>
</select>
So the Options get the values 0-2 instead of option_value_N
. How can I change this?
I already tried to add a choice_value
callback. However, the result was even more irritating :
->add('option', 'choice', array(
...
'choices' => array(
'Option A' => 'option_value_1',
'Option B' => 'option_value_2',
'Option C' => 'option_value_3',
),
'choices_as_values' => true,
'choice_value' => function ($allChoices, $currentChoiceKey) {
if (null === $currentChoiceKey)
return 'nothing';
if ('Option A' === $currentChoiceKey)
return 'option_value_1';
if ('Option B' === $currentChoiceKey)
return 'option_value_2';
if ('Option C' === $currentChoiceKey)
return 'option_value_3';
return 'unknown';
}
));
THE RESULT:
<select id="custom_data_type_option" class="form-control" name="custom_data_type[option]">
<option value="nothing">Option C</option>
<option value="nothing">Option C</option>
<option value="nothing">Option C</option>
</select>
I do understand, that before Symfony 2.7 the handling was different and a choice key => value
was rendered as <option value="key">value</option>
. To turn of this behaviour in Symfony 2.7 the 'choices_as_values' => true
option has to be used.
But I do not understand, why the values are not simply used as specified in choices
(which is a key => value
array)...
And what is wrong with the choice_value
callback that delivers such a strange result?
Upvotes: 1
Views: 2562
Reputation: 4315
This is how I do and it's working well (but Symfony 2.8). I defined my array without reversing keys and use the php array_flip()
method :
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$myArray = [
'option_value_1' => 'Option A',
'option_value_2' => 'Option B',
'option_value_3' => 'Option C',
];
$builder->add('mySelect', ChoiceType::class, [
'choices' => array_flip($myArray),
'choices_as_values' => true,
]);
The rendering using Twig:
{{ form_widget(form.mySelect) }}
PS: advice: avoid using names as 'option' as varaiable or key names...
Upvotes: 1
Reputation: 9585
So the Options get the values 0-2 instead of option_value_N. How can I change this?
The way to generate the "choices" option has changed since the version 2.7, if the choice_value
option is null
, an incrementing integer is used as the value.
And what is wrong with the choice_value callback that delivers such a strange result?
if you need to keep the values in the final <select>
then only have to do this:
->add('option', 'choice', array(
'choices' => array(
'Option A' => 'option_value_1',
'Option B' => 'option_value_2',
'Option C' => 'option_value_3',
),
'choices_as_values' => true,
// this will keep the same functionality as before
'choice_value' => function ($value, $key, $index) {
return $value;
}
));
THE RESULT:
<select id="custom_data_type_option" class="form-control" name="custom_data_type[option]">
<option value="option_value_1">Option C</option>
<option value="option_value_2">Option C</option>
<option value="option_value_3">Option C</option>
</select>
Refs:
Upvotes: 2