I'm looking through a checkboxes form with #attributes set to array('class'=>'froggy') and I can't find froggy anywhere in the DOM when I'm inspecting it with the firefox dom inspector. I was expecting that the class would be applied once at the top-level containing div.
drupaldocs (which seems down) says that checkboxes uses #attributes

Comments

Wesley Tanaka’s picture

Title: is forms api #attributes on checkboxes getting applied? » setting class, type, name, id, or value on forms api #attributes on checkboxes results in duplicate attributes
Priority: Minor » Normal

took a look at theme_checkbox, and it turns out that a bunch of attributes could get set twice.

Wesley Tanaka’s picture

Title: setting class, type, name, id, or value on forms api #attributes on checkboxes results in duplicate attributes » setting class, type, name, id, or value on forms api #attributes on checkbox results in duplicate attributes

this happens with single checkbox calls too, by inspection.

magico’s picture

Any news about this problem?

lilou’s picture

Version: x.y.z » 7.x-dev
casey’s picture

Status: Active » Fixed

Is/was this really a bug?

casey’s picture

Status: Fixed » Active

didn't mean to set this to fixed already.

Wesley Tanaka’s picture

Yes it really was. I do not know if it is.

casey’s picture

Oww I get it. indeed, you're right.

function theme_checkbox($variables) {
...
  $checkbox .= 'type="checkbox" ';
  $checkbox .= 'name="' . $element['#name'] . '" ';
  $checkbox .= 'id="' . $element['#id'] . '" ' ;
  $checkbox .= 'value="' . $element['#return_value'] . '" ';
  // Unchecked checkbox has #value of numeric 0.
  if ($element['#value'] !== 0 && $element['#value'] == $element['#return_value']) {
    $checkbox .= 'checked="checked" ';
  }
  $checkbox .= drupal_attributes($element['#attributes']) . ' />';

First we're adding attributes to the string manually and then using drupal_attributes(). We could unset the manually added ones before drupal_attributes().

casey’s picture

Status: Active » Needs review
StatusFileSize
new10.74 KB

Pro
- No double attributes
- all attributes are handled the same
- all attributes are passed through check_plain() (security)

Contra
- all attributes are passed through check_plain(), while some don't need it (performance)

Status: Needs review » Needs work

The last submitted patch, duplicateattributes.patch, failed testing.

casey’s picture

Oww some attributes can't be passed through check_plain(); especially URLs like the action attribute of <form>s.

Another way to fix duplicate attributes is removing them from #attributes.

casey’s picture

Status: Needs work » Needs review

Like this.

casey’s picture

StatusFileSize
new6.53 KB
sun’s picture

Component: base system » forms system
Status: Needs review » Closed (won't fix)

This issue reads a bit strange, as it started off with an entirely different question in 2005 (5.x), then changed its scope later on. Trying to address them one by one:

1) Setting a CSS class on #type 'checkbox' should be as simple as setting $element[#attributes][class][] = 'classname'. Note that 'class' is always an array in D7.

2) Certain attributes can indeed be set more than once. However, that would be a module developer mistake and I've personally never heard from anyone running into this problem. Furthermore, the patch over in #690980: Disabled form elements not properly rendered will eliminate this possibility by using #attributes only, and overriding those special attributes with the values of the internal element properties.

3) All HTML attributes *have to* be passed through check_plain(). What you encountered is actually the problem discussed and solved over in #715142: [beta blocker blocker] Various URLs escaped twice, since check_url() resp. filter_xss_bad_protocol() calls check_plain() -- certain attributes were escaped *twice*, which, in the case of URLs, can lead to double-encoded characters in the URL, effectively rendering it unusable.

4) The performance difference of invoking check_plain() for all attributes is only marginal and does not really count, compared to the improved consistency, and also importantly, vastly improved theme function code that can be overridden more easily.

In effect, I think this issue won't fix. Feel free to re-open.