Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Hi,
In a custom module's hook_form_alter() implementation, adding an '#attributes' array or using the '#disabled' property doesn't work for cck fields.
Example:
function mymodule_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'my_cck_type_node_form') {
// this works
$form['title']['#disabled'] = true;
$form['title']['#attributes']['class'] = 'my_class';
// this doesn't
$form['my_cck_field']['#disabled'] = true;
$form['my_cck_field']['#attributes']['class'] = 'my_class';
}
}
Comment | File | Size | Author |
---|---|---|---|
#26 | additional_element_properties-336355-26.patch | 3.55 KB | d.olaresko |
#15 | cck_option_widget_patch.patch | 772 bytes | igor.ro |
Comments
Comment #1
yched CreditAttribution: yched commentedThis has become a little more complex in CCK D6 : it's only once the form element has been 'processed' that it expands into its actual FAPI basic element (textfield, select, etc).
So what you need to do in your form_alter is to add a #process' function (making sure that it comes after the one that already exists, and does not override it.
Then, in this process function, you can set your '#disabled' or '#attributes'
This should work for all/most widgets and field types that ship with CCK, but might need to be adapted a little for other field types or widgets.
Do a dsm($element) in my_process_function() to see how the element is structured and where you need to alter stuff.
(dsm() is defined by devel.module)
Comment #2
KarenS CreditAttribution: KarenS commentedI think #after_build would be safer -- it works the same as #process but you are guaranteed to have the complete processed form. If you use #process, you may get there before your field has been processed and added to the form, depending on the weight of your module compared to the weight of CCK and the module that is processing the field. With #after_build you don't have that problem.
Also note that form elements may not be where you expect -- it depends on whether you are using fieldgroup (or multigroup, once it's working) or other modules that alter the form. I would assume that all other modules will be done manipulating the form by the time you get to #after_build though.
Comment #3
danielb CreditAttribution: danielb commentedyched's code does not work for me, I've tried modifying it to match the values I see in the arrays... all it succeeds in doing is making the cck field vanish completely.
My module's weight is 99 I shouldn't even need to do this - but the regular form alter doesn't work - even though I see the fapi arrays in there.
Comment #4
joachim CreditAttribution: joachim commentedWith noderef (on D5, admittedly) I can lock it, but then noderef's validation complains.
Comment #5
owahab CreditAttribution: owahab commentedSame here, the code yched mentioned doesn't work in 100% of the cases.
Even with #process replaced with #after_build, I still can only make the field vanish.
Also the my_process_function() does never get executed.
Please help.
Comment #6
owahab CreditAttribution: owahab commentedWhat worked for me is the normal FAPI #after_build implementation for the whole form:
Comment #7
fairwind@drupal.ru CreditAttribution: fairwind@drupal.ru commented(sorry for my english)
It does not work for me, both for form#after_build & field#after_build.
What i do:
As you can see i trying all places that can affect #disabled property, but without success. In "drupal_set_message" output i can see '#disabled', but not in form.
$form['title']['#disabled'] = TRUE;
in #after_build handler don't work too, but works in _form_alter.Weight of my module set to 100.
Where is my mistake? Help please!
Comment #8
markus_petrux CreditAttribution: markus_petrux commentedTry this one:
When after_build handler is invoked, the code in FAPI that deals with $elements['#disabled'] has already been processed (_form_builder_handle_input_element executes() is executed before #after_build handlers are processed, see form_builder() ), so now you need to generate the
$element['#attributes']['disabled'] = 'disabled'
for the corresponding theme function of the element.Comment #9
fairwind@drupal.ru CreditAttribution: fairwind@drupal.ru commentedThank you wery much, markus_petrux! It's works!
Comment #10
markus_petrux CreditAttribution: markus_petrux commentedSweet!
I have created a wiki page in the CCK handbook with a code snippet for this purpose.
http://drupal.org/node/357328
Comment #11
kenorb CreditAttribution: kenorb commentedsubscribing
Comment #12
dazmcg CreditAttribution: dazmcg commentedIn response to #8:
Any tips on how to get this sort of thing to work so I can set default values - useful for when I include a button which uses one field to go off and populate other fields and bring the form back to the user with these fields populated with said values....
I'm using these lines:
in the "my_form_process" function.
thanks!
Comment #13
kenorb CreditAttribution: kenorb commentedRelated topics:
http://drupal.org/node/407694
http://drupal.org/node/357328
#210639: theming cck fields - set attribute to readonly or disabled
Comment #14
kenorb CreditAttribution: kenorb commentedI have the same problem:
#470260: #attributes are not properly rendered
Comment #15
igor.ro CreditAttribution: igor.ro commentedWe could not change options of cck fields on form alter. This is a problem of cck. In drupal 6 each widget is form element.
Some widgets are simple cover over default form elements. But cck does not allow to change all options of default element.
I offer to make a rule:
If your widget use default form element, you should implement all settings of this element.
Using pre_render or after_build for modifing is not correct.
Because changes we do on form alter will be cached. But on pre_render after_build will not.
Adding patch for cck option widget.
Patches for all other widgets comming soon :)
Comment #16
kenorb CreditAttribution: kenorb commentedI agree with patch #15, some attributes are hard-coded and that's why it doesn't work.
See this: http://drupal.org/node/470260#comment-1618594
Comment #17
kenorb CreditAttribution: kenorb commentedThis could be related as well:
#104715: Disable specific checkbox, radio, option, or optgroup items
Comment #18
czeky CreditAttribution: czeky commentedsubscribing
Comment #19
markus_petrux CreditAttribution: markus_petrux commentedPlease, see: Code snippet: How to set the disabled attribute of a CCK field.
The same method can be used to alter any other attribute of the elements.
Here's another example using a similar technique: Code snippet: How to change the label of the "Add more items" button.
Comment #21
csc4 CreditAttribution: csc4 commentedNot sure why this is closed - is the proposed patch not necessary?
Comment #22
asmdec CreditAttribution: asmdec commentedWhy this is not possible?
http://drupal.org/node/616090#comment-2200612
Comment #23
danielb CreditAttribution: danielb commentedDid you not read the rest of this issue? Just use #after_build to set a callback function, and then in that function you can do whatever you need.
Comment #24
asmdec CreditAttribution: asmdec commentedYes, I read, did you read the solution proposed in that link? I don't know if that solution have some problem, but that's working for me as I can set #disabled just like I do with any other field.
I don't like to code 2 more function just to set the field disabled... sorry if I don't understand if I'm wrong, but anyone explain why that's not possible. It's just what I ask...
Comment #26
d.olaresko CreditAttribution: d.olaresko commentedThere is small patch for optionwidgets module that will add all additional element properties to select element.
Comment #27
kenorb CreditAttribution: kenorb commentedIf extra patch is still needed, create a new issue.