There's a new component on the estate!

It will be named the feedback script.

The idea is simple, it should be non-intrusive, and easy to respond to.

That's why there is only a small edge in the bottom to indicate there is something, and as the user hover over it, it will show the entire div

So how is this done?

This sounds like one of those cases that should be simple, we just wish somebody else already made it and not having to bother with it.

Well, here it is

CSS

#tabfeedback
{
  text-align:center;
  height: 10px; 
  width: 100%; 
  position: fixed; 
  bottom:0px;
  left:0px; 
  z-index: 1;
  background-color:white;
}
#tabfeedback:hover
{
  height: 50px; /* Increase height on hover */ 
  z-index: 1;
  transition:height 0.5s /* Introduces animation */
}

Now on to the HTMLAdd this anywhere in the page

<div id="tabfeedback">
<span id="spanfeedback">Do you like this page?</span>
	<a href="#" onclick="upvote();return false;">✔</a> 
	<a href="#" onclick="downvote();return false;">x</a>
  <div id="comment" class="hidden">
    	<input id="txt" type="text" onkeypress="sendfbtext(this, event);" />
  </div>
</div>

The magic in upvote(), downvote() and sendbftext() is in the javascript

function vote(data)
{
$.ajax({
      url: "php/feedback.php", //use your own php path here
      type: 'POST',
      data: data,
      dataType: 'json'
      });
}
function sendfbtext(obj, event)
{
	if (event.keyCode == 13)
	{
		//send data
		var data = {action:'down', comment: obj.value};
		vote(data);
		$("#comment").addClass("hidden");
	}
}

function upvote()
{
     var data = {action:'up'};
     vote(data);     
     $("#spanfeedback").text("Thank you for the vote of confidence.");
     $("#comment").css("display:inline-block");
}
function downvote()
{
    var data = {action:'up'};
    vote(data);
    $("#spanfeedback").text("Thank you for your feedback.");
    $("#comment").removeClass("hidden");
}

Don't forget to include jQuery

Now onto your php script.

This will be a multi-part script

1) The database script (db.php) is used to simplify connection, you might already have your own database module, so it's best to use your judgment for that

<?php
class DBConn
{
   private $url;
   private $user;
   private $pass;
   private $db;
   private $conn;

   function __construct($url, $user, $pass, $db)
   {
    $this->url = $url;
    $this->user = $user;
    $this->pass = $pass;
    $this->db = $db;
   }

   function __destruct()
   {
     mysqli_close($this->conn);
   }

   function connect()
   {
     $this->conn = mysqli_connect($this->url, $this->user,$this->pass,$this->db) or die("Error ".mysqli_error($this->conn));
     return $this;
   }
  
   function query($query)
   {
	return $this->conn->query($query);
   }

   function execute($code, $a_param_type, $a_bind_params)
   {
      $stmt = $this->conn->prepare($code);
      if (isset($a_param_type) && !empty($a_param_type) && isset($a_bind_params) && !empty($a_bind_params))
      {
	
	//curtesy of http://www.pontikis.net/blog/dynamically-bind_param-array-mysqli
	/* Bind parameters. Types: s = string, i = integer, d = double,  b = blob */
	$a_params = array();
	 
	$param_type = '';
	$n = count($a_param_type);
	for($i = 0; $i < $n; $i++) {
	  $param_type .= $a_param_type[$i];
	}
	 
	/* with call_user_func_array, array params must be passed by reference */
	$a_params[] = & $param_type;
	 
	for($i = 0; $i < $n; $i++) {
	  /* with call_user_func_array, array params must be passed by reference */
	  $a_params[] = & $a_bind_params[$i];
	}
      	call_user_func_array(array($stmt, 'bind_param'), $a_params);
      }

      if (!$stmt)
      {
         echo "Error:".$this->conn->error;
      }
      return $stmt->execute();
   }
   
   function executeNoParam($code)
   {
      return $this->execute($code, null, null);
   }

   function getConn()
   {
     return $this->conn;
   }
}

?>

2) Install script

<?php
include('common/db.php');
$configs = parse_ini_file("configs/configs");

$db = new DBConn($configs['path'],$configs['user'],
		   $configs['password'], '');
$conn = $db->connect()->getConn();
$dbname = $configs['database'];

$query = "CREATE DATABASE IF NOT EXISTS ".$dbname;

$db->executeNoParam($query) or die ("ERROR ".mysqli_error($conn));
mysqli_select_db($conn, $dbname);

$query = "CREATE TABLE counter(
  id INT(11) NOT NULL AUTO_INCREMENT,
  action VARCHAR(5),
  source VARCHAR(500),
  comment VARCHAR(500),
  ip VARCHAR(20),
  PRIMARY KEY(id)
)";

$db->executeNoParam($query) or die ("ERROR ".mysqli_error($conn));;
echo "Install complete";
?>

3) Insert Script (feedback.php)

<?php
include('common/db.php');
$configs = parse_ini_file("configs/configs");

$db = new DBConn($configs['path'],$configs['user'],
		   $configs['password'], $configs['database']);

$conn = $db->connect()->getConn();
$query = "INSERT INTO counter (action, source, comment,ip) VALUES (?,?,?,?)";

$us_action = '';
$us_source = $_SERVER['HTTP_REFERER'];
$us_comment = '';

if (isset($_POST['action']))
{
  $us_action = $_POST['action'];
}
if (isset($_POST['comment']))
{
  $us_comment = $_POST['comment'];
}

$action = mysqli_real_escape_string($conn, $us_action);
$comment = mysqli_real_escape_string($conn, $us_comment);
$source = $us_source;

$db->execute($query, array('s','s','s','s'), 
		     array($action, $source, $comment, $_SERVER['REMOTE_ADDR'])
	    );
?>

4) View Script (viewfeedback.php)

<?php
include('common/db.php');
$configs = parse_ini_file("configs/configs");

$db = new DBConn($configs['path'],$configs['user'],
		   $configs['password'], $configs['database']);

$conn = $db->connect()->getConn();
$query = "SELECT action, source, comment FROM counter";

$res = $db->query($query);

if ($res)
{
?>
	<HTML>
	<HEAD>
	<BODY>
		<table>
<?php
   while ($obj = $res->fetch_object())
   {
	echo "<tr><td>".$obj->action."</td><td>".$obj->source."</td><td>".$obj->comment."</td></tr>";
   }
?>		</table>
<?php
}
?>