1

Need:

If we select a value in a drop-down list field(A), then we need to display and set as required field(B).

Note: the field(B) is a date range.

I tried to add states with a hook form alter

$form['field_b']['#states'] = [
      'visible' => [
        ':input[name="field_a"]' => ['!value' => '_none']
      ],
      'required' => [
        ':input[name="field_a"]' => ['!value' => '_none'],
      ],
  ];

As you see I use: '!value' to negate a value and '_none' for no value. So, It will not be required if there is no value selected

This code didn't work. It display the field B, but it is not mandatory.

We found that there is an issue with core https://www.drupal.org/project/drupal/issues/2855139

At the end issue was closed, but it didn't work for us. It worked with texte fields but not for our rage date.

3 Answers 3

0

So, if dont want to use conditional_fields module and only conditional fields core You can do it, but required field have sometime a little bug.

In the issue someone take some code from conditional_fields that fix this issue, and use it.

your_module/js/conditional_fields.js

(function ($, Drupal) {

// Fix core's required handling.
$(document).bind('state:required', function (e) {
  if (e.trigger) {
    var fields = $(e.target).find('input, select, textarea, fieldset');
    fields.each(function() {
      var label = 'label' + (this.id ? '[for=' + this.id + ']' : '');
      var $field_labels = $(e.target).find(label);
      var $fieldset_legends = $(e.target).find('legend span.fieldset-legend');
      var $labels = $field_labels.add($fieldset_legends);
      if (e.value) {
        $(this).attr({ required: 'required', 'aria-required': 'aria-required' });
        $labels.each(function() {
          $(this).addClass('js-form-required form-required');
        });
      } else {
        $(this).removeAttr('required aria-required');
        $labels.each(function() {
          $(this).removeClass('js-form-required form-required');
        });
      }
    })
  }
});

})(jQuery, Drupal);

In your_module.module in a form alter add:

$form['#attached']['library'][] = 'your_module/conditional_fields';

$form['field_b']['#states'] = [
      'visible' => [
        ':input[name="field_a"]' => ['!value' => '_none']
      ],
      'required' => [
        ':input[name="field_a"]' => ['!value' => '_none'],
      ],
  ];

Don't forget add the js code in your_module.libraries.yml file

Adding JS to a Drupal module

With our above code it worked!.

0

In Drupal 9, there's no need to add so much custom code like the other answer.

Here's an easy example, with the condition being a checkbox checked/unchecked:

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('my_module.settings');

    $form['api'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use the API'),
      '#description' => $this->t('Uncheck to skip the API call and fall back to a hard-coded response.'),
      '#default_value' => $config->get('api'),
    ];

    $form['appid'] = [
      '#type' => 'textfield',
      '#title' => $this->t('API Key'),
      '#default_value' => $config->get('appid'),
      '#description' => $this->t('The API key'),
      '#states' => [
        'visible' => [
          ':input[name="api"]' => ['checked' => TRUE],
        ],
        'required' => [
          ':input[name="api"]' => ['checked' => TRUE],
        ],
      ],
    ];

    return parent::buildForm($form, $form_state);
  }
  • You can use value instead of checked, or some other property.
  • Use ! to negate it, like !value
  • Use _none to represent no value, so use ['!value' => '_none'] to ensure there's a value
0

So for fields having required attribute in widget array, You may use below code :

  $form['field_name']['widget']['#states'] = [
    'required' => [
      ':input[name="conditional_field_name[$option_id]"]' => ['checked' => TRUE],
    ],
  ]
  //Please vote if it works.

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.