it is possible to change the form element id through #attributes, but the label does not respect that.
example:
form element:
$form['test'] = array(
'#title' => 'Test',
'#type' => 'checkbox',
'#attributes' => array('id' => 'my-checkbox'),
);
rendered:
<input type="checkbox" class="form-checkbox" value="1" name="test" id="my-checkbox">
<label for="edit-test" class="option">Test </label>
problem:
Info: reference to non-existent ID "edit-test"
possible solution:
this code needs to be improved in form.inc
function theme_form_element_label() {
...
if (!empty($element['#id'])) {
$attributes['for'] = $element['#id'];
}
...
Comments
Comment #1
maciej.zgadzaj commentedI see this already fixed in the most recent 7.x-dev from 2012-09-14.
Comment #3
dawitti commentedI just tested this on the current (as of Oct 11, 2012) dev version and the issue is not fixed.
The reason why this happens is because form_builder() sets $element['#id'] regardless of $element['#attributes']['id'].
Later in the forms processing theme_form_element_label() uses $element['#id']to set the label's for attribute value.
But the theme functions for textfields, selects,... ( e.g. theme_textfield() ) only use $variables['element']['#attributes']['id']
So we can have to different id values that are being used in different places.
In order to prevent different id attributes we synchronise $element['#id'] and $element['#attributes']['id'] in form_builder().
According to the current Forms Api documentation:
...we should not use #id, so we let $element['#attributes']['id'] override $element['#id'] if set.
Old code:
New code:
Comment #4
dawitti commentedComment #5
dawitti commentedComment #6
JulienD commentedLike @dawitti I just tested on the latest D7 dev and it's still there.
This issue is also available for Drupal 8, so tagging as D8.
@dawitti, as marked in the comment "In rare cases, you can set this value yourself on a form element", why do you force the override of $element['#id'] if it is already set ?
Comment #8
jaffaralia commentedHere i corrected that patch..
Comment #10
JulienD commentedWhat did you corrected ? Have you found a case where $element['#id'] were not properly set ?
According to the first check on $element['#id'] a line above, the NULL value could not be assigned to $element['#id'] in the second ternary.
Comment #11
jaffaralia commentedYour patch #6 is correct.
The form element rendered correctly. Still finding why its fails
Comment #12
mgiffordThis still a concern in D8? Unassigned issue too.
Comment #13
David_Rothstein commentedI'm making the title more general, given what the patch is trying to accomplish. (There are other parts of Drupal that make decisions based on #id too.)
Not sure if there are other places in the codebase this would need to be changed as well.
Comment #14
David_Rothstein commentedI would think the first drupal_html_id() call shouldn't be there - if ['#attributes']['id'] is set shouldn't that just be used as is?
Comment #15
bogdan.racz commentedIs this really referring to 8.1.x? I only find the issue in Drupal 7, shouldn't the version of the issue be changed to 7.x-dev?
Regarding the drupal_html_id() removal in patch #6, I've attached a new one for 7.x-dev. But a question remains ... what if, in a custom module, the ID is erroneously misspelt and it doesn't conform to the standard?
Comment #17
bogdan.racz commentedComment #18
rakesh.gectcrComment #19
rakesh.gectcrI am not able find this issue any more with Drupal 8.x So I changed to Drupal 7.x-dev,
Comment #20
bogdan.racz commentedComment #21
David_Rothstein commentedThen Drupal will probably output an invalid HTML ID. But isn't that what it will do already in that case? I'm not sure it's related to this issue, or that the code should try to change an ID that was specifically set.
For Drupal 8 this code is in https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Form!FormBuilder....
Comment #22
bogdan.racz commentedComment #23
bogdan.racz commented@David_Rothstein thanks for pointing out where the problem was.
I've attached a patch for 8.1.x
Comment #24
bogdan.racz commentedComment #26
bogdan.racz commentedComment #27
bogdan.racz commentedI've attached a new patch, to fix the failing tests.
The problem that I found, is that in some places the ['#attributes']['id'] is an array, like bellow:
in renderDisplayTop() in ViewsEditForm.php
Is this ok?
Comment #28
dawehnerI'm wondering whether the alternative implementation could be to reference
$element['#id']from$element['#attributes']['id']so multiple code paths changing it would not just ignore each other.
Comment #37
ocastle commentedPatch 27 works for me on Drupal 8.8.1
Comment #38
ocastle commentedUpon further review, this doesn't work when used with Ajax. The label 'for' attribute is regenerated but the input is left as defined.
Comment #45
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.