Symfony2: How to render HTML5 number input type and accept float values ​​in a form?

I want to use the symfony integer field type because it uses HTML5 "number" input type, which is more assignable for numbers.

When I create my form inside my controller:

$form = $this->createFormBuilder($stuff)
 ->add('freqLivrLO', 'integer', array(
            'label' => 'Fréquence de livraison (nb fois/semaine)',
            'rounding_mode'=>null,
            'precision'=>2,
            'constraints' => array(
                new GreaterThan(array(
                    'value' => 0, 'message' => 'La fréquence de livraison doit être strictement positive')),
                new LessThanOrEqual(array(
                    'value' => 7, 'message' => 'La fréquence de livraison doit être inférieure à 7'))
            ),
            'attr' => array('step'=>'0.01',
                'min'=>'0',
                'max'=>'7'),
        ))

      

Displays a numeric field correctly:

<input id="form_freqLivrLO" name="form[freqLivrLO]" required="required" step="0.01" min="0" max="7" value="0.07" type="number">

      

However, when I enter a float value, it is rounded to the next available integer. What should I do?

+3


source to share


4 answers


For now, the only workaround I can find is to create a custom form field type that does not account for the number. Instead of displaying it as text input, I display it as numeric input.

Sources:

Step 1.Creating a custom form field

In your package repository create your own form class (be careful in namespace) FloatType.php

<?php
namespace <Base Bundle Name>\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class FloatType extends AbstractType
{

    public function getParent()
    {
        return 'number';
    }

    public function getName()
    {
        return 'float';
    }
}

      

As you can see, your new type simply doesn't inherit from the number type. We'll use it later to cause the form field to display correctly.

Step 2. Creating a template.

To display the newly created form type correctly, you need to call the form template. Since your new type will not contain a number, this will make things much easier.



In the Ressource repository of your package, create a repository called Form inside the view repository. Inside this repository, we'll create a Twig float.html.twig template that will be used to render your custom field:

{% block float_widget %}
    {% set type = type|default('number') %}
    {{ block('form_widget_simple') }}
{% endblock float_widget %}

      

Step 3: communication and use

Finally, all that remains is to add your template as a news source in app / config / config.yml

# Twig Configuration
twig:
    #use a custom field type for float values
    form:
        resources:
            - '<Bundle full name>:Form:float.html.twig'

      

And use it in your controller:

use <Base Bundle>\Form\Type\FloatType;
...

$form = $this->createFormBuilder($stuff)
->add('freqLivrLO', new FloatType(), array(
            'label' => 'Fréquence de livraison (nb fois/semaine)',
            'precision'=>2,
            'constraints' => array(
                new GreaterThan(array(
                    'value' => 0, 'message' => 'La fréquence de livraison doit être strictement positive')),
                new LessThanOrEqual(array(
                    'value' => 7, 'message' => 'La fréquence de livraison doit être inférieure à 7'))
            ),
            'attr' => array('step'=>'0.01',
                'min'=>'0',
                'max'=>'7'),
        ))

      

And this! Any better solution would be greatly appreciated: D

+4


source


By receiving signals from Adambey, you can:

->add('lat', NumberType::class, array (
    'required' => true,
    'scale' => 7,
    'attr' => array(
       'min' => -90,
       'max' => 90,
       'step' => 0.0000001,
    ),
))

      



In your Twig template you will need to define the type, and in my case it looks like this:

{{ form_widget(edit_form.lat, { 'type':'number' }) }}

      

+4


source


I got around this by using a little cheeky JQuery to change the input type at runtime.

Here is my form entry:

->add('totalDays', 'number', array(
    'required'      => false,
    'scale'         => 1,
    'attr'          => array(
        '_type'         => "number",
        'min'           => 0,
        'step'          => 0.5,
    ),
))

      

Now here's my JQuery will change the input type to whatever was defined in the "_type" attribute:

$('input').each(function(k, v){
    if ($(this).attr('_type')) {
        $(this).prop('type', $(this).attr('_type'));
    }
});

      

+2


source


You must use form type number

instead integer

. And all will be well! just change

 ->add('freqLivrLO', 'integer', array(...

      

For

 ->add('freqLivrLO', 'number', array(...

      

0


source







All Articles