Posted in API and Javascript
3029
4:06 am, March 15, 2022
 

Love Like Dislike API and Javascript

Working Example Full Page

You can check it out below, just include the script and it records the details based on the current URL. 

Love Like API Demo

Quick Embed

Add this to the page where you would like the icons and likes to appear. 

HTML

<div id="love_like">&nbsp;</div><script src="https://api.kruxor.com/js/lovelike.js"></script>

 

The Idea

An API that allows a url to have love, like or dislike's attached to it. 

Quite simple layout. 

url, love_num, like_num, dislike_num

then have a way to send the nums, and update the buttons with the number. 

just include a script on the page and it will do the rest, show the buttons, and current stats. 

Demo

Structure

Script

/js/lovelike.js

This script needs to, write to the page the love, like dislike buttons.

allow turning on and off of buttons

send click data to the api, will need a way of updating this via php callback via ajax.

load the existing values from the api data for the url

Get the Icons

Try icons from : https://heroicons.com/ 

Love: 

<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" />
</svg>

Like: 

<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" />
</svg>

Dislike: 

<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path d="M18 9.5a1.5 1.5 0 11-3 0v-6a1.5 1.5 0 013 0v6zM14 9.667v-5.43a2 2 0 00-1.105-1.79l-.05-.025A4 4 0 0011.055 2H5.64a2 2 0 00-1.962 1.608l-1.2 6A2 2 0 004.44 12H8v4a2 2 0 002 2 1 1 0 001-1v-.667a4 4 0 01.8-2.4l1.4-1.866a4 4 0 00.8-2.4z" />
</svg>

Write the buttons to the page

/* draw the buttons on the page */
/* <div id="love_like">&nbsp;</div> */
function kx_draw_buttons() {
  var kx_buttons = `<style>.kx-buttons {
    padding:10px;
    border-radius:5px;
    background:#000;
    position:absolute;
  }
  </style>
  <div class='kx-buttons'>

  </div>`;
  document.getElementById("love_like").innerHTML = kx_buttons;
}
window.onload = function() {
  kx_draw_buttons();
}

Include Test Script

<div id="love_like">&nbsp;</div><script src="https://api.kruxor.com/js/lovelike.js"></script>

Just adding text to start with, with the values.

Love: 0 Like: 0 Dislike: 0

Then attach click events to each item, to allow a callback to the api to write the data back to the database. 

Testing here: https://kruxor.com/view/code/OSUTE/test-love-like-dislike-script-from-api/ 

Read and Write Class Values

Add a php script that loads the love like class and allows reading and writing to it. 

callback.php

<?php

error_reporting(E_ALL);
ini_set( 'display_errors','1');

/* accept callbacks for api js's */

/* ?class=love_like&calltype=read

https://api.kruxor.com/callback.php?class=love_like&calltype=read
https://api.kruxor.com/callback.php?class=love_like&love=1&like=0&dislike=0&url=test

Allowed Vars
class = love_like
calltype = write, read ?? does need this? prob not.

*/

if(!isset($_GET['class'])) {
  return false;
} else {
  // only allow certain classes to be called, otherwise anything can be written...
  $class = $_GET['class'];
  // add additional allowed classes here...
  if($class === "love_like") {
    // add additional classes to this if...
  } else {
    return false;
  }
}

/*
if(!isset($_GET['calltype'])) {
  return false;
} else {
  $calltype = $_GET['calltype'];
}
*/

// try and start the class with no global inc
include("class/core.class.php");
include("class/functions.class.php");
include("class/db.class.php"); // ???

// start required classes. 
$functions = new functions;

// check if the class exists for $class extend load.
$class_file_name = "class/extends/" . $class . ".extend.php";
if(file_exists($class_file_name)) {
  include($class_file_name);
} else {
  return false;
}

$class_start = new $class;
$class_start->start();

if($class === "love_like") {

  if(isset($_GET['url'])) {
    $url = $_GET['url'];
  } else {
    return false; // need a url to continue
  }
  if(isset($_GET['love'])) {
    $love = $_GET['love'];
    // these must equal 1 only
    if($love > 1) {
      return;
    }
  } else {
    $love = 0;
  }
  if(isset($_GET['like'])) {
    $like = $_GET['like'];
    if($like > 1) {
      return;
    }
  } else {
    $like = 0;
  }
  if(isset($_GET['dislike'])) {
    $dislike = $_GET['dislike'];
    if($dislike > 1) {
      return;
    }
  } else {
    $dislike = 0;
  }

  // load from any match url.
  $fields_array = [
    "url" => $url,
  ];
  if($class_start->load_from_fields_array($fields_array, $max = 1)) {
    // we have a record and its loaded, otherwise add it.
    $class_start->love = $class_start->love + $love;
    $class_start->like = $class_start->like + $like;
    $class_start->dislike = $class_start->dislike + $dislike;
    $class_start->update();
  } else {
    $class_start->url = $url;
    $class_start->love = 0 + $love;
    $class_start->like = 0 + $like;
    $class_start->dislike = 0 + $dislike;
    $class_start->add();
  }

  // return this data as an array that can be used to update the page.

 

}


echo $class_start->nice_name;

 

?>

Callback is now writing data, just needs to return something useful. 

https://api.kruxor.com/callback.php?class=love_like&love=1&like=0&dislike=0&url=http://kruxor.com

Love Like Javascript

