0

My goal: Upon checking a checkbox, a pertinent element is enabled.

This is my JavaScript. As I understand it, this is the input. So calling parentNode on that is going up to the checkbox div. Then I set parent_1 which is the col-md-3 div. Then I set child to be the next sibling to parent_1, which is the next col-md-3 div. But I get the error

Uncaught TypeError: Cannot read property '0' of undefined 

The error location is the input.

function selectElement(object) {
    var parent = object.parentNode;
    var parent_1 = parent.parentNode;
    var child = parent_1.nextSibling;
    if (parent.children[0].checked == true) {
        child.children[0].disabled = false;
    } 
    else {
        child.children[0].disabled = true;
    }
}

This is my HTML:

<div class="col-md-3">
    <div class="checkbox checkbox-primary">
        <input type="checkbox" id="fast_dd" onClick="selectElement(this);">
        <label for="fast_dd">Anomalies</label>
    </div>
</div>
<div class="col-md-3">
    <select name="fast" class="selectpicker" disabled>
        <option>Options</option>
    </select>
</div>

edit - Not at all sure why I wrote parent.children[0] instead of just object, clumsy of me

edit 2 - Changed title to be more accurate

Firkamon
  • 807
  • 1
  • 9
  • 19

3 Answers3

2

You are almost there.

What you want is to get the next element, not necessarily the next DOM node (which is a text node).

Use this JS instead:

function selectElement(object) {
    var parent = object.parentNode;
    var parent_1 = parent.parentNode;
    var child = parent_1.nextElementSibling; //nextElementSibling instead of nextElement
    if (object.checked == true) { // use object instead of parent.children
        child.children[0].disabled = false;
    } 
    else {
        child.children[0].disabled = true;
    }
}

Here is a fiddle: http://jsfiddle.net/1hzmwd7w/2/

xDaevax
  • 2,012
  • 2
  • 25
  • 36
  • 1
    +1. The text node exists because there is a new line character between the two elements. That's a common mistake if you're not aware of it. – Sebastien C. Aug 18 '14 at 13:13
  • Yes. I have made that mistake more times than I will admit here. :) – xDaevax Aug 18 '14 at 13:15
  • Wonderful! Thank you. This had me puzzled because your JSFiddle worked perfectly, and mine still did not. I removed the Selectpicker class and it now works flawlessly. If you're reading this and you're using Selectpicker, find another style! – Firkamon Aug 18 '14 at 13:35
1
var isClassMember = function (element, classname) {
    var classes = element.className;
    if (!classes) {
        return false;
    };
    if (classes == classname) {
        return true;
    };
    var whitespace = /\s+/;
    if (!whitespace.test(classes)) {
        return false;
    };
    var c = classes.split(whitespace);
    for (var i = 0; i < c.length; i++) {
        if (c[i] == classname) {
            return true;
        };
    };
    return false;
};
var getElements = function (classname, tagname, root, firstFlag, depth) {
    if (!root) {
        root = document;
    }
    else {
        if (typeof root == "string") {
            root = document.getElementById(root);
        };
    };
    if (!tagname) {
        tagname = "*";
    };
    if (depth) {
        var maxRecursion = depth;
        var all = (function getChildsElementsLevel(root, tagName, currentLevelNumber) {
            var result = [],
                currentLevelChilds = (function getLevelChilds(root, tagName) {
                    var result = [];
                    var children = root.firstChild;
                    do {
                        if (children.nodeName == tagName) {
                            result.push(children);
                        };
                    } while (children = children.nextSibling);
                    return result;
                })(root, tagName),
                currentLevelChildsLength = currentLevelChilds.length,
                nextLevelNumber = ++currentLevelNumber;

            for (var f = currentLevelChildsLength; f--;) {

                var currentEl = currentLevelChilds[f];
                result.push(currentEl);
                if (nextLevelNumber < maxRecursion) {
                    result.concat(getChildsElementsLevel(currentEl, tagName, nextLevelNumber));
                }
            }
            return result;
        })(root, tagname, 0);
    }
    else {
        var all = root.getElementsByTagName(tagname);
    }
    if (!classname) {
        return all;
    };
    var elements = [],
        allLength = all.length,
        isMyClass = isClassMember;
    if (firstFlag) {
        for (var i = 0; i < allLength; i++) {

            var element = all[i];
            if (isMyClass(element, classname)) {
                return element;
            };
        };
    }
    else {
        for (var i = allLength; i--;) {

            var element = all[i];
            if (isMyClass(element, classname)) {
                elements.push(element);
            };
        };
    }

    return elements;
};
function toArray(Lcollection) {
    for (var i = 0, a = [], len = Lcollection.length; i < len; i++) {
        a.push(Lcollection[i]);
    };
    return a;
};

(function () {
    function init() {
        var myDIV = getElements("checkbox-primary", "DIV", null, true);
        if (myDIV && myDIV.childNodes) {
            var myArray = toArray(myDIV.childNodes),
                myArrayLength = myArray.length,
                myCheckBox = null;

            for (var i = 0; i < myArrayLength; i++) {
                var tempNode = myArray[i];
                if (tempNode.nodeName.toUpperCase() === "INPUT" && tempNode.type.toUpperCase() === "CHECKBOX") {
                    myCheckBox = tempNode;
                    break;
                };
            };
            if (myCheckBox) {
                if (myCheckBox.checked) {
                    myCheckBox.disabled = false;
                }
                else {
                    myCheckBox.disabled = true;
                }
            };
        };
    };
    if (this.addEventListener) {
        this.addEventListener("load", init, false)
    }
    else {
        window.onload = init;
    }
}());
Greck
  • 170
  • 1
  • 7
-2

You can do it in a much simple way.

Add an ID to your select tag

 <select name="fast" id="fast" class="selectpicker" disabled>

And use this javascript to check for the click event and handle the actions.

function selectElement(object) {
 if (object.checked == true) {
     document.getElementById("fast").disabled = false;
 } 
 else {
     document.getElementById("fast").disabled = true;
 }
}
DJ22T
  • 1,628
  • 3
  • 34
  • 66
  • I'm coding like this because I need this to work for other elements with, of course, differing IDs. The common structure is that the select element is in a div that is location directly below the input div. – Firkamon Aug 18 '14 at 13:08
  • Doesn't the class will work for you? or it could be an unknown element? – DJ22T Aug 18 '14 at 13:09
  • Using DOM smartly is always better than a stupid and heavy getElementById. – Sebastien C. Aug 18 '14 at 13:10
  • @sebcap26 what do you mean? – DJ22T Aug 18 '14 at 13:11
  • I mean that `getElementById` is not magically returning an element. That's a function which is searching in the index of all ids in the page. The more indexes you have, the slowest it will be. And using global "variables" instead of a well defined structure is not what I call a good program. – Sebastien C. Aug 18 '14 at 13:17
  • i get it, so what you propose then? in the Javascript context? – DJ22T Aug 18 '14 at 13:18
  • Look at the answer from xDaevax. – Sebastien C. Aug 18 '14 at 13:19
  • 1
    The trade-off is readability. The `getElementById` method can be slow as @sebcap26 pointed out, so typically using DOM context is faster. The caveat is that DOM traversal is harder to read than a `getElementById` call. I usually opt for DOM traversal though personally so I don't have to decorate everything with an id. Here are some useful links: http://www.youtube.com/watch?v=mHtdZgou0qU, http://stackoverflow.com/questions/1716266/javascript-document-getelementbyid-slow-performance, http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas – xDaevax Aug 18 '14 at 13:26
  • @xDaevax Great clarification, much obliged. – DJ22T Aug 18 '14 at 13:48