1

I want a button on my php page to hide and unhide a section on my page. I have this javascript function:

      function toggle_filters(){
    var x = document.getElementById("filters");
    var displayState = x.style.display;
    if(displayState == "none")
    {
        displayState = "block";
    }
    else {
        displayState = "none";
    }
}

and i have this html code:

<section id="buttons">
    <button id="filter_button">Filters</button>
</section>
<section id="filters">
    <form>
        <select>
            <option>1st option</option>
            <option>2nd option</option>
        </select>
    </form>
</section>

(it is a simplified version)

The problem is that my browser gives me this error:

Uncaught TypeError: Cannot read property 'style' of null

Here is a jsfiddle with my code: https://jsfiddle.net/90wkwn65/2/

I searched the internet but I can't find an answer. Any help would be appreciated!

  • It's preferred to toggle the *display* property between "none" and "" (empty string) so that when visible, the element adopts its default or inherited style. It's more generic than setting it to "block", which doesn't suit many elements. Oh, and the error is probably because the function is running before the element exists in the page. – RobG May 15 '15 at 23:52
  • It's a typo, I'll edit it. – Lorenzo De Bie May 15 '15 at 23:53

2 Answers2

3

When you do this:

var displayState = x.style.display;

displayState is just a variable that contains a string. It has zero connection to x.style any more.

So, when you then do this:

displayState = "block";

All you're doing is change the value of the displayState variable - no connection at all to the style object of x. So you need to assign to a property on the actual style object in order to actually change the style.


Also from the code in your jsFiddle, you need to change this:

document.getElementById("filter_button").onclick = toggle_filters();

to this:

document.getElementById("filter_button").onclick = toggle_filters;

When you put () after a function name that function is executed immediately and the return result would be applied as the onclick handler. In this particular case you just want to assign a function reference as the onclick handler so you pass only the function name without parens after it.


Applying those two changes, this code works in the jsFiddle:

function toggle_filters(){
    var x = document.getElementById("filters");
    if(x.style.display == "none")
    {
        x.style.display = "block";
    }
    else {
        x.style.display = "none";
    }
}
document.getElementById("filter_button").onclick = toggle_filters;

The above code works in the jsFiddle, but if your real code is still getting the error:

Uncaught TypeError: Cannot read property 'style' of null

Then, that is because you're running the document.getElementById("filter_button") line of code too soon (probably in the <head> section). Instead, you must run that line of code only AFTER the DOM has been loaded. The simplest way to do that is to move that <script> tag to right before the </body> tag. See this answer (pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it) for much more detail on this issue.

Community
  • 1
  • 1
jfriend00
  • 580,699
  • 78
  • 809
  • 825
1

You can store element.style as a reference in order to alter the css properties, but you cannot store element.style.display as a reference in the same way.

Also when assigning an onclick function, do not use parenthesis, otherwise the function will execute instead of being assigned to the click event.

(Demo)

  function toggle_filters() {
      var x = document.getElementById("filters");
      if (x.style.display === "none") {
          x.style.display = "block";
      } else {
          x.style.display = "none";
      }
  }
  document.getElementById("filter_button").onclick = toggle_filters;