Symfony - decimal number in integer type field causes no validation error

3.4k views Asked by At

This is the field in Entity:

/**
* @Assert\NotBlank(groups={"group1"})
* @Assert\Type(type="integer", groups={"group1"})
* @Assert\Range(min=0, groups={"group1"})
* @ORM\Column(type="integer")
*/
private $cableCount;

and this is the corresponding field in the form type:

$builder->add('cableCount', IntegerType::class, [
     'label' => 'Cable Count',
     'required' => true
]);

The field is rendered with up and down arrows and user can increase and decrease the values like 1, 2, 3, ... However user can also type in 3.45 and submit the form. No validation error pops up. just the value is rounded to 3. the expected behavior is to get a validation error informing the user that this field can accept only integer numbers.

How should I solve this issue? is there a built-in feature in symfony for this or should I create a custom constraint?

2

There are 2 answers

1
Jason Roman On BEST ANSWER

Symfony's IntegerType will automatically round whatever number you send to it. On the browser side, if you use IntegerType then it will normally check for a valid integer before letting you submit the form.

In order to get what you want, you should use a NumberType. Your @Assert\Type(type="integer", groups={"group1"}) will then be ran on the server and appropriately error if you submit a non-integer.

The only issue there is you lose the up/down arrows. If you want that you'll have to override with a custom form theme for the NumberType. Something like this:

{%- block number_widget -%}
    {%- set type = form.vars.attr['int'] is defined and form.vars.attr['int']
        ? 'number'
        : type|default('text')
    -%}
    {{ block('form_widget_simple') }}
{%- endblock number_widget -%}

Then in your form type, specify that attr like so:

$builder->add('cableCount', NumberType::class, [
    'label' => 'Cable Count',
    'required' => true,
    'attr' => [
        'int' => true,
    ]
]);
2
A. Atallah On

You can try to use the Regex assert like this:

/** @Assert\Regex(pattern="/^\d*$/") */

Edit: As mentionned by @JasonRoman, you first have to deal with the IntegerType who will automatically round your inputs.