0

I am using Js to enable a form field when a checkbox is check otherwise its disable. I am using document.getElementsByClassName which returns an array of checkboxes then i add an addEventListener to each through a for loop. I then check if the box is checked and either removeAttribute('diabled') or setAttribute of a target form field which i get from the href of the checkbox. everything works great except that it only works for the element of the getElementsByClassName array.

html code:

<div class="form-group">
    <form method="POST" action="/admin_accounts/editaccount.php">
        <div class="input-group">
            <div class="input-group-addon input-group-addon-reponsive">
                <label for="memType">Member Type</label>
            </div>
            <select class="form-control" id="memTypeEdit" name="memTypeEdit" disabled>
                <option value="Regular">Regular</option>
                <option value="Ordinary">Ordinary</option>
                <option value="Associate">Associate</option>
                <option value="Executive">Executive</option>
                <option value="Honorary">Honorary</option>
                <option value="Dependant">Dependant</option>
                <option value="Instructor">Instructor</option>
                <option value="Volunteer">Volunteer</option>
            </select>
            <div class="input-group-addon"> 
                <input type="checkbox" class="edit-toggle" href="memTypeEdit"> 
                <label>Edit</label>
            </div>
        </div> 
        <div class="input-group">
            <div class="input-group-addon input-group-addon-reponsive">
                <label for="employ">Employment</label>
            </div>
            <select class="form-control" id="employEdit" name="employEdit" disabled>
                <option value="None"              >None</option>
                <option value="President"         >President</option>
                <option value="Vice President"    >Vice President</option>
                <option value="Treasurer"         >Treasurer</option>
                <option value="Clerk"             >Clerk</option>
                <option value="Instructor"        >Instructor</option>
                <option value="Web Administrator" >Web Administrator</option>
                <option value=""                  >Volunteer</option>
            </select>
            <div class="input-group-addon"> 
                <input type="checkbox" class="edit-toggle" href="employEdit"> 
                <label>Edit</label>  
            </div>
        </div>
        <div class="input-group date" data-provide="datepicker">
            <div class="input-group-addon input-group-addon-reponsive">
                <label for="regDate">Registration Date</label>
            </div>
            <input type="text" id="regDateEdit" name="regDateEdit" class="form-control" disabled>
            <div class="input-group-addon">
                <input type="checkbox" class="edit-toggle" href="regDateEdit"> 
                <label>Edit</label>
            </div>
        </div>
        <div class="input-group date" data-provide="datepicker">
            <div class="input-group-addon input-group-addon-reponsive">
                <label for="expDate">Expiry Date</label>
            </div>
            <input type="text" class="form-control" id="expDateEdit" name="expDateEdit" disabled>
            <div class="input-group-addon">
                <input type="checkbox" class="edit-toggle" href="expDateEdit"> 
                <label>Edit</label>
            </div>
        </div>
        <div class="input-group">
            <div class="input-group-addon input-group-addon-reponsive">
                <label for="admin">Administrator</label>
            </div>
            <select class="form-control" id="adminEdit" name="adminEdit" disabled>
                <option value="0">Is Not Administrator</option>
                <option value="1">Is Administrator</option>                                        
            </select>
            <div class="input-group-addon"> 
                <input type="checkbox" class="edit-toggle" href="adminEdit"> 
                <label>Edit</label>
            </div>                                                        
        </div>
        <div class="text-right">
            <div class="btn-group btn-group-sm" role="group">
                <button type="submit" name="create" class="btn btn-success">Save</button>
                <button type="reset" class="btn btn-info" value="Reset">Reset</button>
            </div> 
        </div>
    </form>
</div>

and the Js:

<script>
    var anchors = document.getElementsByClassName('edit-toggle');
    for (var i = 0, length = anchors.length; i < length; i++) {
        var anchor = anchors[i];
        anchor.addEventListener('click', function() {
            var target = document.getElementById(anchor.getAttribute('href'));
            if (anchor.checked){
                target.removeAttribute('disabled');
            }else{
                target.setAttribute('disabled', 'disabled');
            }
        }, true);
    };
</script>

As it is right now the name="adminEdit" works as intended but non of the others but when I remove class="edit-toggle" from the adminEdit checkbox, the expDateEdit starts working. So it looks like on the last element works. any ideas? thank you.

1 Answers1

0

Your problem is that in a loop, the value of anchor will end up being what it is when the last time the loop is run and all the event listeners will refer to the same anchor object. To solve this, you create a function which is executed immediately and you pass the anchor[i] to it to fix its value. Something like this should work.

<script>
    var anchors = document.getElementsByClassName('edit-toggle');
    for (var i = 0, length = anchors.length; i < length; i++) {            
        !function (anchor){
            anchor.addEventListener('click', function() {
                var target = document.getElementById(anchor.getAttribute('href'));
                if (anchor.checked){
                    target.removeAttribute('disabled');
                }else{
                    target.setAttribute('disabled', 'disabled');
                }
            }, true);
        }(anchors[i]);
    };
</script>

As Squint points out, in this case, a simpler solution would be to just use this instead of anchor

<script>
    var anchors = document.getElementsByClassName('edit-toggle');
    for (var i = 0, length = anchors.length; i < length; i++) {
        var anchor = anchors[i];
        anchor.addEventListener('click', function() {
            var target = document.getElementById(this.getAttribute('href'));
            if (this.checked){
                target.removeAttribute('disabled');
            }else{
                target.setAttribute('disabled', 'disabled');
            }
        }, true);
    };
</script>
mseifert
  • 5,390
  • 9
  • 38
  • 100
  • Worked great the only thing i had to do was name the function FireFox required the name – bradly strachan Apr 30 '17 at 00:45
  • Yes. Two other solutions besides naming the function would be 1) putting an exclamation before the function: !function(){}(); or 2) wrapping the function in parenthesis: (function(){})(); I edited my answer accordingly. – mseifert Apr 30 '17 at 00:51
  • @bradlystrachan: This is not the solution to use for your problem. All you need to do is replace `anchor` inside the event handler with `this`. While the solution is correct, that approach is very unnecessary here. –  Apr 30 '17 at 00:52
  • @squint - true enough. I will edit the answer to reflect this (no pun intended).. – mseifert Apr 30 '17 at 00:57
  • ...also, as a side note, don't use `set/removeAttribute` for setting disabling/enabling. Use the `.disabled` property instead. The whole of your event handler can be reduced to this `document.getElementById(this.getAttribute('href')).disabled = !this.checked`. Though you should use `data-` attribute for non-standard attributes, like `href` on an `input`. –  Apr 30 '17 at 00:58
  • thank you @squint i will use that approach. – bradly strachan Apr 30 '17 at 01:02
  • and thank you also @mseifert I learned alot from you answer I'm a beginner wit JS so your answer is not for not – bradly strachan Apr 30 '17 at 01:02
  • Thank you again @squint very good feedback – bradly strachan Apr 30 '17 at 01:06