Skip to content Skip to sidebar Skip to footer

Precedence When Html Form Element Attributes And Properties Conflict

I notice a discrepancy in behavior between browsers and different types of form elements, when form element DOM attributes are set in conflict with current state from the same elem

Solution 1:

Take at look at http://jsfiddle.net/Ldf2s/9/.

<formname="foo"><inputname="bar"type="checkbox" /><inputname="baz"type="text"/></form><script>setTimeout(function() {
    document.forms['foo'].bar.setAttribute("checked", "true");
}, 5000);

setTimeout(function() {
    document.forms['foo'].baz.setAttribute("value", "attr value");
}, 5000);
</script>

If you run the page and don't touch the input boxes, after 5 seconds the checkbox will be ticked and value will be set. But if you run the page and immediately click on the checkbox and type some text in the text input, the values will not be modified once 5 seconds has elapsed.

The concepts to be understood here are the dirty checkedness flag and the dirty value flag.

What these do is to mark the checkbox and text input fields as to whether document.forms['foo'].bar.setAttribute("checked", "true"); and document.forms['foo'].baz.setAttribute("value", "attr value"); affect the checkedness and value of the respective inputs or not.

For the dirty checkedness flag, the HTML5 spec says

Each input element has a checkedness, which is exposed by the checked IDL attribute.

Each input element has a boolean dirty checkedness flag. When it is true, the element is said to have a dirty checkedness. The dirty checkedness flag must be initially set to false when the element is created, and must be set to true whenever the user interacts with the control in a way that changes the checkedness.

The checked content attribute is a boolean attribute that gives the default checkedness of the input element. When the checked content attribute is added, if the control does not have dirty checkedness, the user agent must set the checkedness of the element to true; when the checked content attribute is removed, if the control does not have dirty checkedness, the user agent must set the checkedness of the element to false.

So in the JSFiddle above the act of the user clicking the checkbox stops the setAttribute call affecting whether the checkbox is checked or not.

However, it also says that

The checked IDL attribute allows scripts to manipulate the checkedness of an input element. On getting, it must return the current checkedness of the element; and on setting, it must set the element's checkedness to the new value and set the element's dirty checkedness flag to true.

So document.forms['foo'].bar.checked=false; should also have the effect of stopping the setAttribute call from setting the checked state because it too should make the dirty checkedness flag true.

But in Chrome the checked value is changed, so it is inconsistent with the HTML5 spec.


The HTML5 spec also has an analogous requirement for the text input value in that there is a dirty value flag that is set true when the user changes the value, or the value property is set programatically.

It seems in this case Chrome behaves correctly, possibly because the requirement to set the dirty value flag when the value property is set programatically is made explicitly when describing the dirty value flag, whereas the equivalent description of the dirty checkedness flag does not have the matching comment. That requirement is only given separately in the quote above.

Solution 2:

Browsers differ, partly because there have been no exact, consensus-based definitions for the DOM features involved. In HTML5, this is being standardized: the input element is defined to that the checked property (“IDL attribute”, as they call it) describes the actual checkedness state (which as affected by user actions and by JavaScript code), whereas the defaultChecked property corresponds to the HTML attribute checked, which sets the initial checkedness.

In the example code in the question, the checked property is set to the value false, which does not change anything (it is the initial value, in the absence of the checked attribute). Then the checked attribute, and thereby the defaultChecked property, is set, but this does not change the checkedness state.

Thus, Chrome does not work by the HTML5 draft. This is formally just a feature, since there is so far no approved specification, but in practical terms, it can be described as a bug.

For a text input box, input type=text, there is no such issue, since the value property more directly reflects the value attribute (there is no separate defaultValue property).

Post a Comment for "Precedence When Html Form Element Attributes And Properties Conflict"