8

How do I disable an option in the select form field?

$form['feed'] = array(
  '#type' => 'select', 
  '#title' => t('Display of XML feed items'), 
  '#options' => array(
    'title' => t('Titles only'), 
    'teaser' => t('Titles plus teaser'), 
    'fulltext' => t('Full text'),
  ),
  '#description' => t('Global setting for the length of XML feed items that are output by default.'),
);

How can I disable, for example, the "Title only" option?

  • This would be great to know how to do, I still want the option to appear in the list, but not be selectable... – DrCord Sep 30 '14 at 15:01
6

The only way to disable one of the options for a "select" form field is to override the theme_select() function implementing hook_theme_registry_alter().

theme_select() executes the following code:

function theme_select($variables) {
  $element = $variables['element'];
  element_set_attributes($element, array('id', 'name', 'size'));
  _form_set_class($element, array('form-select'));

  return '<select' . drupal_attributes($element['#attributes']) . '>' . form_select_options($element) . '</select>';
}

The function that you implement should invoke your own function instead of form_select_options().

As theme_select() is called for each select field used in any Drupal form, I would rather consider implementing hook_form_alter() to remove the option from the form field you want.

6

Disabling an option may be tricky to achieve (Using form_alter to disable ONE option of a select field) so I'll recommend you to look at optgroups as an alternative. The Drupal form API documentation doesn't explain it but the API allows nested array for the options, have a look at form_select_options() and the <optgroup> part.
You can write this code:

$form['feed'] = array(
    '#type' => 'select', 
    '#title' => t('Display of XML feed items'), 
    '#options' => array(
        'Titles only' => array(, 
          'teaser' => t('Titles plus teaser'), 
          'fulltext' => t('Full text'),
        ),
        'Titles only 2' => array(, 
          'teaser2' => t('Titles plus teaser 2'), 
          'fulltext2' => t('Full text 2'),
        ),
    ),
    '#description' => t('Global setting for the length of XML feed items that are output by default.'),
);

Have a look at Drupal 6 forms and optgroup arrays.

Edit: to clarify this is an alternative and not a direct answer.

  • The question is about disabling one of the options, not grouping them. – kiamlaluno Aug 26 '11 at 20:06
  • I understood that but I thought optgroup provided a good alternative. – tostinni Aug 26 '11 at 20:14
  • brilliant! That's exactly what I was looking for, thank you!!! – uwe Nov 11 '11 at 3:14
3

I don't know and haven't been able to find any way to disable an individual option. It does look like they are trying to get something like this into Drupal. Maybe some alternatives, could what you want be done with css?:

$form['feed']['#attributes'] = array('class' => array('options-styles-class'));

Or, if you don't want the values to be shown at all you can unset them

unset($form['feed']['#options']['title']);
3

I got mine working with the following line

unset($form['field_name']['und']['#options'][1]);

where 1 is the index of the item which you don't want to be displayed.

  • This removes the option. The question is about disabling the option (leaving it displayed grayed out). – Koen Nov 12 '15 at 12:32
0

Convert the one single item you want to disable into an empty <optgroup>.

Pros:

  • This can be done in a hook_form_alter or directly when building your custom form, there is no need to implement a theme_select function in your theme.

Cons:

  • There's no way to represent the value='title' attribute associated with the original <option> in the resulting DOM.
  • YMMV if you're trying to disable an option that already pertains to an optgroup. Nested optgroups might indeed work, but this is untested and unconfirmed.

Implementation:

Optgroups in Drupal are denoted inside the #options array as any key => value pairs where the value is itself an array.

So from the example in the OP we would move the value of t('Titles only') to become the key and then make the value be an empty array.

$form['feed'] = array(
  '#type' => 'select', 
  '#title' => t('Display of XML feed items'), 
  '#options' => array(
    t('Titles only') => array(), // This one becomes disabled as an empty optgroup
    'teaser' => t('Titles plus teaser'), 
    'fulltext' => t('Full text'),
  ),
  '#description' => t('Global setting for the length of XML feed items that are output by default.'),
);

The resulting HTML will look something like this:

<form>
  <div>
    <label>Display of XML feed items</label>
    <select>
      <optgroup>Titles only</optgroup>
      <option value="teaser">Titles plus teaser</option>
      <option value="fulltext">Full text</option>
    </select>
  </div>
</form>
0

For disabling the whole field, use

$form['field_name']['#disabled']= TRUE;

For disabling an option in the select field, use

unset($form['field_name']['und']['#options'][1]);

where:

['field_name'] is the name of the your field

[1] is the index of the option in the list

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.