Correctly using hook_form_alter on CCK fields for attributes like #disabled

Moonshine - August 27, 2008 - 17:30
Project:Content Construction Kit (CCK)
Version:6.x-2.x-dev
Component:General
Category:support request
Priority:normal
Assigned:Unassigned
Status:closed
Description

I've tried to apply #disabled to serveral cck fields at this point, via weighted hook_form_alter() calls, but have yet to see any field respond.

Has anyone been able to successfully apply #disabled to a cck field?

#1

yched - August 27, 2008 - 19:59

Applying to one of the CCK wrappers won't work, you need to apply it to the actual Form API element that supports #disabled (http://api.drupal.org/api/file/developer/topics/forms_api_reference.html...)
Meaning the '#type' => 'textfield', 'textarea', 'select'... element

#2

Moonshine - August 28, 2008 - 01:59

Hi yched!

Thanks for the info... However, I think that is actually the key to the problem. Those '#type' => 'textfield', 'textarea', 'select'... elements aren't available via hook_form_alter(), as CCK hasn't built them out yet.

However, in the very next FAPI step (drupal_form_builder()), core processes #disabled elements via _form_builder_handle_input_element(). So there doesn't seem to be a place where #disabled can be inserted w/ CCK elements, unless I'm missing something obvious? #process, #after_build, #pre_render are all too late.

The only thing I've had success with is using a call like this, within one of those later steps, to mimic what core actually does with #disabled fields.

<?php
$elements
['field_tester'][0]['value']['#attributes']['disabled'] = 'disabled';
?>

Which is fine, but I'm still thinking that ultimately CCK may want to honor it itself if needed.

#3

rsantiag - August 28, 2008 - 10:30

Hi Moonshine,

Where did you put that code?? I call it in hook_form_alter, but doesn´t work!!!

I can´t believe nobody needs this feature before!!!

#4

yched - August 28, 2008 - 11:52

@Moonshine : hm, of course you're right, elements are not processed yet by the time form_alter runs...
That's a little annoying I guess, not only about #disabled.

#5

Moonshine - August 28, 2008 - 16:00

@rsantiag - Code like that would have to be put in a step that comes after CCK has added the actual form elements. So you're looking at either #process, #after_build or #pre_render if you want to put in disabled code like that.

@yched - Yeah, it does make things a little awkward, as you really are religated to working with post build steps when working with CCK forms. But honestly 99% of the time it's not a big deal as you can still to what you want via those later steps. The only place where it's are real showstopper is when it's something that's dealt with in drupal_form_builder like #disabled. I'm not sure what else is really handled there off hand.

If it *was possible to build out the fields earlier, it would certainly clear up some confusion I see come up on IRC more and more. Most people just expect everything to be available in _form_alter. Not sure if that was a change from the D5 version or not.

#6

KarenS - August 28, 2008 - 16:33

This is a difference in D6 -- the CCK fields now use FAPI and get built out in #process. The only thing that happens in form_alter() is to attach the top level, unprocessed, element to the form. This was done to allow widgets to handle their own pre- and post-processing, to make CCK's core multiple value handling easier, and to make it possible to 'nest' elements (like the nodereference field which then in turn builds out either an optionwidgets widget or a text widget).

The top level element is there during form_alter, so you can attach your own #after_build or #pre_render function to the top level of the field in form_alter(), and your custom function will be get the fully-processed form element that can be altered any way you like. I wouldn't use #process, you might still be too early at that point, depending on where and how you use it.

Since CCK widgets now use FAPI, you really need to know a little FAPI to work with them, but it's not really any harder than using form_alter.

Another alternative, if you only want to disable it, would be to do it in a custom theme or preprocess instead of in form_alter. That might be easier, and it might be a more logical place to do it.

#7

rsantiag - August 29, 2008 - 11:39

Finally I got it working!!

The steps:

1. Add a new callback when the field is "#pre_reder"ing:

function mymodule_elements() {
return array(
'text_textarea' => array( // I need to disable a Text Area field type
'#pre_render' => array('mymodule_field_process'),
),
);
}

2. Treat the field when callback funtion will be called:

function mymodule_field_process($element) {

if ($element['#field_name'] == 'field_disabled' ){ // Change field_disabled with the real name of your field. You can add here any other conditions you want.
$element['value']['#attributes']['disabled'] = 'disabled';
}

return $element;
}

That's all folks!!

thanks for the help!!

#8

greggles - November 27, 2008 - 03:55

The solution from #7 fixed this for me.

I'll admit that this is far beyond my realm of knowledge of FAPI and CCK, but it sure would be nice if we could just form_alter in a #disabled like we do for every other field type.

#9

greggles - November 27, 2008 - 16:59
Status:active» fixed

Spoke a little too soon - if I try to submit fields that I've disabled in that manner I get a validation error:

"Fieldname field is required."

All the same, this seems "fixed" and/or a duplicate of #336355: Unable to add '#attributes' or use '#disabled' = true via hook_form_alter() where I found a similar answer.

#10

markus_petrux - November 27, 2008 - 21:58

Try also setting ['#required'] = FALSE

--project followup subject--

System Message - December 11, 2008 - 23:37

Automatically closed -- issue fixed for two weeks with no activity.

#11

System Message - December 11, 2008 - 23:51
Status:fixed» closed

Automatically closed -- issue fixed for two weeks with no activity.

#12

danielb - March 10, 2009 - 13:00
Title:CCK elements support #disabled?» Correctly using hook_form_alter on CCK fields

I thought i'd change this since people search for this on google

#13

greggles - March 10, 2009 - 13:12
Title:Correctly using hook_form_alter on CCK fields» Correctly using hook_form_alter on CCK fields for attributes like #disabled

Sure, great idea.

#14

greggles - March 25, 2009 - 22:10

See also http://drupal.org/node/357328 in the handbook which documents how this can be achieved.

#15

andreiashu - March 25, 2009 - 22:19

greggles: that handbook came just on time for me. It is just great when I can be reassured on some ideas.
Thanks !

#16

d2f - March 31, 2009 - 17:27

I just found that someone can patch the script

see http://drupal.org/node/404974

but I still don't know how to implement the function

#17

Eikaa - November 9, 2009 - 09:02

for me, this worked, i had to pay attention to the groups the fields were in:

<?php
function mymodule_form_alter(&$form, $form_state, $form_id) {
 
$form['#after_build'][] = 'mymodule_after_build';
}

function
mymodule_after_build($form, &$form_state) {
 
// This is for a node reference field:
 
$form['field_refref']['nid']['nid']['#value'] = $some_value;
 
$form['field_refref']['nid']['nid']['#attributes']['disabled'] = true;
 
// This is for an integer field:
 
$form['group_something']['field_number'][0]['value']['#value'] += 1;
  return
$form;
}
?>

 
 

Drupal is a registered trademark of Dries Buytaert.