Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ChoiceType with Integers as choice values

Running into a minor problem on Symfony 2.8. I have a couple of db fields, one is an integer and one is decimal. When I build my form, these fields are dropdowns so I'm using ChoiceType instead of IntegerType or NumberType.

The form actually works fine, the difference internally between the two apparently doesn't cause an issue, and I can pick a value and it properly saves to the db.

The issue now is in a Listener. When certain fields are changed, I need to kick off an extra process, so I have an event listener and am using the getEntityChangeSet() command.

What I'm noticing is that it's reporting back these fields as changed, because it's recognizing a difference between 1000 and "1000" which I can see on a Vardump output:

 "baths" => array:2 [▼
    0 => 1.5
    1 => "1.5"
  ]

This is causing the listener to always trigger my hook even when the value really hasn't changed. If I change the form type to Integer, that's just a text entry and I lose my dropdown. How do you force a dropdown ChoiceType to treat a number as a number?

In my entity, this is properly defined:

 /**
 * @var float
 *
 * @ORM\Column(name="baths", type="decimal", precision=10, scale=1, nullable=true)
 */
private $baths;

In my regular form:

 ->add('baths', BathsType::class)

which pulls in:

class BathsType extends AbstractType
{


    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'choices' => array_combine(range(1,10,0.5),range(1,10,0.5)),
            'label' => 'Bathrooms:',
            'required' => false,
            'placeholder' => 'N/A',
            'choices_as_values' => true,

        ]);
    }

    public function getParent()
    {
        return 'Symfony\Component\Form\Extension\Core\Type\ChoiceType';
    }


}
like image 719
Kris White Avatar asked Oct 22 '25 16:10

Kris White


2 Answers

You should only pass values to your choices option, they will be indexed by numeric keys used as strings for "hidden" html input values which will do the mapping behind the scene.

Then use choice_label to set the labels (visible values) as the choices casted to string :

class BathsType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'choices' => range(1,10,0.5),
            'label' => 'Bathrooms:',
            'required' => false,
            'placeholder' => 'N/A',
            'choices_as_values' => true,
            'choice_label' => function ($choice) {
                return $choice;
            },
        ]);
    }

    public function getParent()
    {
        return 'Symfony\Component\Form\Extension\Core\Type\ChoiceType';
    }
}
like image 190
Heah Avatar answered Oct 25 '25 09:10

Heah


In symfony 4 choices_as_values does not exist, so the solution would be the same as Heah answer but without that option:

class BathsType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'choices' => range(1,10,0.5),
            'label' => 'Bathrooms:',
            'required' => false,
            'placeholder' => 'N/A',
            'choice_label' => function ($choice) {
                return $choice;
            },
        ]);
    }

    public function getParent()
    {
        return 'Symfony\Component\Form\Extension\Core\Type\ChoiceType';
    }
}
like image 38
Diguin Avatar answered Oct 25 '25 08:10

Diguin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!