14

I've created an entity with an 'add new' form. The entity itself has a limited number of actual variables. I've added most of the extra data I need using custom Fields (i.e. the Field API).

What I need to do at this stage is be able to dynamically hide one field based on the value of another. i.e. if a drop-down field has it's value set to No, another field should be hidden, otherwise it should be shown.

From what I can see, it is somewhat easy to add this functionality to fields created using the Form API (i.e. via the AJAX property), however is there any way to achieve it using attached fields? I have no issues using custom Javascript if that is what is required to solve this.

1

3 Answers 3

5

jQuery works well for this:

(function($) {
  $(document).ready(function() {
    $('#select1').change(function() {
      switch ($(this).val()) {
        case '1':
          $('#field2').hide();
          break;
        default:
          $('#field2').show();
          break;
      }
    });
  });
}) (jQuery);
4
  • Yeah, I ended up using drupal_add_js on the form page and ended up doing it in jQuery. I was just wondering whether there was a more 'Drupal' way to do this.
    – NRaf
    Aug 5, 2011 at 23:00
  • I would mention that I'm not a big fan of the Drupal #states approach to visibility, which is why I didn't suggest it above.
    – keithm
    Jan 21, 2014 at 19:32
  • @keithm Could you elaborate please on why you're not a fan of states (as of 2015, D7). I'm working on a project where we're trying to make the decision to use #states vs drupal_add_js. Why do you think one is a better choice over the other?
    – blue928
    Apr 1, 2014 at 9:33
  • It's a matter of legitimate programmer preference in my opinion; my rationale may differ from yours. That said, in practice I rather dislike resorting to another syntax that duplicates functionality found in Javascript/jQuery. When I have tried #states, I also found the use cases for which it is apparently designed too limiting. When my problem extended outside these use cases, I had to rewrite the whole thing in straight Javascript anyway.
    – keithm
    Apr 2, 2014 at 13:49
19

In Drupal 7, Drupal 8 you can use $form #states instead of custom jQuery script. Example:

  $form['student_type'] = array(
    '#type' => 'radios',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

  // High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'checkboxes',
    '#options' => drupal_map_assoc(array(t('SAT'), t('ACT'))),
    '#title' => t('What standardized tests did you take?'),
    // This #states rule says that this checkboxes array will be visible only
    // when $form['student_type'] is set to t('High School').
    // It uses the jQuery selector :input[name=student_type] to choose the
    // element which triggers the behavior, and then defines the "High School"
    // value as the one that triggers visibility.
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type"]' => array('value' => 'high_school'),
      ),
    ),
  );

Here is example if you want to use #states for multiple values condition:

 $form['student_type'] = array(
    '#type' => 'checkboxes',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

  // High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'textfield',
    '#title' => t('What standardized tests did you take?'),
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type[high_school]"]' => array('checked' => TRUE),
        ':input[name="student_type[undergraduate]"]' => array('checked' => TRUE),
        ':input[name="student_type[graduate]"]' => array('checked' => FALSE),
      ),
    ),
  );

See the form_example/form_example_states.inc from examples module for more details and examples.

2
  • Speaking of #states, I've never found a way to define more complex visibility conditions, such as: hide control A when control B value is in array(x,y,z). Do you happen to know a syntax for that? Jun 29, 2012 at 15:20
  • 1
    See my update above
    – milkovsky
    Jul 20, 2012 at 8:32
4

You should try Conditional Fields, I think this module is a must-have for this task. You can set dependencies between fields on a user-friendly admin interface. For example, you can set A field to be only visible if B field has value "1234", or you can set C textfield to be visible only when D field is checked, or set E field to invisible if F is focused etc.

On the upload form, these dependencies will be set client-side, on node display, these dependencies will be set on the server-side.

You can set these dependencies at admin/structure/types/manage/[YOURCONTENTTYPESMACHINENAME]/dependencies.

Conditional Fields (Source of the image: the project's page)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.