1

I'm trying to use the states API in Drupal 8 but I'm having trouble, and I'm also having difficult debugging.

Use case:

On user accounts, I have a taxonomy term reference field called Gender. The three terms in the taxonomy vocabulary are female, male, and other.

I also have a text field on user accounts called Other. I want to show this Other field if and only if Gender is set to other (term ID: 27).

Here is the code I'm using:

function mymodule_form_user_register_form_alter(&$form, &$form_state, $form_id) {
  $form['field_gender_other']['#states'] = array('visible' =>
    array('input[name="field-gender"]' => array('value' => '27'),
    ),
  );
}

I based this off of code I used for Drupal 7. Unfortunately, it's not doing anything.

I looked at StateDemo.php in the fapi submodule of the Examples module for Drupal 8, but that's for building a new form, and I'm trying to modify an existing form.

  • Have you debugged the code to see that this function is being hit? – Kevin Sep 15 '17 at 16:57
  • Is that taxonomy term is select list or autocomplete? – Ajay Reddy Sep 15 '17 at 17:09
  • @AAjayReddy Taxonomy term is in a select list. – Patrick Kenny Sep 15 '17 at 17:11
3

You should use like below:

$form['field_popin_text']['#states'] = [
  'visible' => [
    'select[name="NAME_OF_SELECT_LIST"]' => ['value' => '27'],
  ]
];
  • Thanks, I had the select wrong and I was also using a - in the list name when I should have been using a _. – Patrick Kenny Sep 15 '17 at 17:28
2

I use this to display or hide fields with dependency in a dropdown select list.

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {
  if ($form_id == 'node_CONTENT_TYPE_form' || $form_id == 'node_CONTENT_TYPE_edit_form') {
    conditional_field_select(
      $form,
      'field_target',
      'field_controller',
      ['value_a', 'value_b', 'value_c'],
      'visible'
    );
  }
}

function conditional_field_select(array &$form, $targetField, $controlledBy, array $values, $state = 'invisible', $cond = 'or') {
  if (isset($form[$targetField]) && isset($form[$controlledBy])) {
    $form[$targetField]['#states'][$state] = [];
    foreach ($values as $value) {
      array_push($form[$targetField]['#states'][$state], ['select[name=' . $controlledBy . ']' => ['value' => $value]]);
      if (end($values) !== $value) {
        array_push($form[$targetField]['#states'][$state], $cond);
      }
    }
  }
}

It can easily be changed to input.

array_push($form[$targetField]['#states'][$state], [':input[name=' . $controlledBy . ']' => ['value' => $value]]);    
1

However it has some difference, If you are doing it in hook_field_widget_form_alter() Or

Drupal States API with Paragraph fields

Drupal 7 states API with hook_field_widget_form_alter()

/**
 *  Implements hook_field_widget_form_alter().
 */
function HOOK_field_widget_form_alter(&$element, &$form_state, $context) {
  if ($element['#field_name'] == 'Your_field_name') {

    $element['#states'] = array(
      'invisible' => array(
        ':input[name="NAME_OF_SELECT_LIST"]' => array('value' =>'xxx'),
      ),
    );
  }
}

Drupal 8 states API with hook_field_widget_form_alter()

use Drupal\Core\Form\FormStateInterface;
/**
 * Implements hook_field_widget_form_alter().
 */

function HOOK_field_widget_form_alter(&$element, FormStateInterface $form_state, $contexare ) {
  if (!empty($contexare['items'])) {
    // Get the field element.
    $items = $contexare['items'];
    // Checking the field machine name is field_trigger.
    if ($items->getName() == 'Your_field_name') {
      $element['value']['#states'] = [
        'visible' => [
          'select[name="'NAME_OF_SELECT_LIST'"]' => ['value' => 'xxx'],
        ]
      ];
    }
  }
}

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.