Recently had a need for this in one of my own projects and didn't really like that the only way to achieve this was to override the theme function for the select box in question.

This patch adds a new FAPI type '#disabled_values' which would only be valid for select options. An example of using it would be as follows:

$form['test'] = array(
  '#type' => 'select',
  '#title' => 'TEST',
  '#options' => array('test' => 'Test', 'test1' => 'Test 1', 'test2' => 'Test 2', 'test3' => 'Test 3'),
  '#disabled_values' => array('test1', 'test2'),
  '#default_value' => 'test2'
);

In the above example code, 'test2' is the default value, as well as one of the disabled options, in this case, 'test2' will actually be enabled as it needs to be a selectable option to maintain integrity of submitted data. I'm sure there are other ways to handle this, but this seems the cleanest.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cdale’s picture

FileSize
888 bytes

Here is a patch against 6.3.

cburschka’s picture

'#disabled_values' which would only be valid for select options

And checkboxes and radiobuttons, ideally; basically anything with #options.

Edit: Please make a patch against 7.x-dev, seeing as it is already radically different in multiple places.

moshe weitzman’s picture

Seems a bit cleaner to allow the options value to be an array and set disabled there. just like how table cells can be an array. if we do a separate property, i suggest putting options in the name.

cdale’s picture

Is 7.x-dev the same as HEAD? If so, the first patch, 'form.inc_1.patch' is against that. If it's not HEAD, which CVS tag do I checkout to make the patch?

The second is against 6.3.

catch’s picture

@cdale - D7 is HEAD, yes.
At first glance, I think I agree with Moshe's comments in #3.

cdale’s picture

FileSize
889 bytes

Seems a bit cleaner to allow the options value to be an array and set disabled there.

I thought about this too, but when looking at the code, I saw that when the options value is an array, it actually creates an optgroup with the label of the group being the key, and contained options being the array of values. It might be possible to use an object and change a little bit of the logic, as there is also an is_object check, but it doesn't seem to do anything special with it. It just felt cleaner to add a new property. I'm open to suggestions though.

I agree on the options in the name part. I've re-roll the patch using #disabled_options instead of values. I had actually considered using the #disabled property, but was unsure if setting this to be an array would break other code where it expected the value to be a boolean.

Rowanw’s picture

Too bad IE6 and 7 don't support disabled options for select fields. :)

cburschka’s picture

@ #4: Yes, HEAD = 7.x. I didn't check your first patch; I just saw that the second was for 6.3 and made assumptions. ;)

Also, we don't rely on client-side validation anyway. If the browser sucks, about the worst thing that can happen is that the user submits the form and gets a message about an invalid selection.

cburschka’s picture

I had actually considered using the #disabled property, but was unsure if setting this to be an array would break other code where it expected the value to be a boolean.

As far as I can tell, #disabled is unused. An entire field is disabled by setting ['#attributes']['disabled']. However, #disabled would be easily mistaken for a boolean option to disable the entire field, so we shouldn't use it for this.

---

Here's a new patch that adds this functionality for checkboxes and radios, also adding it as a system default to system_elements.

There's also a code-style fix in the checkboxes function, where I split a big single line array into multiple lines.

cdale’s picture

Great. Patch works for me with Radios, Checkboxes, and Selects each with multiple different options and configurations. :)

cdale’s picture

Having thought about it, Should the #default_value for radios always be enabled? Even if it is in the #disabled_options? That way, an accidental click can be corrected, rather than having a potentially wrong value submitted that, even on validation error could most likely not be corrected?

cburschka’s picture

Status: Needs review » Needs work

The problem does make sense.

A disabled select option will never be selected by default, and a disabled checkbox may well be desired to be checked by (unalterable) default. So this affects only radio buttons.

I'm not sure how to resolve precedence, but I prefer your suggestion of ignoring commands to disable the default. The alternative of discarding the default when it is disabled seems rather counter-intuitive to me; if a module really wishes an option to be disabled, it should just avoid setting it as a default.

cdale’s picture

Status: Needs work » Needs review
FileSize
2.91 KB

Updated patch that does not disable the radio option if it is the default value.

cburschka’s picture

That works well. Code style seems to be okay too.

I'm not quite sure if the modification I made to system_elements is correct. There are some properties that elements support, but that are not mentioned in system_elements - therefore not sure if disabled_options should be explicitly mentioned. A Form API guru should sign off on that.

