Forum Moderators: open

Message Too Old, No Replies

Uncaught TypeError (null) breaking script

         

not2easy

5:44 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I need some help with a dropdown script that works fine on my desktop and on several other sites but won't drop down anything in a WP environment. I do not speak javascript so I need some help with how to fix up this Uncaught TypeError (null) error. I can understand where it is and I visited the Moz help page that the error produced in ff dev tools debugger: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type but have no idea what I can do to fix it.

The whole script is only about 10 lines. These lines are where the error is:
 var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
that maxHeight = null; is where the problem starts.

The relative css for that 'panel' element is:
max-height: 0; 
I've worked for days on setting up a series of dropdown lists of varying lengths so I can't set a specific max height for the panel element. I do not know why the script functions fine outside of the WP environment since it is a basic .js script and that hasn't been replaced afaik. Can I just replace "null" with "0" in the script and at least get it functioning?

robzilla

6:32 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



panel.style.maxHeight = 'none';

Have you tried that? Null is not a valid value for max-height, but "none" is (default value).

You'll probably have to adjust your if() condition after that.

Maybe your WP environment forces strict mode?

not2easy

6:44 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I'll try that and see if it handles the problem. Thank you for the help, I have no idea how to adjust the if() condition if it needs adjusting. Sorry, I do not write javascript. It was doing fine until I tried to use it on this one page though it is still working on other static html pages. I will let you know if I see other errors or if that was all it needed.

Thanks robzilla!

robzilla

7:01 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You could also try:
panel.style.maxHeight = '';

If you use the 'none' value, your if() would have to be changed to something like if(panel.style.maxHeight && panel.style.maxHeight != 'none'), because 'none' is truthy whereas null would have been falsy.

Strict mode doesn't seem to have a problem with the null value in my testing, so I'm not sure why it trips up for you. I'm no javascript expert either, maybe someone else will chime in. Or post the rest of the code, that would also help.

[edited by: robzilla at 7:03 pm (utc) on Jul 17, 2021]

not2easy

7:02 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



No, it shows the same error and highlight line 9:
 if (panel.style.maxHeight){


I don't want to set a max-height because the lists vary from 5 items to 14 items. I am looking for some other way to display these now, but since it is dozens of lists, I was hoping to be able to get it going without starting over.

I'll try that adjustment, to the script. I do appreciate your suggestions, I do not know the syntax for .js so I would really make a mess without help. I cannot guess why it is giving me grief either, as mentioned this is the first time it has not worked as expected.

not2easy

7:08 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The entire code is:
var acc = document.getElementsByClassName("dropdown");
var i;

for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = 'none';
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});


The rest is in .css but only determines the appearance of the button to open and close the dropdown. The panel element (var) is the hidden html for the dropdown that shows when active.

robzilla

7:16 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



var acc = document.getElementsByClassName("dropdown");
var i;

for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
console.log(i);
console.log(panel);
});

What does this show in the debugger?

not2easy

7:30 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The debugger response is:
Uncaught TypeError: panel is null
<anonymous> https://www.example.com/dropdown.js:9

not2easy

7:36 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Sorry robzilla, I did not notice that your suggestion was not what I have in the script.

I'll copy that to the script and replace the version I was referring to in the response. It takes some time due to log in to try it, check that it has refreshed, etc...

Thank you for your help.

not2easy

7:44 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I get a different error now: syntax

Uncaught SyntaxError: missing } in compound statement dropdown.js:12:10note: { opened at line 5, column 33dropdown.js:5:33


So I can add in a closing c brace just at the end (line 12) and try again.

not2easy

7:55 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Now I get a different error:
20 dropdown.js:9:10
null dropdown.js:10:10
20 dropdown.js:9:10
null dropdown.js:10:10

robzilla

8:19 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



OK, so if panel is null, then it stands to reason that you'll get an error trying to access panel.style.maxHeight in your if(). You can't access the CSS styles of an element that cannot be found.

If panel is null, then this.nextElementSibling is returning null. Apparently the element with class "dropdown" that you clicked to get the above output does not have a sibling coming after it.

(The "20" in the debugger output is the nth dropdown you clicked, the null value that follows is its non-existent sibling.)

Can you post some of the HTML as well? You can simplify or censor it, if you like, but it would be helpful to see the structure of the HTML elements that you're targeting with javascript.

not2easy

9:10 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



OK, thank you for that information robzilla because I think the error might possibly be due in part to using a relative link to the script which is called by a form in the yoast plugin. I used that because only this one page uses this script. I could load the tiny script for all pages and use it only on the one page. I can put the link to an 'earlier' implementation like the functions file or a theme hook that might resolve better. I am leaning toward thinking that if I were to move the script to the theme's folder and not use a relative link to the root that might handle it better.

All the stylesheets and .js stuff in the theme are within the theme folder and the theme's stylesheet might have elements that affect its css. More to look at.

It may not have affected views on my desktop because none of the other WP elements or the functions.php settings were on the plain html page I was using to create the content. I am thinking of the CSS for buttons in particular because that element is present although I don't use it, WP does for search and such. The button elements in css might affect this script because the head element of the content is <button class="dropdown"> Clearly I need to take a closer look at these elements. It worked fine on desktop using the same stylesheet but without the other WP elements.

Each button has an ID so I could call the content by ID I guess. The page is not about rugs at all, but for an example, think of 4 - 15 rugs of various lengths. Each section lists the price by length sorted by widths. So there is a panel for "4ft" and another for "5ft" etc. to 24ft. I wanted to hide each section until clicked so people don't need to scroll a long page to get to the length they are interested in. The height of each panel is controlled by its content when it works.

I have much to investigate I think.

robzilla

10:25 pm on Jul 17, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Well, if you got the errors then probably the script was being loaded correctly. But if something in WP is messing with your HTML then maybe you can't rely on nextElementSibling(). It's more foolproof to use something like a dataset, or classes/IDs, as you say. So if your button has an ID, maybe give that same ID to your dropdown (as a class or in a dataset), so that you can more reliably target that element in the event listener.

lucy24

12:05 am on Jul 18, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Tangentially: Do all your scripts come with try / catch loops? It is of course better not to have errors at all, but second-best is to make sure the whole thing doesn't grind to a screeching halt. (I can tell which of my scripts include code cribbed from someone else, because they all have this element. I’d actually forgotten what the command was, and wasted a good deal of time searching for "onErr(blahblah)"--who knows what language that would have been.)

not2easy

12:44 am on Jul 18, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



If this was @me -
Do all your scripts come with try / catch loops?
This is pretty much "all my scripts" right here.

If I used lots of scripts I might have learned something about .js by now, but I don't.