If you try to set a custom id attribute on a form element which utilizes #states, states.js will use the wrong selector while looking for your element and your states will have no effect. This is because the automatically generated id attribute for that form element (which you overrode) is set in Drupal.settings.states and in turn fed to states.js. Here's an example:
$form['my_form_elemnt'] = array(
'#type' => 'container',
'#attributes' => array('id' => 'a-custom-identifier'),
'#states' => array(
'visible' => array(
':input[name="some_checkbox"]' => array('checked' => TRUE),
),
),
);
In the above example, the selector used for the element in Drupal.settings.states will be #edit-my-form-element and not #a-custom-identifier.
Perhaps this functionality ought to be reconsidered if it hasn't already in Drupal 8. At the very least, though, the incompatibility between #states and custom id attributes ought to be mentioned in the documentation for #states in one or all of the following places:
https://api.drupal.org/api/drupal/developer%21topics%21forms_api_referen...
https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_...
Comments
Comment #1
jhodgdonDocumentation and/or code bugs need to be fixed in Drupal 8.x first, then backported to 7.x if appropriate, so I'm moving this issue there.
Also, it seems like you are reporting a bug with drupal_process_states(), not the documentation, so I'm at least moving it there for consideration. If the Form System maintainers decide it works as designed, then they should comment here and move this issue back to the Documentation component.
Comment #2
amar.deokar CreditAttribution: amar.deokar commentedI had faced same issue. I cant use my custom id to field, if i am using #states on that field. Is there any fix for this ?
Comment #3
eshta CreditAttribution: eshta at Acquia commentedI've just faced this same issue. In my case I wanted to target a particular container with AJAX replacement, but also make it toggle visibility with states. My work-around was to use #prefix and #suffix to add a custom ID around the containing element that I could target with AJAX. This left the main element's ID as the auto-generated ID that could respond to states.
I agree that this should be looked at but not sure I've got time or that its high up on the priorities of others. Figured I'd at least post my work-around in case it can help someone else searching for this type of issue.
Comment #16
larowlanAn ID should be set with #id, not #attributes according to the docs on
\Drupal\Core\Render\Element\RenderElement