Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Getting specific element (of parent) by name

I'm using custom tags to define sections in an application, so I have something like this:

<mysection>

   <form>
       <input name="myfield">
   </form>

</mysection>

I'm using the following and able to get the tag (printed to console, everything is groovy)

var parent = document.getElementsByTagName('mysection');

The issue I'm having is finding the child field by name:

var myfield = parent.getElementsByName("myfield");

...as I don't want to pick up on any other 'sections' that might have an input with the name 'myfield'.

EDIT:

var parent = document.getElementsByTagName('mysection')[0];

was suggested and returns to console the section contents, however, getElementsByName throws an error:

Uncaught TypeError: Object #<NodeList> has no method 'getElementsByName' 
like image 955
Fluidbyte Avatar asked Dec 16 '12 20:12

Fluidbyte


People also ask

Can you get element by name in Javascript?

The getElementsByName() accepts a name which is the value of the name attribute of elements and returns a live NodeList of elements. The return collection of elements is live. It means that the return elements are automatically updated when elements with the same name are inserted and/or removed from the document.

How do you find the parent element?

To get the parent node of an HTML element, you can use the parentNode property. This property returns the parent node of the specified element as a Node object. The parentNode property is read-only, which means you can not modify it. In HTML, the document is itself the parent node of html element.

How do I get a parent selector?

By using querySelector() and closest() methods is possible to get the parent element. querySelector() returns the first element that matches a specified CSS selector(s) in the document. closest() searches up the DOM tree for the closest element which matches a specified CSS selector.


2 Answers

Using getElementsByTagName() and getElementsByName() will return a NodeList, you need to get the first element of the list like this:

var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];

Edit

You were correct, getElementsByName is not valid for an element. I am unsure how to localize the functionality of it as you are trying to do. It seems that it will only work for document. You may have to write your own implementation of getElementsByName if you want to use it in a localized scope.

Second Edit

To be nice, I made that implementation for you :D Here it is in all its "glory".

Element.prototype.getElementsByName = function (arg) {
    var returnList = [];
    (function BuildReturn(startPoint) {
        for (var child in startPoint) {
            if (startPoint[child].nodeType != 1) continue; //not an element
            if (startPoint[child].getAttribute("name") == arg) returnList.push(startPoint[child]);
            if (startPoint[child].childNodes.length > 0) {
                BuildReturn(startPoint[child].childNodes);
            }
        }
    })(this.childNodes);
    return returnList;
};
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];

Small fix

I was incorrectly passing the element and not its children into the recursion. The code above has been edited with the proper argument passed now. See working fiddle: http://jsfiddle.net/js6NP/5/

like image 60
Travis J Avatar answered Nov 15 '22 21:11

Travis J


I actually found a much more simple way to handle this:

document.querySelectorAll('mysection [name="myfield"]');

Here you can see an example where it only modifies the field inside the section specified: http://jsfiddle.net/fluidbyte/kph6H/

qSA supports modern browsers and is compatible down to IE8, Here's a polyfill to support back to IE7: https://gist.github.com/2724353

like image 42
Fluidbyte Avatar answered Nov 15 '22 20:11

Fluidbyte