I 've just added a function filterByParent (in /lib/container.js, it's automatically included with each page) that is very powerful and will do your job. A few pointers on how to use it:
- Get an array of elements, say all INPUT elements like in your example.
- Call filterByParent(collection, parentFinder) to get back a smaller, filtered array.
- Iterate on the new array to do whatever you want.
The first argument of filterByParent is obvious, but the second can be a bit difficult to grasp. Basically filterByParent tries, for each element in the given array, to find a parent element (which may be the initial element itself; "parent" is used in the broader sense "parent or self") with specific characteristics. If no such parent element is found, the element is filtered out.
parentFinder, therefore, is a function that returns a parent element that has some specific characteristics, or the BODY element if none (this results in the filtering out).
You do not have to write parentFinder yourself. There is a powerful function findParentNode (element, elName, elClass, elID) which starts from element and tries to find a "parent or self" element with the specified tag name, class, and id (you can omit as many of those as you like). You can easily build on that, making a "specialized" version of it:
function myFinder(el) {
return findParentNode(el, "FORM", "", "myformid");
}
Now, if you have an array of elements and say
filtered = filterByParent(myCollection, myFinder);
what will happen is that the filtered array will contain only those elements who happen to be descendants of a FORM tag with id="myformid".
You can also get fancy and write myFinder inline:
filtered = filterByParent(
myCollection,
function(el) {return findParentNode (el, "FORM", "", "myformid");}
);
This will do the exact same thing.
As a last, practical example, here is a function that when executed will check all the "attempt" checkboxes in the quiz overview page based on the principle that they are in a FORM. If you try to add some checkboxes outside a FORM in the same page (this is useless practically, but enough for an example), you will see that they don't get checked (i.e., the filtering works).
function checkattempts() {
var inputs = document.getElementsByTagName('INPUT');
inputs = filterByParent(inputs, function(el) {return findParentNode(el, 'FORM');});
for(var i = 0; i < inputs.length; ++i) {
inputs[i].checked = 'checked';
}
}
"Deselect all" would of course be
inputs[i].checked = '';
instead.
Jon