5

According to this URL Set Default Text in a Select (drop-down) box/menu I need add disabled attribute for the placeholder in symfony. This is my code.

$builder
    ->add('name', 'text', array(
        'label' => 'Business Name',
    ))           
    ->add('country', 'entity', array(
        'class' => 'AppBundle:Country',
        'property' => 'name',
        'placeholder' => 'Please select',
    )); 

Now I need to add disabled like <option value="" disabled>Please select</option>

How can I do it? What is the best way to do that?

Community
  • 1
  • 1
Dinuka Thilanga
  • 4,220
  • 10
  • 56
  • 93
  • Think about it: having a "Please select" option that is disabled, means that item (country 1) would be the thing selected instead. So it wouldn't be much of a placeholder. – conny Jun 12 '15 at 03:29
  • Have you resolve your issue since 3 month ? I would like to know the answer... – BENARD Patrick Jun 12 '15 at 05:51

7 Answers7

2

if this topic is still open... I had a similar problem today and managed it this way. (tested in symfony 2.7.10)

Obviously the placeholder is a standalone attribute in vars, therefore you cannot select it in the finishView.

In your buildForm method:

$builder->add('label', 'choice', array(
    'data' => $var, // your default data
    'read_only' => true,
    'placeholder' => false, // implement a condition to check wether you want the choice read only
));

Implement the finishView Method (Interface implementation from AbstractType):

public function finishView(FormView $view, FormInterface $form, array $options)
{
    foreach ($view->children['country']->vars['choices'] as $id => $choiceView) {
        // implement a condition to prevent the accepted/wanted option be disabled
        if ($id != $yourAcceptedValueId) {
            $choiceView->attr = ['disabled' => 'disabled'];
        }
    }
}

Unfortunately in the choices list is no placeholder option, so you have to implement two settings to achieve this.

Greets

rogaa
  • 370
  • 2
  • 16
2

It's way easier to do it like this :

$builder->add('civility', ChoiceType::class, [
    'choices' => [
        'Civility*' => '',
        'Mrs.' => 1,
        'Mr.' => 2,
    ],
    'required' => 'required',
    'choice_attr' => ['Civility*' => ['disabled'=>'']]
])

So when the form loads you'll get : <option value disabled selected="selected">Civility*</option>

Then you can add some css option[disabled] {color: #9f9f9f;}

WillMic
  • 41
  • 1
  • 7
  • This still works perfectly with Symfony5. One hint: For MacOS you also need to add `select:invalid { color: #9f9f9f; }` to style it correctly. – Manuel Apr 13 '21 at 16:07
0
/* ... */
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;

class YourBusinessFormType extends AbstractType
{
    public function finishView(FormView $view, FormInterface $form, array $options)
    {
        foreach ($view->children['country']->children as $country) {
            if ($country->vars['value'] == "") {
                $country->vars['attr']['disabled'] = 'disabled';
            }
        }
    }
/* ... */
conny
  • 9,973
  • 6
  • 38
  • 47
Dawid Sajdak
  • 3,064
  • 2
  • 23
  • 37
0

Why add an disabled option when you can set a value for empty value ?

$builder->add('states', 'entity', array(
    'empty_value' => 'Choisissez une option',
));
BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105
  • 1
    `empty_value` is the value that should be used on the server if the user submitted the form without selecting an option. This is different from forcing the user to select an option before submitting the form so the default option is never valid. – CJ Dennis May 23 '18 at 05:43
0

As explained in the doc, set the placeholder parameter to false to disable/avoid the default option:

$builder
    ->add('name', 'text', array(
        'label' => 'Business Name',
    ))           
    ->add('country', 'entity', array(
        'class'       => 'AppBundle:Country',
        'property'    => 'name',
        'placeholder' => false,
    )); 


Prior to Symfony2.6, you can use the empty_value parameter instead:
$builder
    ->add('name', 'text', array(
        'label' => 'Business Name',
    ))           
    ->add('country', 'entity', array(
        'class'       => 'AppBundle:Country',
        'property'    => 'name',
        'empty_value' => false,
    )); 
Veve
  • 6,643
  • 5
  • 39
  • 58
0

You can create your own form type and create a template for this form type. For example: you create form type with name CountrySelectorType and set parent EntityType or ChoiceType. Next you need to create a folder and file form_types/fields.html.twig (or any other name) in your app/Resources/views folder and add this path to your config.yml file, for ex:

twig:
  debug: '%kernel.debug%'
  strict_variables: '%kernel.debug%'
  form_themes:
      - 'form/fields.html.twig'

And here you can find all filed layouts for your custom field type

Next you just copy a parent widget code to your fields.html.twig file, change widget name according to your type field name and customize it like you want. I also has the same problem so my custom city selector type with disabled default option looks like below:

{% block country_selector_widget %}
    {%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%}
        {% set required = false %}
    {%- endif -%}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %} class="form-control">
        {%- if placeholder is not none -%}
            <option {% if is_filer_form_field %}disabled{% endif %} value=""{% if required and value is empty %} selected="selected"{% endif %}>
                {{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}
            </option>
        {%- endif -%}
        {%- if preferred_choices|length > 0 -%}
            {% set options = preferred_choices %}
            {{- block('choice_widget_options') -}}
            {%- if choices|length > 0 and separator is not none -%}
                <option disabled="disabled">{{ separator }}</option>
            {%- endif -%}
        {%- endif -%}
        {%- set options = choices -%}
        {{- block('choice_widget_options') -}}
    </select>
{% endblock %}
Pawel Novikov
  • 465
  • 1
  • 11
  • 26
-2

It should look like this:

$builder
    ->add('name', 'text', array(
        'label' => 'Business Name',
    ))           
    ->add('country', 'entity', array(
        'class' => 'AppBundle:Country',
        'property' => 'name',
        'placeholder' => 'Please select',
        'attr' => array('disabled'=>'disabled')
    )); 

Here is documentation for this: http://symfony.com/doc/current/reference/forms/types/form.html#attr

Pavel
  • 76
  • 8