Simple Like Dislike Button – Free Code Download

Welcome to a tutorial and example on how to create a like-dislike button. Want to add your own like/dislike button? Here’s a quick sharing of my simple version using pure HTML CSS Javascript, no third-party libraries. Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Demo Like Dislike Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

QUICKSTART & DEMO

1-demo-simple.html
<!-- (A) LOAD JS + CSS -->
<link rel="stylesheet" href="likedis.css"/>
<script src="likedis.js"></script>
 
<!-- (B) EMPTY HTML <DIV> -->
<div id="demo"></div>
 
<!-- (C) JAVASCRIPT -->
<script defer async>
// (C1) ATTACH LIKE/DISLIKE WIDGET
var el = document.getElementById("demo");
likedis.attach({target : el});
 
/* (C2) TO GET LIKE/DISLIKE STATUS
// -1 DISLIKE, 0 NOT SET, 1 LIKE
var liked = el.dataset.like; */
</script>

For you guys who just want to use this as a “plugin” without reading everything:

  1. Load the CSS and Javascript.
  2. Create an empty <div> to create the like/dislike buttons.
  3. On page load, simply call likedis.attach({target : ELEMENT}) to attach the like/dislike buttons.

That’s all. Check ELEMENT.dataset.like to get the like status – 0 if not set, 1 for like, -1 for dislike.

 

 

LIKE DISLIKE BUTTON

All right, let us now get into the details of the like/dislike button.

 

1) THE JAVASCRIPT

likedis.js
var likedis = {
  // (A) CREATE WIDGET
  // opt : option
  //  target : target element to attach widget
  //  uptxt : optional. default upvote text.
  //  downtxt : optional. default downvote text.
  attach : function (opt) {
    // (A1) CONTAINER CSS + DEFAULT "LIKE STATUS" + CUSTOM DATA
    opt.target.classList.add("likedis");
    opt.target.dataset.like = "0";
    if (opt.data) { for (let k in opt.data) {
      opt.target.dataset[k] = opt.data[k];
    }}

    // (A2) UPVOTE + DOWNVOTE ICONS
    let up = document.createElement("div"),
        icoup = document.createElement("div"),
        down = document.createElement("div"),
        icodown = document.createElement("div");
    up.classList.add("up");
    down.classList.add("down");
    icoup.classList.add("icoup");
    icodown.classList.add("icodown");
    up.appendChild(icoup);
    down.appendChild(icodown);
    opt.target.appendChild(up);
    opt.target.appendChild(down);

    // (A3) UPVOTE + DOWNVOTE TEXT
    let notxt = opt.uptxt === undefined || opt.downtxt === undefined,
        txtup, txtdown;
    if (notxt) {opt.target.classList.add("notxt"); }
    else {
      txtup = document.createElement("div");
      txtdown = document.createElement("div");
      txtup.classList.add("txtup");
      txtdown.classList.add("txtdown");
      txtup.innerHTML = opt.uptxt;
      txtdown.innerHTML = opt.downtxt;
      down.appendChild(txtdown);
      up.appendChild(txtup);
    }

    // (A4) ON LIKE/DISLIKE
    up.addEventListener("click", function(){
      likedis.toggle(opt.target, 1);
      if (opt.change) { opt.change(opt.target, txtup, txtdown); }
    });
    down.addEventListener("click", function(){
      likedis.toggle(opt.target, 0);
      if (opt.change) { opt.change(opt.target, txtup, txtdown); }
    });
  },

  // (B) TOGGLE LIKE/DISLIKE
  toggle : function (target, direction) {
    // (B1) GET CURRENT STATUS
    let current = target.dataset.like;

    // (B2) LIKE
    if (direction) {
      if (current=="1") { target.dataset.like = "0"; }
      else { target.dataset.like = "1"; }
    }

    // (B3) DISLIKE
    else {
      if (current=="-1") { target.dataset.like = "0"; }
      else { target.dataset.like = "-1"; }
    }
  }
};

