There is a thumb-up button on each message bubble of the chatbot. As there are multiple bubbles on each page, both the text bubble and the thumb-up button are indexed. I am attempting to store the results of all the thumb-up buttons in a dictionary. However, this function only saves the last thumb-up value. I am curious why this is happening.
let clickedThumbUP = false;
let rating_dict = { "ratingUp": {}};
//for each click, we store the button id and click response to a dictionary, then we push the entire dictionary to the database?
let rating_up = $(".thumbup").click(function(){
//let rating_up = checkRating(clickedThumbUP);
clickedThumbUP = !clickedThumbUP; // Toggle state on each click
// get button id
buttonid = $(this).data("index")
if (clickedThumbUP === true) {
$(this).toggleClass("thumbup thumb-up-black");
//store result in dictionary
rating_dict['ratingUp'][buttonid] = true;
//user can't press the thumbdown button
return true
}
else{
$(this).toggleClass("thumbup thumb-up-black");
//for (let item of Object.entries(rating_dict['ratingUp'])){
rating_dict['ratingUp'][buttonid] = false;
//}
return false
}
});
html
<div class="msg ${side}-msg">
<div class="msg-img" style="background-image: url(${img})"></div>
<div class="ratings">
<div class="msg-bubble">
<div class="rating-img">
<button type="submit" class="thumbup" data-index="${message_index}""></button>
<button type="submit" class="thumbDown" id="thumbDown-${message_index}"></button>
</div>
</div>
<div class="msg-text">${text}</div>
</div>
</div>
</div>
2
Answers
As you want each of your thumbs-up buttons to have its own true/false state, maintaining one global variable
clickedThumbUP
to track if the value is true/false isn’t going to do that for you, as clicking on one thumbs-up button and then a different one will change this single global variable value. Instead, check if your thumbs-up button index is already in yourrating_dict
object, and use that to determine if your thumbs-up button is active or not for the message:This can be refactored further by removing the if-statement, and instead negating the current
buttonid
value and updating the object accordingly. This works because if your button isn’t in the object, you’ll getundefined
, which when negated using!
becomestrue
:Notes:
.click()
is deprecated in jQuery, instead, use.on("click", function { ... })
return true
orreturn false
in.click()
or.on()
impacts if you prevent the default behavior of what you’re clicking on. It also stops the event from "bubbling" up the DOM to the parent elements. You typically want this to be consistent each time you click, so it’s a bit strange that you sometimesreturn false
and other timesreturn true
. If you don’t need it, remove thereturn
in your event handler callback.rating_up
variable you can remove it, and just use$(".thumup").on("click", ...)
without assigning it to anything..click()
can be replaced with.addEventListener("click", function(e) {...})
. You will need to get your elements using.querySelectorAll()
and then iterate your elements and add the event listener to each, or use event-delegation if you use this option.$(this).data("index")
can be replaced withthis.dataset.index
$(this).toggleClass(...)
can be replaced withthis.classList.toggle(...)
The problem is that you’re using a global
clickedThumbUP
variable to manage the state of all the thumb-up buttons. Instead you need have a place to store the state of each button.One place to store the state for each button element would be on a custom data attribute for each button: