I am trying to style CCK fields, but can't do so with checkboxes / radio buttons, as the id selector is not displayed for all radio buttons / checkbox cck fields.

Here's an example of the output of a text_textfield field, with the ID displayed:
<div id="edit-field-garden-size-0-value-1-wrapper" class="form-item"> ... </div>

Here's an example of the output of an optionwidgets_buttons field, with the ID not displayed:
<div class="form-item"> ... </div>

Did anyone have the same issue and a potential solution for this? Thanks.

Comments

yched’s picture

Status: Active » Closed (works as designed)

We rely on core's radio and checkboxes form elements. Nothing we can do here. I think there's a core issue about that somewhere.
At worst, maybe you can override the form.inc's theme_checkboxes() function in your theme ?

haagendazs’s picture

Thanks for following up. I did more research after this looking in the core section and found a thread here http://drupal.org/node/215301 that has a patch attached with it that fixed the issue.

nancydru’s picture

Version: 6.x-2.2 » 6.x-2.6
Status: Closed (works as designed) » Active

The patch mentioned in #215301: Checkboxes/radios wrapper container does not get an 'id' attribute does not apply any longer. Plus it appears that this is supposedly fixed (form.inc), yet it seems CCK is not providing an ID attribute.

yched’s picture

Plus it appears that this is supposedly fixed (form.inc)

Fixed in D6 ? Can you point to a thread or commit message showing that ?

nancydru’s picture

No, I can't, but if you look at the patch in that thread compared to the code that exists now, you will see a significant change that appears to have attempted to fix this (and didn't).

Alex Andrascu’s picture

subscribing...that's an issue

Alex Andrascu’s picture

and here is the way i solve it...not sure it's properly done but at least got me back on track. Maybe some keen eye should look upon it and make a patch

files edited:

// $Id: form.inc,v 1.265.2.32 2010/03/01 09:24:22 goba Exp $    
from line 2198 
function theme_form_element($element, $value) {
  // This is also used in the installer, pre-database setup.
  $t = get_t();
  $output = '<div class="form-item"';
  if (!empty($element['#id'])) {
    $output .= ' id="'. $element['#id'] .'-wrapper"';
  }
  else { // if we can't get the #id from $element['#id'] just build it from $element['#name']
    $id=explode("[value]", $element['#name']);
    $output .= ' id="'. $id[0] .'-wrapper"';
  }
  $output .= ">\n";
  $required = !empty($element['#required']) ? '<span class="form-required" title="'. $t('This field is required.') .'">*</span>' : '';

  if (!empty($element['#title'])) {
    $title = $element['#title'];
    if (!empty($element['#id'])) {
      $output .= ' <label for="'. $element['#id'] .'">'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
    }
    else {
      $output .= ' <label>'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
    }
  }

  $output .= " $value\n";

  if (!empty($element['#description'])) {
    $output .= ' <div class="description">'. $element['#description'] ."</div>\n";
  }

  $output .= "</div>\n";

  return $output;
}
lotyrin’s picture

Project: Content Construction Kit (CCK) » Drupal core
Version: 6.x-2.6 » 6.16
Component: optionwidgets.module » forms system
Status: Active » Needs work

#7 fixes this issue for me (I have ids now), but an id generated by this change is inconsistent with the ids that work without the change.

For instance, a normal (non optionwidgets) field with a working id on gets "edit-field-field-name-0-value-wrapper", an id on one of the fields that is fixed by #7 gets "field_field_name-wrapper"

Also, this is definitely a core issue, since #7 patches core.

Someone with more familiarity with forms system than I have should decide whether or not this is a duplicate of #215301: Checkboxes/radios wrapper container does not get an 'id' attribute. I haven't tested the patch from that issue (since I believe it only applies to 7).

jteague’s picture

Category: bug » task
Status: Needs work » Needs review

In running into this with the latest version of CCK 6.3.x dev, I also needed to add a unique ID wrapper to the radio and check box groups. Taking from #7, I simply inserted this in form.inc at line 2206 in the "function theme_form_element" as a test:

  else { // if we can't get the #id from $element['#id'] just build it from $element['#name']
    $id=explode("[value]", $element['#name']);
    $idnew = str_replace(array('][', '_', '[0', ']', ' '), '', $id);
    $output .= ' id="'. $idnew[0] .'-wrapper"';
  }

The string replace addition implodes the returned field name (the first child) down to a single 'string'-wrapper. This gets rid of the brackets and other unwanted characters in the string. Of course, you can add hyphens or underscores if you want to break it up into something prettier. For me, I just needed a unique ID. Also, since this test was run on the core, I moved it into hook_alter function in my custom site module.

tmsimont’s picture

I know this is a lame solution to this issue, but might be the easiest workaround since this remains a problem in the latest D6 release.

I just put the checkbox/radio field inside a fieldgroup without any siblings, you can then target the fieldset group with the "fieldset.group-fieldgroupname " selector and remove the border, legend, etc to make it a invisible wrapper with a unique classname.

nancydru’s picture

And you also put #prefix and #suffix with a div. But that doesn't fix the base problem.

sun’s picture

Title: Wrapper ID (form-item) not displayed for Checkboxes / Radio Buttons CCK Fields » "-wrapper" HTML ID not output for #type checkboxes/radios
Status: Needs review » Active

