0

I am trying to create a toggle function with JavaScript (not jQuery).

I have created an ID named box, and a class within the ID named box-open.

The width of the ID box is 100px.

The width of box-open is set to 1000px.

When I try to use my code I get this error, that displays “Cannot set property 'display' of undefined”.

I have tried writing the code a couple of different ways, but I always seem to get the same error in the console.

function toggle(open) {
  box = document.getElementById('box').style.display = 'block';

  if (open == true) {
    box.style.display = 'none';
    boxOpen = document.getElementsByClassName('box-open').style.display = 'block';
  } else {
    box.style.display = 'block';
    boxOpen.style.display = 'none';
  }
}
#box {
  width: 100px;
  height: 100px;
  background: gold;
  text-align: center;
  display: block;
}
.box-open {
  width: 50px;
  height: 50px;
  background: green;
  display: none;
}
<div id="box" class="box-close"></div>
<button type="button" onClick="toggle()">click me</button>

This is a link to my codepen, where you can find the code

http://codepen.io/2bu/pen/YNYjjR

4
  • 1
    box = document.getElementById('box').style.display = 'block' sets box to "block". "block".style.display won’t make sense. document.getElementsByClassName('box-open').style.display doesn’t make sense as well. Commented Jan 30, 2017 at 18:52
  • You would be better off toggling the class. Commented Jan 30, 2017 at 18:53
  • also in your else block boxOpen is undefined Commented Jan 30, 2017 at 18:54
  • OK so what is the best way of going about this ? Commented Jan 30, 2017 at 18:55

4 Answers 4

4

I am not sure but this line:

box = document.getElementById('box').style.display = 'block'

should be maybe

box = document.getElementById('box');
Sign up to request clarification or add additional context in comments.

5 Comments

I have also tried box = document.getElementById('box'); I still get the same error
Well we are definitely better here. This is a must. You need to reference a div for "box-open" you have no div with a class named 'box-open' at least not in the example above (getElementsByClassName('box-open')). I would always use getElementById unless you are intentionally trying to get a list of elements. The getElementsByClassName will return an array of elements that fit that condition (I don't think you'll have more than one...or will you).
OK cool so I made the changes. I am still getting the same error. This is an link to the new updated code on codepen. Please can you take a look
Offhand it looks ok except the onclick event does not pass anything as an argument yet your function is requesting one (open). I would assume you meant onclick="toggle(true)" or something along those lines. otherwise the "open" parameter is unknown. That may be where your unknown is coming from now.
Found the error. You went back to GetElementById but you made "Element" plural still. Change this to GetElementById (instead of GetElementsById) and pass "true" in your onclick and it works. Additionally, Tim (below) is correct in that jquery makes this kinda stuff really easy).
2

Your function is not very flexible because it can only toggle a specific box with ID "box". Instead you could pass in a selector for the element you want to toggle:

<div id="box" class="box-close"></div>
<button type="button" onClick="toggle('#box')">click me</button>

And then in your Javascript:

function toggle(selector) {
  var box = document.querySelector(selector);
  var isOpen = box.style.display === "block";
  box.style.display = isOpen ? "none" : "block";
}

This way you can use the same toggle function to toggle any box you like.

4 Comments

So this code works, but it doesn't do what I need it to do. In my code I have an ID and A Class. The game for this toggle method is to create a template which I can use it for other IDs and Classes
I don't really understand what this means ( isOpen ? "none" : "block"; )
? is the conditional operator, condition ? (value if true) : (value if false)
I made an edit to the answer. With the updated function you can just pass a valid selector (just like in CSS) to the toggle function - so both #box and .box-close would work.
1

Here is a simple jQuery implementation. Just change the .box-toggled class to be whatever you actually want. It also uses eventListener to keep your HTML cleaner.

https://jsfiddle.net/segbxnh3/3/

var box = document.querySelector('#box');
var toggleButton = document.querySelector('button');

toggleButton.addEventListener('click', function() {
    $(box).toggleClass('box-toggled');
});

UPDATE:

Here is a vanilla JS implementation. https://jsfiddle.net/segbxnh3/5/

var box = document.querySelector('#box');
var toggleButton = document.querySelector('button');

toggleButton.addEventListener('click', function() {
  if (box.classList.contains('box-toggled')) {
        box.classList.remove('box-toggled');
  } else {
    box.classList.add('box-toggled');
  }
});

2 Comments

Thank you and I appreciate the code that you wrote, But I need to figure this out in JS NOT JQUERY. I know how to write the code in JQUERY already. I am trying to figure away to write it vanilla JS
@cord updated my answer with a working vanilla js implementation.
1

You can use like this.

function toggle(open, element){
        box = document.getElementById('box');
        boxOpen = document.getElementById('box-open');
    if ( open == true) {
        box.style.display = 'none';
        boxOpen.style.display = 'block';
        element.setAttribute('onclick', "toggle(false, this);");
    }else{
          box.style.display = 'block';
          boxOpen.style.display = 'none';
          element.setAttribute('onclick', "toggle(true, this);");
    }
}
*{
  margin:0px;
  padding:0px;
  font-family: 'Montserrat', sans-serif;
}

#box{
  width:100px;
  height: 100px;
  background: gold;
  text-align: center;
  display:block;
}


#box-open{
  width:50px;
  height: 50px;
  background: green;
  display: none;
}
  <div id="box"></div>
  <div id="box-open"></div>
  <button type="button" onClick="toggle(true, this);" >click me </button>

Also, check this solution

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.