On a form, is it possible to use #states to hide/show a field based on whether or not an image field has been filled in?

More specifically, I'd like to get this node form:

image fields on node form

to only show the "Show featured image" checkbox if an image has been added. If it matters, I'm using the media browser widget for the image field.

I tried using #states, but it doesn't seem to work here. I had the following code in a hook_form_alter function, but adding an image didn't make field_image_show show up.

// Hide the "show featured image" field until a featured image is added.
if (isset($form['field_image_show'])) {
  $langcode = $form['field_image']['#language'];
  $form['field_image_show']['#states'] = array(
    'visible' => array(
      ':input[name="media[field_image_und_0]"]' => array('filled' => true),

If it's not possible with #states, any idea how to handle it with custom JS? I tried the following JS, but it also didn't work.

$field_image_show = $('#edit-field-image-show');

var imageCheck = function() {
  if ($('#edit-field-image-und-0 .preview').is(':empty')) {
  else {

// Check on initial page load.

// Check when media browser does stuff.
// @nope This doesn't seem to actually ever fire.
$('#edit-field-image-und-0 input').change(function() {

You should be able to do it with #states just fine. Maybe double check your input name or try something a little different depending on what the html for that element looks like. This is the code I am using that works.

 $form['field_hero_image']['#states'] = array(
  'visible' => array(
    ':input[name="field_image[und][0][fid]"]' => array('empty' => true),

This causes it to only appear if there is no value for the input fid. Pertinent HTML:

<input type="hidden" name="field_image[und][0][fid]" value="1088">
<input type="hidden" name="field_image[und][0][display]" value="1">
<input type="hidden" name="field_image[und][0][width]" value="915">
<input type="hidden" name="field_image[und][0][height]" value="450">


'visible' => array(
    ':input[name="field_image[und][0][fid]"]' => array('value' => 0),

may work just as well (untested)

  • Thanks for your answer! This makes sense, but I'm seeing different behavior. When I upload an image by clicking "Browse" and use the media browser to either upload or select an existing image, I don't get a value set in the field_image[und][0][fid] input. If I click "Attach" (after the media browser closes) and the preview appears, #states kicks in and works as you describe because the value then appears in the input. – Sarah German Apr 29 '15 at 20:56
  • I was not using the media module in the answer. I imagine it is an issue with using a widget instead of something like managed_file. I will look in to this farther after work. – sareed Apr 29 '15 at 22:07
  • I looked into JS from the media module, and from what I can tell, the Drupal.media.popups.mediaBrowser function in js/media.js only runs once you hit the Attach button. Is does not run when you've selected something from the media browser via the Browse button. It's in that function where you get the "uploadField.val(mediaFile.fid)" that makes #states effective. – Sarah German Apr 30 '15 at 14:14

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.