Better title.

As there is no http://api.drupal.org/api/function/form_process_radios/7 in D6, http://api.drupal.org/api/function/theme_radios/6 and http://api.drupal.org/api/function/theme_checkboxes/6 basically need to be adjusted accordingly.

Technically, that unset() just needs to be removed? theme_form_element() appends "-wrapper" to $element['#id'] already.

The patches in #215301: Checkboxes/radios wrapper container does not get an 'id' attribute may contain additional pointers.

joelstein’s picture

Status: Active » Needs review
StatusFileSize
new354 bytes

In case it helps, here's a patch which removes the problematic unset() function.

joelstein’s picture

StatusFileSize
new679 bytes

Oops, here's the patch which affects both checkboxes and radios.

Status: Needs review » Needs work

The last submitted patch, form.inc_.patch, failed testing.

drclaw’s picture

Why not just override the theme function? You don't have to change the function in Core to make it work. Just copy the function to your theme's template.php file and change the word 'theme' to whatever your theme is named... Isn't this the whole point of writing theme functions? So people can override them?

Maybe I missed something...

drclaw’s picture

By the by, this fixed it for me:

/**
 * Return a themed form element.
 * 
 * Override here is to get a element ID on radios and checkboxes
 *
 * @param element
 *   An associative array containing the properties of the element.
 *   Properties used: title, description, id, required
 * @param $value
 *   The form element's data.
 * @return
 *   A string representing the form element.
 *
 * @ingroup themeable
 */
function phptemplate_form_element($element, $value) {
  // This is also used in the installer, pre-database setup.
  $t = get_t();

  $output = '<div class="form-item"';
  if (!empty($element['#id'])) {
    $output .= ' id="'. $element['#id'] .'-wrapper"';
  }
  else { // if we can't get the #id from $element['#id'] just build it from $element['#name']
    $id=explode("[value]", $element['#name']);
    $output .= ' id="edit-'. preg_replace('/\[|\]|_/', '-', str_replace('][', '-', $id[0])) .'value-wrapper"';
  }
  $output .= ">\n";
  $required = !empty($element['#required']) ? '<span class="form-required" title="'. $t('This field is required.') .'">*</span>' : '';

  if (!empty($element['#title'])) {
    $title = $element['#title'];
    if (!empty($element['#id'])) {
      $output .= ' <label for="'. $element['#id'] .'">'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
    }
    else {
      $output .= ' <label>'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
    }
  }

  $output .= " $value\n";

  if (!empty($element['#description'])) {
    $output .= ' <div class="description">'. $element['#description'] ."</div>\n";
  }

  $output .= "</div>\n";

  return $output;
}
ianchan’s picture

@drclaw - your code was MOST helpful. thank you!

shp’s picture

Status: Needs work » Needs review

#14: form.inc_.patch queued for re-testing.

shp’s picture

Version: 6.16 » 6.20
StatusFileSize
new834 bytes

One more patch...

shp’s picture

StatusFileSize
new816 bytes
shp’s picture

StatusFileSize
new979 bytes
lotyrin’s picture

Any reason why there are three copies of this patch now?

Status: Needs review » Needs work

The last submitted patch, form.inc_.shp_.patch, failed testing.

akin.demirci’s picture

subscribing...

jvdurme’s picture

Well, the id is in there now with removing the "unset" line from form.inc.

But can someone tell me how on earth I can add a CSS class to the outer wrapper of the checkboxes div?
When I try adding a new class with hook_form_alter, it only applies to the checkboxes themselves, but not to the outer checkboxes field wrapper.

And if I cannot add a new CSS class to that, I cannot style the label.

thanks.

EDIT: ok nevermind, CSS can be styled by ID also if you use the # tag instead of the . tag in the CSS file

shp’s picture

Version: 6.20 » 6.x-dev
StatusFileSize
new931 bytes
shp’s picture

Status: Needs work » Needs review
dave kopecek’s picture

@drclaw -- Thanks. Dropped #17 into my template.php and I'm on my way.

fuerst’s picture

Status: Needs review » Reviewed & tested by the community

#27 works well.

gbirch’s picture

#17 works great for me too (dropped into template.php). One quibble, however:

to made the id format consistent with other form elements, the line

$output .= ' id="edit-'. preg_replace('/\[|\]|_/', '-', str_replace('][', '-', $id[0])) .'value-wrapper"';

should be

$output .= ' id="edit-'. preg_replace('/\[|\]|_/', '-', str_replace('][', '-', $id[0])) .'-value-wrapper"';

(adds a dash between the field name and "value-wrapper")

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

- Was this fixed in Drupal 8/7 already?
- Looks like we purposefully removed the IDs there before. Why?
- As per #31, the resulting ID would not be nice either.

shp’s picture

Was this fixed in Drupal 8/7 already?

In Drupal 7 it was fixed (I've examined the code and checked on the live site). In D8 the code is almost the same as in D7, so in D8 it is fixed too.

gábor hojtsy’s picture

How was it fixed? Where is that issue? Can we be forward compatbile?

shp’s picture

I meant that in D7/8 the "id" attribute is rendered, but unfortunately I have not found an issue for that.
http://drupal.org/node/444256

Status: Needs work » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.