treksler’s picture

subscribing

cburschka’s picture

Patch broken. Fortunately this is merely because the aforementioned code-style fix has been implemented on its own by now. Hence, rerolling without this fix.

Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch failed testing.

Damien Tournoud’s picture

Category: feature » bug

Being able to disable options per element is a very common requirement, and have been supported by HTML for ages. Promoting to a bug.

antgiant’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, form-disabled-options-284917-16.patch, failed testing.

effulgentsia’s picture

Subscribing. Will look at more thoroughly later.

effulgentsia’s picture

Marked #104715: Disable specific checkbox, radio, option, or optgroup items a duplicate of this one, but folks here may want to review the comments on that issue for additional background.

effulgentsia’s picture

Title: Add disabled attribute to select options » Allow FAPI select, radios, and checkboxes to specify some options as disabled
Status: Needs work » Needs review
FileSize
1.92 KB

Refinement of #16.

Status: Needs review » Needs work

The last submitted patch, form-disabled-options-284917-23.patch, failed testing.

effulgentsia’s picture

Status: Needs work » Needs review
FileSize
2.29 KB

fixed typo and applied same code in form_process_tableselect() too, since that mimics checkboxes/radios.

surendarm’s picture

mikeschneik’s picture

sorry, was a mistake

Mike Wacker’s picture

subscribe

bleen’s picture

I think we should revisit Moshe's comment in #3. This would allow us more flexibility in the future to do things like include an individual description on a per-option basis (as just one example).

Adding #disabled seems very limiting

= my 2 cents

sun’s picture

+++ includes/form.inc	21 Feb 2010 22:03:45 -0000
@@ -1875,7 +1875,16 @@ function form_select_options($element, $
+      // @todo See http://drupal.org/node/426056 about server-side enforcement
+      //   of #disabled. Until then, if an option is already selected, do not
+      //   disable it.

If this @todo can be resolved by now, and if this patch stays that simple, then I see no reason why we shouldn't fix this bug for D7. (super-minimal API addition)

Powered by Dreditor.

ohnobinki’s picture

+1

AaronBauman’s picture

Issue tags: +Needs tests

tagging

andypost’s picture

andypost’s picture

Why not make option element as array with attributes as most of core elements do?

optgroup should have it's own attributes!

Is there any reasons except historical to hardcode this elements?

Also filed #875914: form_select_options() poorly documented

william.lai’s picture

just found a link that doing the similar thing http://www.akchauhan.com/assign-attributes-to-options-using-formapi-in-d...

is it a good approach?

andypost’s picture

william.lai this is bad hack, array as option leads to optgroup

william.lai’s picture

thanks andypost.

But I think the option group is sth similar this, right?

  <optgroup label="Swedish Cars">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
  </optgroup>
  <optgroup label="German Cars">
    <option value="mercedes">Mercedes</option>
    <option value="audi">Audi</option>
  </optgroup>

ref:http://www.w3schools.com/tags/tag_optgroup.asp

We still cannot set the attribute of options, right? eg. title, class

    <option value="mercedes" title="mercedes">Mercedes</option>
    <option value="audi" title="audi">Audi</option>
andypost’s picture

@william.lai NOT, please read while issue

al_wild’s picture

Assigned: Unassigned » al_wild
sbrattla’s picture

What is the current status on the #disabled_options property? It would be great if someone who's been following this post could make a little summary of what remains to be done before we can get the #disabled_options available. I'm on a project where that property would be really helpful.

Cyberwolf’s picture

Subscribing.

David_Rothstein’s picture

As part of this patch, and to prove it's working, we should fix the instances in core that currently have to work around this limitation.

I know of one - it's the $form['account']['roles'] section of user_account_form(). See #119038: Code cleanup: 'authenticated users' role.

Dave Kopecek’s picture

Subscribing

casey’s picture

Subscribe. I have been in need of something similar; attributes (e.g. classes to option element). Currently I use a custom #theme callback.

But can't we use something similar as used in theme_table? Allowing the #options array to contain arrays? So that,

Each option can be either a string or an associative array with the following keys:
* "data": The string to display as the option text.
* Any HTML attributes, such as "class", to apply to the option.

/Edit, sorry I didn't read the issue.

casey’s picture

After some thinking I like #disabled_options better too; disabled options is info relevant for FAPI.

1. But shouldn't those be validated server-side?

2. For still being able to pre-disable options but allow them to be enabled using Javascript we might introduce a #options_attributes property.

So options in #disabled_options will be show, but won't be selectable even after they are enabled using Javascript. In case the latter is needed, #options_attributes (e.g. array('myoption' => array('disabled' => 'disabled'))) can be used.

I am not on my own pc so I can't provide a patch.

casey’s picture

I wasn't right again; #disabled isn't validated either.

sun’s picture

Version: 7.x-dev » 8.x-dev

No idea why this is still targeting D7.

drm’s picture

I'd just like to add that if you don't want to patch core, it is fairly easy to make an option disabled with jquery. Just stick this in your form-builder function.

drupal_add_js('$(document).ready(function(){
                       $("#edit-your-checkbox-id").attr("disabled", "disabled");
                    });', 'inline');
