1

I'm getting this error "app_copy.js:13 Uncaught TypeError: Cannot read property 'remove' of undefined" and am not sure why. When you click on the first button I want those buttons removed and two hidden buttons to show. Why am I getting this error when I click on the first button? It works if I use document.querySelector and remove a single one but not if I use document.querySelectorAll like I'm trying to do here. Thanks!

Codepen: http://codepen.io/abharms/pen/BKvYvL

HTML

<div class="wrapper">

  <a class="numberButtons first" href="#">1</a>
  <a class="numberButtons second" href="#">2</a>
  <a class="numberButtons third" href="#">3</a>

 <a class="yesNo hide" href="#">Yes</a>
 <a class="yesNo hide" href="#">No</a>
</div>

CSS

body {
background-color: #74c7d5;  
}
.wrapper {
text-align: center;
margin-top: 200px;
}
.wrapper a {
text-decoration: none;
padding: 10px 15px 10px 15px;
margin: 10px;
border: 1px solid white;
color: #9965a8;
border-radius: 5px;
}
.wrapper a:hover {
background-color: white;
color: #74c7d5;
}
.hide {
display: none;
}

JavaScript

var numberButtons = document.querySelectorAll(".numberButtons");
var yesNo = document.querySelectorAll(".yesNo");
var first = document.querySelector(".first");
var second = document.querySelector(".second");
var third = document.querySelector(".third");


function numberButtonsLoop() {
for(var i = 0; i < numberButtons.length; i++)
numberButtons[i].addEventListener("click", function(){
var clickedOption = this;
        if(clickedOption === first) {
            yesNo.classList.remove("yesNo");
            numberbuttons.classList.add("hide");
        }   
    });     
};              


numberButtonsLoop();
Austin
  • 115
  • 1
  • 10

2 Answers2

0

Your variables yesNo, and numberbuttons, each hold a collection of HTML element nodes returned from document.querySelectorAll(), even if those collection are comprised of only one element; to remove the class-name from all elements in that collection you'd have to iterate over each element node in turn:

if(clickedOption === first) {
    // Array.from() converts the array-like collection
    // into an Array upon which we can use the
    // Array.prototype.forEach() method to iterate over
    // the newly-formed Array:
    Array.from( yesNo ).forEach(function(element){
        element.classList.remove("yesNo");
    });
    Array.from( numberbuttons ).forEach(function(element){
        element.classList.add("hide");
    });
}
David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

Due to the query selectors returning an array of elements (since you are selecting by className), you need to loop through all elements in the array when you remove/add the class.

This error was present for both adding a class name to the numberButtons and yesNo elements. I have fixed both in my snippet.

var numberButtons = document.querySelectorAll(".numberButtons");
var yesNo = document.querySelectorAll(".yesNo");
var first = document.querySelector(".first");
var second = document.querySelector(".second");
var third = document.querySelector(".third");


function numberButtonsLoop() {
for(var i = 0; i < numberButtons.length; i++)
  numberButtons[i].addEventListener("click", function(){
    var clickedOption = this;
    if(clickedOption === first) {
      for(var i=0; i<yesNo.length; i++) {
        yesNo[i].classList.remove("yesNo");
      }
      for(var i=0; i<numberButtons.length; i++) {
        numberButtons[i].classList.add("hide");
      }
    }   
  });     
};              


numberButtonsLoop();
body {
background-color: #74c7d5;  
}
.wrapper {
text-align: center;
margin-top: 200px;
}
.wrapper a {
text-decoration: none;
padding: 10px 15px 10px 15px;
margin: 10px;
border: 1px solid white;
color: #9965a8;
border-radius: 5px;
}
.wrapper a:hover {
background-color: white;
color: #74c7d5;
}
.hide {
display: none;
}
<div class="wrapper">

  <a class="numberButtons first" href="#">1</a>
  <a class="numberButtons second" href="#">2</a>
  <a class="numberButtons third" href="#">3</a>

 <a class="yesNo hide" href="#">Yes</a>
 <a class="yesNo hide" href="#">No</a>
</div>
Wowsk
  • 3,637
  • 2
  • 18
  • 29