Re: Accessing Form attributes instead of elements

RobG
Fri, 21 Sep 2007 12:01:36 -0000

On Sep 20, 8:04 pm, "Jean-Philippe Encausse"
<J...-vcK5r0oTKUrk1uMJSBkQmQ@public.gmane.org>
wrote:
> Hi,
>
> I''m sorry for this JavaScript Off topic question a little bit
tricky:
>
> I have an HML Form with:
> - An input using name="name"
> - An attibute name="formName"
>
> In JavaScript I would like to access the form''s attribute. How to
do that ?
>
> - form.name returns input
> - form[''name''] returns input
>
> Any idea ?

The attributes of HTML elements can be accessed as properties of the
DOM HTML object that represents the element using dot properties or
square bracket notation.

HTML DOM forms have an elements collection that contains all the
controls within the form.  It is a convention that each member of that
collection that has a name can be accessed as a property of the form
DOM object itself.

The result is that where a form control has a name that is the same as
an attribute of the formelement, the form''s dot property accessor will
be a reference to the form control, not the native attribute of the
form.

The most common incarnation of this is when a submit button named
"submit" is placed in a form, thereby shadowing the form''s
submit
method. Attempting to call the form''s submit method results in a
javascript error.

The W3C DOM Core getAttribute method *should* access the actual
properties of the form, so:

  $(formID).getAttribute(''name'')


*should* do the job.  However, IE''s getAttribute method is broken in
places, so an alternative is to use the HTML Element''s attributes
object:

  $(formID).attributes.getNamedItem(''name'').nodeValue


which *should* work in any W3C DOM 2 conforming browser.
Unfortunately, IE is again deficient.  While the above does work, an
appropriate feature test would be:

  var el = $(formID);
  if (typeof el.attributes == ''object'' &&
      typeof el.attributes.getNamedItem == ''function'') {
    return el.attributes.getNamedItem(attributeName).nodeValue;
  }

but in the second part of the test, IE returns ''object'', not
''function''.  So the test becomes:

  if (typeof el.attributes == ''object'' &&
      (typeof el.attributes.getNamedItem == ''function'' ||
       typeof el.attributes.getNamedItem == ''object'')
     ) { ... }

So there is still a chance (however unlikely) that it will fall apart
because getNamedItem has been replaced by an object and is not a
function.

Another aspect is that the attributes are also available as properties
of the attributes object itself, so:

  $(formID).attributes[''name''].nodeValue


"works". That is what Prototype.js uses for its readAttribute method -
but only where its browser sniffing says it is working with IE, in
other cases it will use getAttribute.  It think the feature test above
is a more robust solution than browser sniffing, even though it is not
perfect.

In any case, it is best if you never create form controls with names
that match native attributes of the form DOM object so that you can
rely on the tried-and-true dot property access method.


--
Rob