JavaScript Concatenating getElementsByName() Calls Together

svet-am

Supreme [H]ardness
Joined
Jan 6, 2003
Messages
5,146
Is this valid:

Code:
var myVar = document.getElementsByName(value1).getElementsByName(value2);

What I am trying to do is find one block of code by it's name and then find another block of code (by name) within that block.

in a perfect world, my target tag would have an id property and I'd just find it that way but that's not doable for this application.
 
I believe a more proper term for that would be chaining.

I've never attempted that with vanilla javascript, but in jQuery it would be something like this (assuming value1 and value2 are variables):
Code:
var insideElement = jQuery('[name="' + value1 + '"]').find('[name="' + value2 + '"]');
 
Code:
    <div id="columns" name="columns">
        <ul id="column1" class="column" name="column1">
            <li class="widget color-white" id="widget0" name="widget0">
                <input type="hidden" name="widgetType" value="0">
                <div class="widget-head">
                    <h3>Widget title</h3>
                </div>
                <div class="widget-content">
                    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam magna sem, fringilla in, commodo a, rutrum ut, massa. Donec id nibh eu dui auctor tempor. Morbi laoreet eleifend dolor. Suspendisse pede odio, accumsan vitae, auctor non, suscipit at, ipsum. Cras varius sapien vel lectus.</p>
                </div>
            </li>
        </ul>
    </div>

so, using getElementsByName(), I can find "widget0". Now, I need to be able to easily find "widgetType" by name once I've found "widget0".
 
I threw this together with limited testing using your example html:
Code:
<div id="columns" name="columns">
	<ul id="column1" class="column" name="column1">
		<li class="widget color-white" id="widget0" name="widget0">
			<input type="hidden" name="widgetType" value="0">
			<div class="widget-head">
				<h3>Widget title</h3>
			</div>
			<div class="widget-content">
				<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam magna sem, fringilla in, commodo a, rutrum ut, massa. Donec id nibh eu dui auctor tempor. Morbi laoreet eleifend dolor. Suspendisse pede odio, accumsan vitae, auctor non, suscipit at, ipsum. Cras varius sapien vel lectus.</p>
			</div>
		</li>
	</ul>
</div>
	
<script type="text/javascript">
	var outsideEls = document.getElementsByName('widget0');
	var el = findElementByNameWithinEls(outsideEls,'widgetType');
	console.debug(el);
	/**
	 * Find an element with a specific name attribute which is a descendant of any element contained in elArray.
	 * @param Array els
	 * @return element or false
	 */
	function findElementByNameWithinEls(els,elName){
		while(els.length != 0){
			var childEls = getChildEls(els);
			for(var i=0;i<childEls.length;i++){
				if(childEls[i].getAttribute('name') == elName){
					return childEls[i];
				}
			}
			els = childEls;
		}
		return false;
	}
	/**
	 * Get an array of all child elements under any of the elements contained in the els array.
	 * @param Array els
	 * @return Array
	 */
	function getChildEls(els){
		childEls = Array();
		for(i=0;i<els.length;i++){
			for(var j=0; j<els[i].childNodes.length; j++){
				if(els[i].childNodes[j].nodeType == 1){
					childEls.push(els[i].childNodes[j]);
				}
			}
		}
		return childEls;
	}
</script>
 
I threw this together with limited testing using your example html:

thank you very much for that effort. I'll take a look at it and learn from it.

was I totally off-base in thinking that I could do something like:

var myVar = getElementByName().getElementByName();
 
thank you very much for that effort. I'll take a look at it and learn from it.

was I totally off-base in thinking that I could do something like:

var myVar = getElementByName().getElementByName();

I think that is like saying "Give me all elements that have a specific name attribute of A, and of those elements returned give me all elements that have a specific name attribute of B." That should always return nothing, unless the element(s) somehow had two name attributes that matched both A and B.

Psuedo-code that would make a little more sense as to what you wanted to do is:
Code:
getElementsByName('a').getDescendents().getElementBysName('b')
 
Ok a couple of things:

first, .getElementsByName() returns an array, so referring to the array's reference doesn't get you what you want.

Second, I don't think that function can be applied to search children, and you don't really need it to, since it looks through the whole document, recursing through all the nesting.

If it did work, the syntax would look more like:
document.getElementsByName("widget0")[0].getElementsByName("widgetType")[0].

Which to me seems non-definitive since you could have more than one element with the name widget0.

You can play around with these concepts by messing around with this:

Code:
<html>
<head>
<script language = javascript>
function goClick()
{
	var x = document.getElementsByName("widget0");
	
	alert(x[0].id);
	var xx = x[0].childNodes;
	alert(xx[1].id);
	
	var z = document.getElementsByName("widgetType");
	alert(z[0].id);
	alert(z[0].parentNode.id)
	

}


</script>

</head>

<body>
    <div id="columns" name="columns">
        <ul id="column1" class="column" name="column1">
            <li class="widget color-white" id="widget0" name="widget0">
                <input type="hidden" name="widgetType" id="testtest" value="0">
                <div class="widget-head">
                    <h3>Widget title</h3>
                </div>
                <div class="widget-content">
                    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam magna sem, fringilla in, commodo a, rutrum ut, massa. Donec id nibh eu dui auctor 

tempor. Morbi laoreet eleifend dolor. Suspendisse pede odio, accumsan vitae, auctor non, suscipit at, ipsum. Cras varius sapien vel lectus.</p>
                </div>
            </li>
        </ul>
    </div>
<div></div>
<input type = "button" value = "go" onClick = "goClick()"/>
</body>
</html>

I added an id of "testtest" to the node you're looking for as an easy way to verify that you have a reference to the correct node. Click the go button and see what the alerts show.

If it was me, I would take one of two approaches:
(outside of jquery, which looks interesting but I've never used ;) )
1) get a reference to widget0, and iterate its child nodes until I found one of type input with name widgetType.
2) get the array of all nodes with name widgetType, and iterate it to find the one whose parent is widget0.
 
I have one final question. I think I figured out my chaining issue.

I currently have some test code working by chaining getElementsByTagName() off of getElementById()

like so:

Code:
 var widgetType = document.getElementById(widgetID).getElementsByTagName('input').length;

is it possible to chain getElementsByName() off of getElementById() instead of getElementsByTagName() ? I tried it and it didn't work but I can't find anywhere that explicitly forbids it.
 
getElementById() returns an element object. getElementsByName() is only available on document objects.
 
Back
Top