skip to Main Content

I have multiple card generated from a loop which share the same functionality. One of them is to Like and Dislike buttons.
It’s someone’s code, I was asked to remove the click event per card once the user click on Like/Dislike button. I don’t know how to remove/disable the click event when one choice is picked as it might disable other cards buttons.

<button onclick="contentLike_Dislike('1','true')">Like</button>
<button onclick="contentLike_Dislike('2','false')">Dislike</button>

contentLike_Dislike(id,islike) {
    if (islike === "true") { like the page}
    else {dislike the page}
}

3

Answers


  1. Normally I would recommend an overhaul that involved using an event handler instead of inline click handler, but it seems like there is a bunch of these buttons on the same page that will need to be fixed.

    So here is a simple solution, have a variable outside of the function that is initially set to false. Then in your function, check to see if its false and at the end set it to true. I have console.logs just to show what is happening when clicked.

    UPDATE: Now that the OP has updated their question and comments with more information, I have updated my answer by storing the IDs in an array.

    let liked = []
    
    function contentLike_Dislike(id,islike) {
      const hasLiked = liked.includes(id)
      if (islike === "true" && !hasLiked) console.log("like")
      else if (islike === "false" && !hasLiked) console.log("dislike")
      if(hasLiked)console.log("already liked")
      liked.push(id);
    }
    <button onclick="contentLike_Dislike(1,'true')">Like</button>
    <button onclick="contentLike_Dislike(1,'false')">Dislike</button>
    Login or Signup to reply.
  2. By using the parent element to select buttons, you can disable only those that are within the same parent. This is optimal for the situation where you have multiple cards on the same page.

    function contentLike_Dislike(event, islike) {
        if (islike === 'true') {
          alert("like");
        } else {
          alert("dislike");
        }
        
        var buttons = event.target.parentNode.querySelectorAll("button");
        buttons.forEach((item) => {
            item.onclick = "";
        });
    }
    <div class="card">
      <button onclick="contentLike_Dislike(event, 'true')">Like</button>
      <button onclick="contentLike_Dislike(event, 'false')">Dislike</button>
    </div>
    Login or Signup to reply.
  3. I propose an approach based on event delegation.

    The advantage comes not only with getting rid of the OP’s inline scripting, but also with the registering and handling the event at exactly one root-element which does enclose the elements which actually do trigger the to be handled event.

    A clean approach would allow a handler function to retrieve all necessary information from the elements that are related to an event. One way of achieving it is the usage of both some data-* global attributes and its HTMLElement counterpart, the dataset property.

    Within the handler function one also would remove this very handler itself from the element it was registered to.

    function handlePreferenceVote({ target, currentTarget }) {
      // - remove event handler immediately
      //   from the delegate/current target.
      currentTarget
        .removeEventListener('click', handlePreferenceVote);
    
      // - read the `dataset` entries from the triggering target.
      const { preferenceId, preferenceValue } = target.dataset;
    
      if (preferenceValue === 'like') {
        // like the page
      } else if (preferenceValue === 'dislike') {
        // dislike the page
      }
      console.log({ preferenceId, preferenceValue });
    }
    
    document
      .querySelector('[data-preference-vote]')
      .addEventListener('click', handlePreferenceVote);
    <div data-preference-vote>
      <button data-preference-id="1" data-preference-value="like">Like</button>
      <button data-preference-id="2" data-preference-value="dislike">Dislike</button>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search