2

I'm trying to use #states in a unlimited field collection (using the field collection module).

I'm adding this functionality to a node add form so am altering form elements using hook_form_alter.

I can get it to work for the first item in the collection using the following code but it doesn't work for items added subsequently.

$form[$k]['field_employee_name']['#states'] = array(
    'visible' => array(
        ':input[name="field_witnesses[und][0][field_person_type][und]"]' => array('value' => 'Employee'),
    ),
);
1

To get this to work we need to add the #states functionality to every field collection after the ajax callback has taken place.

To do this add an #after_build function to the field collection item in hook_form_alter:

$form['field_witnesses'][LANGUAGE_NONE]['#after_build'][] = 'field_witnesses_after_build';

And then in the after build function loop over the elements to add the #states behavior:

function field_witnesses_after_build($form, &$form_state) {
    foreach($form as $k => $v) {
        if(isset($v['#entity_type']) && $v['#entity_type']=='field_collection_item') {

            $form[$k]['field_employee_name']['#states'] = array(
                'visible' => array(
                    ':input[name="field_witnesses[und]['.$k.'][field_person_type][und]"]' => array('value' => 'Moto Employee'),
                ),
            );

        }
    }
    return $form;
}
0

Thank you for posting this, I was really going crazy trying to make #states work with hook_form_alter and your post saved the day! Just to clarify, I'm going to provide some greater detail about how I got this to work:

  1. I created a new content type. It has some of its own fields. I then added a field collection to the content type with machine name "field_volunteer_jobs".
  2. I edited the field collection and added fields for a boolean (checkbox) with machine name "field_vol_use_event_date" and a date with machine name "field_vol_date".
  3. When a person is entering data on the content page, I want the date field to be hidden whenever the checkbox is checked.
  4. I created a new module, named "states". In the module, I have the following hooks:

    function states_form_alter(&$form, &$form_state, $form_id) {
    switch ($form_id) {
    case 'school_event_node_form': 
        $volunteer_jobs_lang = $form['field_volunteer_jobs']['#language'];
        $form['field_volunteer_jobs'][$volunteer_jobs_lang]['#after_build'] = array('states_after_build');
    break;
    }
    }
    function states_after_build($form, &$form_state) { //works!
      foreach($form as $k => $v) {
        if(is_numeric($k) && isset($v['#entity_type']) && $v['#entity_type']=='field_collection_item') {
          $form[$k]['field_vol_date']['#states'] = array(
            'invisible' => array(
            ':input[name="field_volunteer_jobs[und]['. $k.
            '][field_vol_use_event_date][und]"]' => array('checked' => TRUE))
          );
        }
      }
      return $form;
    }
    

Note that in the states_after_build code above, I should really query the field #language and use that instead of [und]...

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.