Posted in API and Javascript
677
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
117
This Month
468
This Year
4181

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...

You could also follow me on twitter. I have a couple of youtube channels if you want to see some video related content. RuneScape 3, Minecraft and also a coding channel here Web Dev.

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

"Olivia, my eldest daughter, caught measles when she was seven years old. As the illness took its usual course I can remember reading to her often in bed and not feeling particularly alarmed about it. Then one morning, when she was well on the road to recovery, I was sitting on her bed showing her how to fashion little animals out of coloured pipe-cleaners, and when it came to her turn to make one herself, I noticed that her fingers and her mind were not working together and she couldn’t do anything. 'Are you feeling all right?' I asked her. 'I feel all sleepy,' she said. In an hour, she was unconscious. In twelve hours she was dead. The measles had turned into a terrible thing called measles encephalitis and there was nothing the doctors could do to save her. That was...in 1962, but even now, if a child with measles happens to develop the same deadly reaction from measles as Olivia did, there would still be nothing the doctors could do to help her. On the other hand, there is today something that parents can do to make sure that this sort of tragedy does not happen to a child of theirs. They can insist that their child is immunised against measles. ...I dedicated two of my books to Olivia, the first was ‘James and the Giant Peach’. That was when she was still alive. The second was ‘The BFG’, dedicated to her memory after she had died from measles. You will see her name at the beginning of each of these books. And I know how happy she would be if only she could know that her death had helped to save a good deal of illness and death among other children."

I just checked google books for BFG, and the dedication is there. 

https://www.google.com.au/books/edition/_/quybcXrFhCIC?hl=en&gbpv=1 


Roald Dahl, 1986
Random CSS Property

overflow-clip-margin

The overflow-clip-margin CSS property determines how far outside its bounds an element with overflow: clip may be painted before being clipped.
overflow-clip-margin css reference