1

I have a Drupal 8 site. How do I use #states to show an field if the value of another field is greater than one of my variables?

The code below is for =$chkval

$chkval = 4;
// This would be set by a database query

'#states' => array(
    'visible'=> array(
        ':input[name = 'actual_reps'] => array('value' => $chkval)
    )
)
2
  • I don't think that drupal states support it.
    – Eyal
    Jan 20, 2016 at 20:11
  • All This magic happens in \core\misc\states.js so have a look at it and maybe you'll figure out how to extend it and if not it should not be hard to write custom JS.
    – user21641
    Jan 21, 2016 at 7:58

2 Answers 2

4

Unfortunately, Drupal does not support that.

The following states may be applied to an element:

  • enabled
  • disabled
  • required
  • optional
  • visible
  • invisible
  • checked
  • unchecked
  • expanded
  • collapsed

The following states may be used in remote conditions:

  • empty
  • filled
  • checked
  • unchecked
  • expanded
  • collapsed
  • value

The following states exist for both elements and remote conditions, but are not fully implemented and may not change anything on the element:

  • relevant
  • irrelevant
  • valid
  • invalid
  • touched
  • untouched
  • readwrite
  • readonly

When referencing select lists and radio buttons in remote conditions, a 'value' condition must be used:

@code

'#states' => array(

// Show the settings if 'bar' has been selected for 'foo'.

'visible' => array(

':input[name="foo"]' => array('value' => 'bar'),

),

),

@endcode

You can see state support value, but value is array, so can't use condition of value.

See the process states documentation page for more information

0

You can actually use this and regex by attaching the webform.states library to your form.

In your custom_module.libraries.yml:

webform.states:
  version: VERSION
  js:
    /modules/contrib/webform/js/webform.states.js: {}
  dependencies:
    - webform/webform.behaviors
    - core/drupal.states

Then in your form, simply add:

$form['#attached']['library'][] = 'custom_module/webform.states';

Now you can use all of these:

  Drupal.states.Dependent.comparisons.Object = function (reference, value) {
    if ('pattern' in reference) {
      return (new RegExp(reference['pattern'])).test(value);
    }
    else if ('!pattern' in reference) {
      return !((new RegExp(reference['!pattern'])).test(value));
    }
    else if ('less' in reference) {
      return (value !== '' && parseFloat(reference['less']) > parseFloat(value));
    }
    else if ('less_equal' in reference) {
      return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value));
    }
    else if ('greater' in reference) {
      return (value !== '' && parseFloat(reference['greater']) < parseFloat(value));
    }
    else if ('greater_equal' in reference) {
      return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value));
    }
    else if ('between' in reference || '!between' in reference) {
      if (value === '') {
        return false;
      }

      var between = reference['between'] || reference['!between'];
      var betweenParts = between.split(':');
      var greater = betweenParts[0];
      var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null;
      var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater));
      var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less));
      var result = (isGreaterThan && isLessThan);
      return (reference['!between']) ? !result : result;
    }
    else {
      return reference.indexOf(value) !== false;
    }
  };

Like so:

'#states' => [
  'visible' => [
    ':input[name="custom_field"]' => ['value' => ['greater_equal' => '40']],
   ],
]

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.