This looks massive at first, but keep calm and look carefully. Not going to explain line-by-line, since the Javascript is very straightforward:

  1. Basically, we are just creating the HTML elements and what to do on click. Will go through the generated HTML below.
  2. Toggle the like/dislike status.

 

 

2) THE HTML

<div id="demo" class="likedis" data-like="0">
  <!-- UPVOTE -->
  <div class="up">
    <div class="icoup"></div>
    <div class="txtup"></div>
  </div>
 
  <!-- DOWNVOTE -->
  <div class="down">
    <div class="icodown"></div>
    <div class="txtdown"></div>
  </div>
</div>T

Yep, this is what the above Javascript generates.

  • <div class="up"> is the upvote button, <div class="down"> is the downvote button.
  • <div class="icoup"> and <div class="icodown"> are the thumbs up and thumbs down icons. Feel free to change this if you want to use your own image or icon set.
  • Lastly, <div class="txtup"> and <div class="txtdown"> is an open text field – Use this to set your “like” and “dislike” text, or use this to show the total count.

 

3) THE CSS

likedis.css
/* (A) CONTAINERS */
.likedis {
  width: 150px;
  margin: 5px;
}
.likedis.notxt { width: 80px; }
.likedis, .likedis .up, .likedis .down { display: flex; }

/* (B) LIKE DISLIKE BUTTONS */
.likedis .up, .likedis .down {
  align-items: center;
  width: 50%;
  cursor: pointer;
}

/* (C) THUMBS ICON */
.likedis .icoup, .likedis .icodown {
  width: 24px; height: 24px;
  background: url("likedislike.png");
}
.likedis .icodown { background-position: -48px; }

/* (D) TEXT OR COUNT */
.likedis .txtup, .likedis .txtdown {
  color: #989898;
  font-weight: 700;
  flex-grow: 1;
  text-align: center;
}

/* (E) LIKED + DISLIKED */
.likedis[data-like="1"] .icoup { background-position: -24px; }
.likedis[data-like="1"] .txtup { color: #2a3c94; }
.likedis[data-like="-1"] .icodown { background-position: -72px; }
.likedis[data-like="-1"] .txtdown { color: #a02727; }

Just some CSS cosmetics. Feel free to change to your own liking.

 

 

USEFUL BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

EXTRA – ADVANCED EXAMPLE

demo-advanced.html
<!-- (A) LOAD JS + CSS -->
<link rel="stylesheet" href="likedis.css"/>
<script src="likedis.js"></script>
 
<!-- (B) EMPTY HTML <DIV> -->
<div id="demo"></div>
 
<!-- (C) JAVASCRIPT -->
<script defer async>
// (C1) TO HANDLE LIKE/DISLIKE UPDATE
function likeupdate (container, up, down) {
  // -1 DISLIKE, 0 NOT SET, 1 LIKE
  console.log(container.dataset.like);

  // YOUR OWN CUSTOM DATA, SEE BELOW
  console.log(container.dataset.id);
  console.log(container.dataset.foo);
  
  // RUN YOUR OWN SCRIPT - AJAX UPDATE OR SOMETHING
  // IF YOU ARE DOING LIKE/DISLIKE COUNTS
  // up.innerHTML = "123";
  // down.innerHTML = "456";
}
 
// (C2) ATTACH LIKE/DISLIKE WIDGET
var el = document.getElementById("demo");
  likedis.attach({
  // TARGET <DIV>
  target : el,
  // CUSTOM DATA
  data : {
    id : 123,
    foo : "bar"
  },
  // DEFAULT TEXT
  uptxt : "YEA",
  downtxt : "NO",
  // ON LIKE STATUS CHANGE
  change : likeupdate
});
</script>

Finally, here is an “advanced example” with all the options –

  • target As above, where to generate the like/dislike buttons.
  • data Optional custom data to attach – The ID and whatever else.
  • uptxt and dontxt Custom text for the like/dislike. Use this as a counter if you want.
  • change This should be a function that has 3 parameters – The container (target), upvote uptxt, downvote downtxt. Fired whenever the user changes the like/dislike status. Use this to do your own AJAX calls or interface updates.

 

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *