0

I'm creating a todo list, with each todo's HTML div containing a data-completed="true" attribute.

I am trying to toggle the completed attribute back and forth when the todo is clicked using Jquery

It switches to false, but when I click again it doesn't switch back. The flipCompleted variable seems to get stuck on false despite the fact the click event is passing in the new value.

$("body").on("click", ".todo", function() {
    let id = $(this).data("id")
    let completed = $(this).attr("data-completed")
    // dbMethods.updateTodo(id, completed)
    domMethods.updateTodo.call(this, completed)
    event.stopPropagation()
})
updateTodo: function(completed) {
        let flipCompleted = !completed
        $(this).children('.todo-title').toggleClass("completed");
        $(this).data("completed", flipCompleted);
    }

HTML:

<div class="todo" data-id="5de7d31d753b914d6f714cab" data-completed="true">
                <div class="todo-title"><h4>Go to shops</h4></div> 
                <button class="delete"><i class="fas fa-trash-alt" aria-hidden="true"></i></button>
            </div>

I've tried changing it with .attr() and .data() both of which only work once.

I'm not sure what I am doing wrong so any help would be greatly appreciated.

5
  • 1
    Just so you know, you can access the 'data-completed' attribute the same way in both scenarios, both setting and getting: let completed = $(this).data("completed") instead of let completed = $(this).attr("data-completed") Commented Dec 18, 2019 at 14:34
  • 1
    @TKoL that's in fact the problem here, since using .data() to set values won't affect the attribute. Commented Dec 18, 2019 at 14:35
  • Can you man an example in a codesandbox? That would be helpful for people who want to help you fix this problem Commented Dec 18, 2019 at 14:36
  • @Pointy oh! Of course! That makes a lot of sense actually Commented Dec 18, 2019 at 14:36
  • 1
    created a working jsfiddle with minor adjustments: jsfiddle.net/q86dar2w Commented Dec 18, 2019 at 14:50

1 Answer 1

2

The issue might be solvable by fixing an inconsistency in your code. You have this:

$("body").on("click", ".todo", function() {
    ...
    // this bit of code right here:
    let completed = $(this).attr("data-completed")
    ...
})
updateTodo: function(completed) {
        ...
        $(this).data("completed", flipCompleted);
    }

But you want to use the jQuery .data function in both cases

$("body").on("click", ".todo", function() {
    ...
    // this bit of code right here:
    let completed = $(this).data("completed")
    ...
})
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the help, this has worked! It only shows up in Jquery however, the mark up doesn't change, is this correct?
I think so. In fact I think that's the crux of hte issue: jquery .data doesn't always change the markup
jquery .data supports any kind of object or data structure, but the markup only supports strings. That's why they get desynced I suppose

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.