Consider the following code: (Figure 1)
var form = document.createElement('form');
form.setAttribute('id', 'TheForm');
form.setAttribute('method', 'GET');
document.body.appendChild(form);
var textbox1 = document.createElement('input');
form.appendChild(textbox1);
textbox1.setAttribute('id', 'Textbox1');
textbox1.setAttribute('type', 'text');
textbox1.setAttribute('value', 'textbox1');
Now consider this snippet: (Figure 2)
var form = document.createElement('form');
form.setAttribute('id', 'TheForm');
form.setAttribute('method', 'GET');
document.body.appendChild(form);
var textbox1 = document.createElement('input');
textbox1.setAttribute('id', 'Textbox1');
textbox1.setAttribute('type', 'text');
textbox1.setAttribute('value', 'textbox1');
form.appendChild(textbox1);
The difference is when textbox1 is appended to the form.
For all attributes other than 'type', the order doesn't seem to matter from browser to browser.
The 'type' attribute matters when you're dealing with certain browsers like Internet Explorer (IE) versions 5 through 8 (IE9 seems to work, except they don't preserve the "value" property's data when converting to the radio/checkbox controls.)
The issue lies in the timing of appending the textbox element to the form. In the older aforementioned versions of IE, according to "TYPE Attribute | type Property" on MSDN (in the Remarks section):
"As of Microsoft Internet Explorer 5, the type property is read/write-once, but only when an input element is created with the createElement method and before it is added to the document."
It is also important to note that Internet Explorer defaults to type="text" if you don't specify.
Normally the order of one appending an element to the document and setting attributes later wouldn't matter, but since the older versions of IE insist on not allowing this to happen after it's appended to the document or form, we must ensure we append the element AFTER we finish setting it up.
If you do as Figure 1 suggests, the browser will throw a JavaScript exception saying:
"This command is not supported"
Simply put, complete all setup of the HTMLElement's properties/attributes you create via document.createElement() before you call HTMLElement.appendChild() to append it to the document. This should work consistent across all browsers.
No. In fact, normally you'll use the direct properties for attributes the given HTML element already provides. For example, the following are identical:
textbox1.setAttribute('value', 'Some string');
textbox1.value = 'Some string';
The highlighted is the preferred best practice way to set that attribute. Both lines of code are the equal to having a hard-coded line of HTML that said:
<input type="text" value="Some string" />
You'll notice that when you click the "Change textboxes to different input types" button below after clicking "Create form" that IE9 does not preserve the original values set on the Input element when it was first created. Chrome, Firefox and Safari do.
I was using the Silverlight HtmlElement.SetAttribute() method to access the DOM from a Silverlight application I was working on. The application kept returning an InvalidOperationException with an obscure "Common_MethodFailed" error message. I wanted to understand if the Silverlight was having issues in that browser, or if it was a problem with the JavaScript engine of the browser.
Incidentally, in Silverlight, one must use the SetAttribute method because the HtmlElement object is generic and doesn't contain all the properties that would match to the actual HTML attributes. Therefore, it was natural for me to assume that Silverlight would also call the JavaScript HtmlElement.setAttribute function when calling down into the DOM.
Further investigation narrowed it down to the line of code where I was calling SetAttribute with the "type" attribute. So I set out to make a plain XHTML/JavaScript page I could test without Silverlight in the browser, and was met with the "This command is not supported" JavaScript error.
I wanted to document it for those that might run into this issue in JavaScript and/or Silverlight. I hope it will help someone find answers to the confusion quickly.
I tried using: inputElement.type = 'checkbox' and it worked the same as calling inputElement.setAttribute('type', 'checkbox');
For the purposes of our experiment here, we'll stick with calling setAttribute.
Try it for yourself below... click each button in order to see if your browser supports appending the elements before setting the "type" attribute.
It seems IE9 actually creates a new HTMLInputElement with the new type and carries over most properties (like the onclick handler) -- but not the original values. The other browsers carry over the original values. I'll leave you to experiment with the "why" on that one on your own. I've run out of time for now. Happy coding!