/* draw the buttons on the page */
/* <div id="love_like">&nbsp;</div> */
function kx_draw_buttons() {
  var kx_buttons = `<style>.kx-buttons {
    position:relative;
  }
  .kx-buttons span {
    cursor:pointer;
  }
  .kx-icon svg {
      height:22px;
      width:22px;
  }
  .kx-love-label svg {
    fill:#cd4343;
  }
  .kx-like-label svg {
    fill:#4d9d4d;
  }
  .kx-dislike-label svg {
    fill:#564e4e;
  }
  .kx-value {
    margin-right:8px;
    display:inline-block;
    position:relative;
    top:2px;
    line-height:1;
  }
  </style>
  <div class='kx-buttons'>
    <span class='kx-icon kx-love-label' id='kx_ll' title='Love This'><svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" />
</svg></span>
    <span class='kx-love-value kx-value' id='kx_lv'>0</span>
    <span class='kx-icon kx-like-label' id='kx_lil' title='Like'><svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" /></span>
    <span class='kx-like-value kx-value' id='kx_liv'>0</span>
    <span class='kx-icon kx-dislike-label' id='kx_dl'><svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
  <path d="M18 9.5a1.5 1.5 0 11-3 0v-6a1.5 1.5 0 013 0v6zM14 9.667v-5.43a2 2 0 00-1.105-1.79l-.05-.025A4 4 0 0011.055 2H5.64a2 2 0 00-1.962 1.608l-1.2 6A2 2 0 004.44 12H8v4a2 2 0 002 2 1 1 0 001-1v-.667a4 4 0 01.8-2.4l1.4-1.866a4 4 0 00.8-2.4z" />
</svg></span>
    <span class='kx-dislike-value kx-value' id='kx_dv'>0</span>
  </div>`;
  document.getElementById("love_like").innerHTML = kx_buttons;
}
window.onload = function() {
  kx_draw_buttons();

  let kx_love = 0;
  let kx_like = 0;
  let kx_dislike = 0;
  let kx_clicked = false;

  document.getElementById("kx_ll").onclick = function(){
    kx_love = 1;
    kx_like = 0;
    kx_dislike = 0;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }
  document.getElementById("kx_lv").onclick = function(){
    kx_love = 1;
    kx_like = 0;
    kx_dislike = 0;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }
  document.getElementById("kx_lil").onclick = function(){
    kx_love = 0;
    kx_like = 1;
    kx_dislike = 0;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }
  document.getElementById("kx_liv").onclick = function(){
    kx_love = 0;
    kx_like = 1;
    kx_dislike = 0;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }
  document.getElementById("kx_dl").onclick = function(){
    kx_love = 0;
    kx_like = 0;
    kx_dislike = 1;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }
  document.getElementById("kx_dv").onclick = function(){
    kx_love = 0;
    kx_like = 0;
    kx_dislike = 1;
    if(kx_clicked === false) {
      kx_get_data(kx_love,kx_like,kx_dislike);
    }
    kx_clicked = true;
  }

  kx_get_data(0,0,0);

}

/*
function kx_send_like() {
  alert("like_clicked, send like and update value. ");
}
function kx_send_love() {
  alert("love clicked, send love and update value. ");
}

function kx_get_data() {
  const data = null;
  const xhr = new XMLHttpRequest();
  xhr.withCredentials = false;
  xhr.addEventListener("readystatechange", function () {
      if (this.readyState === this.DONE) {
          // console.log(this.responseText);
      // var data = JSON.parse(this.responseText);
      }
  });
  xhr.open("GET", "https://api.kruxor.com/callback.php?class=love_like&love=0&like=0&dislike=0&url=test");
  xhr.send(data);
  let data_json = JSON.parse(data);
}
*/


function kx_get_data(kx_love,kx_like,kx_dislike) {
    console.log("kx_love:"+kx_love);
    var path = "https://api.kruxor.com/callback.php?class=love_like&love="+kx_love+"&like="+kx_like+"&dislike="+kx_dislike+"&url="+window.location.href;
    kx_load_json(path,"");
}
function kx_load_json(path, callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4) {
            if (httpRequest.status === 200) {
                var data = JSON.parse(httpRequest.responseText);
                //console.log(data);
                let love_val = data.love;
                kx_update_vals(data.love, data.like, data.dislike);
                console.log(love_val);
                if (callback) callback(data);
            }
        }
    };
    httpRequest.open('GET', path);
    httpRequest.send();
}

function kx_update_vals(love, like, dislike) {
  document.getElementById("kx_lv").innerHTML = love;
  document.getElementById("kx_liv").innerHTML = like;
  document.getElementById("kx_dv").innerHTML = dislike;
}

Result

Test and Working Demo

Testing, and now its working... yay.

Still To Add

Styles, and maybe stop it at one click, rather than it sending back over and over again, when each element is clicked. 

Working

Now just add this to any page and you can record love, like and dislike ratings...

      <style>.kx-buttons {text-align:right;margin-bottom:10px;}</style>
      <div id="love_like">&nbsp;</div><script src="https://api.kruxor.com/js/lovelike.js"></script>

View Statistics
This Week
90
This Month
383
This Year
276

No Items Found.

Add Comment
Type in a Nick Name here
 
Other Items in API and Javascript
Search Articles
Search Articles by entering your search text above.
Welcome

This is my test area for webdev. I keep a collection of code here, mostly for my reference. Also if i find a good link, i usually add it here and then forget about it. more...

Subscribe to weekly updates about things i have added to the site or thought interesting during the last week.

You could also follow me on twitter or not... does anyone even use twitter anymore?

If you found something useful or like my work, you can buy me a coffee here. Mmm Coffee. ☕

❤️👩‍💻🎮

🪦 2000 - 16 Oct 2022 - Boots
Random Quote
“We ought to take outdoor walks in order that the mind may be strengthened and refreshed by the open air and much breathing.".
Seneca
Random CSS Property

:past

The :past CSS pseudo-class selector is a time-dimensional pseudo-class that will match for any element which appears entirely before an element that matches :current. For example in a video with captions which are being displayed by WebVTT.
:past css reference