Need Help With Checkboxes

I am working on a todo app and im having a problem with getting checkboxes to work properly with JS.

The problem i have is when the checkbox is clicked it won’t tick/untick, but clicking anywhere else inside the blue area and it functions correctly.

Any help with why this is happening will be much appreciated!

Project Files: https://github.com/shiney1884/Todo-App

Just with a quick glance, I see that you have many elements with the same id. Ids should be unique, not just for inputs but for any sort of element. So maybe:

<input type="checkbox" id="check1">
<input type="checkbox" id="check2">

that might be causing your problem.

Nah this has changed anything, tried looping through the checkboxes before so that’s why i applied the id’s but in the current code they aren’t being used.

It would be a lot easier to help if you had a live setup. Can you put it in CodePen or something? Also, do the checkboxes work when it’s just simple html? If so, it’s probably the JS code .

Ok yea i can do that for you. And the checkboxes did work with only html.

Heres the codepen: https://codepen.io/shiney1884/pen/rNxbJMX

I am not sure 100% if this will solve it, but I see a couple of things that might move us to getting this fixed.

The first thing is that it would probably be better to separate your event listener from the logic of the desired behavior. So it will look something like this:

listItem = document.querySelectorAll(".item");

clickHandler() { code to handle click }

listItem.forEach( item => item.addEventListener("click", clickHandler); 
//you used a for statement to do the same thing, which is fine

This will break up the code into parts so it’s easier to tell what’s going on. Also, notice I used querySelector to get “.item”, which is a class, not “#item”, which is an id. Ids must be unique on the page, but you have three elements with the same ids. I don’t know if that’s part of the issue here or not, but ids must be unique.

The second thing is that you don’t need to iterate through the listItem array-like structure to find out which one was clicked. You can use event.target for that. If you’re passing event into the clickhandler function (like clickHandler(e), then you have access to the event.target, which will give you the input, list item, and/or div that the user clicked on.

That will probably help untangle what’s going on. Right now the logic is contradicting itself when you click on the checkbox input (at least I think that’s what’s going on).

I’ve cleaned up my code by doing this, thanks it does make it look a lot cleaner. I’ve read about the event.target and doesn’t this just give me the tag (li, input etc.) that I clicked on? What’s the best way to identify which one of the items it was that was clicked to then apply the css to only that item?

yeah, I’m not really an expert but I can give you some ideas. The first one is to console out the event.target in the clickhandler function (console.log(event) inside the function and then open it up and look). It should give you an object and you can open it in the console and see what’s popping up.

One way you might approach it is to put a control statement in the clickhandler–if (e.target === checkboxthing) for one thing, else (it must be the list area). So even though different things call the function, inside the function you put the control to figure out what it was that called it (probably explaining this poorly).

I think if you poke around the event element in the console you might see something you can use. Or… and here it’s more hacky, you could either use a separate class on the checkbox to separate it out (again, using a control statement).

One thing that complicates things is called “event propagation” or “bubbling,” which means even if you click on a particular child element, that it also may register as an event on the parent element. But I don’t know if that’s what’s going on here.

Yea i’ve heard of bubbling and it’s what i was thinking about when doing the js on this project.

One thing i’m trying currently is removing the input tag from the li tag.