Emily K
Emily K

Reputation: 13

jquery add and remove class working inconsistently

I am making a to-do list app. When the user clicks the checkmark to add the class .done, then the text in the <span> should gray out, and the checkmark should fill in and turn black. If they uncheck it, the text should return to black and the checkmark to it's unchecked state.

This works until there is more than one item, and then it works inconsistently. Sometimes the checkmarks won't do anything when checked, sometimes the text stays grayed out but the checkmark returns to unchecked. I am a beginner at jQuery (as I'm sure will be obvious when you see my code), and this is my first post here. I have searched and I am not finding information I haven't tried. I tried to make sure the class is removed before adding a new one.

Here is the js:

$(".checkmark").on("click", function() {
      // alert($(this));

      if ($(this).attr('data-icon') == '\ue603') {
        $(this).attr('data-icon', '\ue600').removeClass("notdone").addClass("done")
      }
      else {
        $(this).attr('data-icon', '\ue603').removeClass("done").addClass("notdone")
      };

      if ($("span.checkmark").is(".done")) {
        // $("#list").prev(".list_item").addClass("grayedout")
        $(this).next().addClass("grayedout")
        // alert(this);
       }
       else {
        $(this).next().removeClass("grayedout")
       };

    });

    $(".delete").on("click", function() {
        // alert("delete me!");
        $(this).closest("li").remove();
      });

 });
    var addItems =function(e) {
          e.preventDefault();

        //make sure the input isn't blank
        if($("#item").val()=='') {
            alert("please enter some sh!t to get done");
          }

        else {
          //add list item 
          $("#list ul").append('<li><span aria-hidden="true" data-icon= '+ uncheck +' class="checkmark"></span><span class="list_item">'+ $('#item').val() + '</span><span aria-hidden="true" data-icon="&#xe601;" class="delete"></span></li>');              
          // clear input box
          $("#item").val("");
           };
    };

Here is a link to the page: http://eak000.github.io/todo/ Thanks in advance for any help.

Upvotes: 1

Views: 169

Answers (1)

Arun P Johny
Arun P Johny

Reputation: 388406

The problem is the line

if ($("span.checkmark").is(".done")) {

it checks whether the first checkmark element has the class done, instead you need to check whether the currently clicked checkmark has the class done so

if ($(this).is(".done")) {
//or if ($(this).hasClass("done")) {

You have another problem in the way in which you are adding the click handler, you are adding the click handler inside another click handler(the add button) which also could lead to problems.

The reason you might have done that is to handle dynamic elements, but the solution is to use event delegation, so instead of adding the click handler in the $("#item").on("keypress", function(e) { handler try to add the below in the dom ready handler

$('.list').on("click", '.checkmark', function () {
    // alert($(this));

    var isDone = $(this).hasClass("done");
    $(this).attr('data-icon', isDone ? '\ue600' : '\ue603').toggleClass("notdone", isDone).toggleClass("done", !isDone)

    $(this).next().toggleClass("grayedout", !isDone)

});

$('.list').on("click", '.delete', function () {
    // alert("delete me!");
    $(this).closest("li").remove();
});

Upvotes: 1

Related Questions