Dynamic form fields using #states array on empty select field Trying to make the second field only visible when there is a value in the first controller field. If nothing is selected in the initial load of the screen, the second field should be hidden. 

Because the controller api_title is a sub array I'm not sure how to set the comparison value in condition name='api_title'

$form['api_title_filter_widget'] = array('#tree' =&gt; true, '#weight' =&gt; '10');
$form['api_title_filter_widget']['api_title'] = array(
        '#type' =&gt; 'select',
        '#title' =&gt; 'API Title',
        '#default_value' =&gt; $api,
        '#options' =&gt; ["" =&gt; "- Select -"] + $published_api_proxies,
        '#ajax' =&gt; array(
            'event' =&gt; 'change',
            'callback' =&gt; 'callback_api_product_filter',
            'method' =&gt; 'replace',
            'wrapper' =&gt; 'api_products_controlled_by_filter',
        ),
    );

$form['api_product']['#states'] = array(                                              
                                   'visible' =&gt; array(   
                                        '**select[name="api_title"]' =&gt;** 
                                          array('!value' =&gt; ''),  
                                            ),
                                         );
Maybe you can try to add an id to your select field

$form['api_title_filter_widget']['api_title'] = [
  '#type' =&gt; 'select',
  '#title' =&gt; 'API Title',
  '#default_value' =&gt; $api,
  '#options' =&gt; ["" =&gt; "- Select -"] + $published_api_proxies,
  '#ajax' =&gt; [
    'event' =&gt; 'change',
    'callback' =&gt; 'callback_api_product_filter',
    'method' =&gt; 'replace',
    'wrapper' =&gt; 'api_products_controlled_by_filter',
  ],
  '#attributes' =&gt; [
    'id' =&gt; 'my_api_title'
  ],
];


Then you should be able to target it through its id :

$form['api_product']['#states'] = [
  'visible' =&gt; [
    ':select[id="my_api_title"]' =&gt; ['filled' =&gt; TRUE],
  ],
];