So the task I had was to conditionally hide two fields in drupal CCK custom content type. When the record had one of three values in a select field, it should show the upload file fields. Otherwise it should hide it.
This is pretty straightforward in a regular module. One makes the changes in hook_form_alter. To hide, we would unset the fields.
function random_module_form_alter(&$form, $form_state, $form_id) { // make your changes here: change values, set defaults, hide fields // the easy life! }
This won't work if one is using CCK. The reason for that, as webchick explains in her blog entry, is that CCK fields are not present at hook_form_alter. She then presents the right approach, which is to use form API #after_build.
/** * Implementation of hook_form_alter(). */ function example_form_alter(&$form, $form_state, $form_id) { // Check for a particular content type's node form. if ($form_id == 'example_node_form') { // Add an after_build function to process when everything's complete. $form['#after_build'][] = 'example_after_build'; } } /** * Modify CCK form elements on the example node form. */ function example_after_build($form, &$form_state) { // TODO: Stuff! return $form; }
This is the basic code structure for solving this problem. From this point, it should have been easy, right? Wrong. I ran into two problems: getting the values from the form and reaching the right form field to turn off.
The most natural solution for getting a value and setting a field to hide is to just reach for that field in the form
$value = $form["height"][0]["value"]; unset($form["height"]);
However, when dealing with CCK fields, the first one won't work, and the second one, in drupal 6, according to a stack overflow thread, can be dangerous since it can do unpredictable things.
So I examined the form object via print_r($form); followed by an exit; statement. There I saw that I could reach for the field that I wanted via $form["#node"]. This returns the node object.
$value = $form["#node"]->height[0]["value"];
Then I attempted to hide the field by unsetting the node values. This was a mistake, since the node object doesn't have anything to do with the form. Yet I couldn't find the form entry for the fields that I needed. Reading through the comments of webchick's entry, someone mentioned the field groups. Ah! Looking back, it seems self evident. I needed to reach the field via the group field first. And following the direction given in the stack overflow page, hiding the field uses the following syntax.
$form["measurements_group"]["height"][0]["#access"] = false;
Altogether, the code to hide a field in a CCK content type form looks like this:
function example_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'measurements_node_form') { // Add an after_build function to process when everything's complete. $form['#after_build'][] = 'example_after_build'; } } function example_after_build($form, &$form_state) { $show = array("Edit more", "Incorrect"); $term_id = $form["#node"]->height[0]["value"]; $term = taxonomy_get_term($term_id); if ($term->name != "" && !in_array($term->name, $show)){ $form["measurements_group"]["height"]["#access"] = false; } return $form; }
Sources:
drupal 6 api on hook_form_alter
stack overflow
webchick's blog on hook_form_alter and CCK on drupal.org