mattyoung’s picture

Sub

acoustika’s picture

+1

acoustika’s picture

Holy cow.... It works :-)

Did the patch in #25 and made this function in template.php for a long select list i have from a vocabulary set up like this

area1
   town1
   town2
area2
  town4
  town4
etc.

I wanted to disable the areas, and this patch (#25) and this function made that doable

function theme_form_MY_FORM_ID_alter(&$form, $form_state, $form_id) {	
	$form['SELECT_LIST_ID']['#disabled_options'] = array(1,4,etc.);
}

So with this patch disabling certain values in a select list becomes not to hard (when you know how to do it)

bleen’s picture

acoustika: if you have taken a good look at the code and confirmed that it worked then you should mark this issue as RTBC

xjm’s picture

Tracking; this would make my life a lot easier.

(Help fix "+1 subscribe" posts: see http://drupal.org/node/34496 and http://3281d.com/2009/03/27/death-to-subscribe-comments )

theunraveler’s picture

Is there any reason this could not be committed to the next 7.x release? The patch in comment #25 seems like it would not break existing implementations.

bleen’s picture

theunraveler: see my comment in #53

theunraveler’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
2.46 KB

I re-rolled the patch for 8.x. Tested it out, and it appears to be doing what it claims to do.

theunraveler’s picture

Status: Reviewed & tested by the community » Needs work

After further consideration, I agree with moshe's (and others') comments in #3. This fix is short-sighted. Since the 'radios', 'checkboxes', and 'tableselect' elements are all (essentially) wrappers around 'radio', 'checkbox', and a heavily-themed 'checkbox', all of which support properties like '#title', '#disabled', '#description', etc., I see no reason why we can't add that functionality.

The only issue, then, becomes what to do about optgroups.

Moving back to "needs work". If anyone disagrees, feel free to move it back.

xjm’s picture

theunraveler’s picture

Status: Needs work » Closed (duplicate)

Yes, I very much agree. Unless anyone objects, I'm marking this as a duplicate of #342316: Introduce proper Form API #types for 'option' and 'optgroup', and make #options consistent..

joachim’s picture

It turns out this is already possible, but not documented. I only stumbled on it in a comment in that other issue. Filed #1349432: Mention checkboxes/radios options pre-setting in forms_api_reference.html for documentation.

guldi’s picture

why isn't this in core already? it's been a topic for years!

i suggest #25 to apply to D7-dev.

DrCord’s picture

Issue summary: View changes

Shouldn't this patch be finished and applied to core?

jannis’s picture

this is a good solution that seems to have slipped through the cracks. subscribing

m4olivei’s picture

Re-roll patch for Drupal 7.38.

phaeton005’s picture

I have checked the latest patch for my own application... Seems to work.
However, I have had to use the 'und' aspect of my field. This is the code I used:
$form["field_who_to_share_with"]['und']['#disabled_options'] = array(2);

steveoriol’s picture

All the patchs are for D7, do you know how to specify some options as disabled on D8 ?...

duncan.moo’s picture

Per this answer on drupal.stackexchange, this works for both Drupal 7 and Drupal 8. Using a form alter:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#disabled'] = TRUE; //disables all options
  $form['checkboxes_element'][abc]['#disabled'] = TRUE; //disables option, called abc
}
thalles’s picture

#68 works fine to me in form settings.
Thanks!