Skip to content Skip to sidebar Skip to footer

Symfony Forms: Html5 Datalist

How can be implemented HTML5 datalist with values from the database (Doctrine)? Purpose: replace selects with many options to inputs with autocompletion.

Solution 1:

First, add your new FormType for the field:.

<?php// src/Acme/Form/Type/DatalistTypenamespaceAcme\Form\Type;

useSymfony\Component\Form\AbstractType;
useSymfony\Component\Form\Extension\Core\Type\TextType;
useSymfony\Component\Form\FormInterface;
useSymfony\Component\Form\FormView;
useSymfony\Component\OptionsResolver\OptionsResolver;

classDatalistTypeextendsAbstractType{
    publicfunctiongetParent()
    {
        return TextType::class;
    }

    publicfunctionconfigureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(['choices']);
    }

    publicfunctionbuildView(FormView $view, FormInterface $form, array$options)
    {
        $view->vars['choices'] = $options['choices'];
    }

    publicfunctiongetName()
    {
        return'datalist';
    }
}

In services.yml:

form.type.datalist_type:class:Acme\Form\Type\DatalistTypetags:-  { name:form.type, alias:datalist }

Do you have a form theme? If yes, skip to the next step, if no, create a new one in app/Resources/views/Form/fields.html.twig and change your default Twig theme to it:

# app/config/config.yml
twig:
    form_themes:
        - ':Form:fields.html.twig'

Now define a template for your new field in the form theme:

{% block datalist_widget %}
    <input list="{{ id }}_list" {{ block('widget_attributes') }}{% if value is not empty %}value="{{ value }}"{% endif %}>
    <datalistid="{{ id }}_list">
        {% for choice in choices %}
            <optionvalue="{{ choice }}"></option>
        {% endfor %}
    </datalist>
{% endblock %}

Use your field in FormType:

publicfunctionbuildForm(FormBuilderInterface $builder, array$options)
{
    $builder->add('country', DatalistType::class, ['choices' => ['a', 'b']]); 
}

Instead of ['a', 'b'] You need to load your choices from DB somehow, I'd suggest passing them in form options as the easiest solution.

Solution 2:

I spent some time trying to solve this issue, and there is a quite simple solution which solves Konstantin's issue with database access. It is to create a new form type which has EntityType as it's parent.

classDatalistTypeextendsAbstractType{
    publicfunctiongetParent() {
        return EntityType::class;
    }
}

You can then create a new template for this widget:

{# views/form/fields.html.twig #}
{% block datalist_widget %}
    <input {{ block('widget_attributes') }} list="{{ form.vars.id }}_list" value="{{ form.vars.value }}" />
    <datalist id="{{ form.vars.id }}_list">
        {% for choice in choices %}
            <option>
                {{ choice.label }}
            </option>
        {% endfor %}
    </datalist>
{% endblock %}

Finally, in the buildForm function of the form you are building, you can add your form element using the DatalistType, and using the EntityType options.

$builder->add('fieldName', DatalistType::class ,
        array('required' => false, 
              'label' => 'fieldLabel', 
              'class' => 'AppBundle\Entity\EntityName',
              'choice_label' => 'entityField'))

Solution 3:

In your formType :

->add('commerciaux', TextType::class,
            [
                'label'     => 'Apporteur d\'affaire*',
                'attr'      =>
                    [
                        'placeholder'   => 'Apporteur d\'affaire',
                        'list'          => 'bieres'           
                    ]
            ]
        )

In your View :

                    {{ form_row(formulaire.commerciaux) }}
                    <datalistid="bieres"><optionvalue="Meteor"><optionvalue="Pils"><optionvalue="Kronenbourg"><optionvalue="Grimbergen"></datalist>

Solution 4:

In your formType :

->add('commerciaux', TextType::class,
            [
                'label'     => 'Apporteur d\'affaire*',
                'attr'      =>
                    [
                        'placeholder'   => 'Apporteur d\'affaire',
                        'list'          => 'bieres'           
                    ]
            ]
        )

Declare ( controller or View) 'bieres' => $array_bieres

In your View :

                    {{ form_row(formulaire.commerciaux) }}
                    <datalistid="bieres">
                       {% for biere in bieres %}
                        <optionvalue="{{ biere }}">
                {% endfor %}
                    </datalist>

Post a Comment for "Symfony Forms: Html5 Datalist"