1

I've created a simple [voting form] using jQuery AJAX and JSON. I want to know how to create a Cookie so that the user will not be able to vote more than once. Following is my code.

I am new to Cookies and jQuery. Please tell me how to complete my task.

JavaScript

<script>
$(document).ready(function(){

    $("#poll").click(function(){
        var count = '';
        if (document.getElementById("vote1").checked) {
            count = 0;
        }
        if (document.getElementById("vote2").checked) {
            count = 1;
        }
        var jsonV= { "vote": count };

        $.ajax({
          type  : "POST",
          url   : "poll_vote.php",
          data  : jsonV,
          dataType: "json",
              success : function ( responseText ){
                console.log("Is working " + responseText);
                 $("#result").html( responseText.vote );
              },
              complete : function(){
                  $("#poll").slideUp();
              },
              error : function( error,responseText ){
                // alert("Server not Responding. Sorry for the inconvenience caused. Please Try again Later");
                console.log( error );
                $("#result").html( error + responseText );
                alert( count );
              }
        });
    });
});
</script>

PHP

<?php

$vote = $_REQUEST['vote'];
$filename = "poll_result.txt";
$content = file($filename);
// $decode = json_decode($encode);
$array = explode("||", $content[0]);
$male = $array[0];
$female = $array[1];

if ($vote == '0') {
  $male = $male + 1;
}
if ($vote == '1') {
  $female = $female + 1;
}

$insertvote = $male."||".$female;
$fp = fopen($filename,"w");
fputs($fp,$insertvote);
fclose($fp);

$table =  (
    "<h2>Results:</h2>
        <table>
        <tr>
            <td> Male :</td>
            <td>
            <img src='poll.gif'
            width= ".(100*round($male/($female+$male),2)).
            "height='20'>".
            (100*round($male/($female+$male),2))." %"  .
            "
             </td>
         </tr>
         <tr>
             <td> Female :</td>
             <td>
             <img src='poll.gif'
             width=". (100*round($female/($female+$male),2)) .
            "
             height='20'>".
             (100*round($female/($female+$male),2))." %" ."

             </td>
         </tr>
     </table>"
 );
$list  = array('vote' => $table);
$encode = json_encode($list);
echo $encode;
?>

HTML

<div id= "poll">
    <h3> What is your Gender? </h3>
    <form>
        Male : 
        <input type ="radio" name ="vote"  id="vote1" >
        <br>
        Female :
        <input type ="radio" name ="vote"  id="vote2" >
    </form>
</div>
SaidbakR
  • 11,955
  • 16
  • 89
  • 173
Akila Randil
  • 195
  • 9
  • Refer http://stackoverflow.com/questions/1458724/how-to-set-unset-cookie-with-jquery link, This has good detail of handling cookies – Manish Shukla Apr 18 '15 at 12:08
  • Note that cookies are stored on client side, is quitely easy deleting them or open browser in incognito mode to vote again.. – DrKey Apr 18 '15 at 14:08
  • There is a jquery plugin called [**cookie**](https://plugins.jquery.com/cookie/) will help you so much. – SaidbakR Apr 18 '15 at 15:38

3 Answers3

1

You would want to set a cookie when the user votes, and check for that cookie in PHP when a vote is submitted. If the cookie is already set, the vote should be discarded.

For example, using just PHP, it could look something like this:

if (!isset($_COOKIE['has_voted'])) {
    // normal vote submission code goes here
    // ...
    // then we set a cookie to expire in 30 days
    setcookie('has_voted', '1', mktime().time()+60*60*24*30);
} else {
    // cookie already exists, user has already voted on this machine
    // do not count the vote, flag an error to the user
}

It is worth noting that there are ways round this - the user could easily delete the cookie manually. In this case, you could also store the IP addresses of users who have already voted, but this can open up problems on shared machines and multiple machines behind a network.

enigma
  • 3,434
  • 2
  • 15
  • 30
0

Since it seems you're using PHP, you'll be able to implement a cookie to prevent multiple votes within your already existing script.

The syntax for setting a cookie in PHP is as follows:

setcookie("cookiename", "cookiedata", cookietime, "cookielocation");

Where "cookiename" is the name of the cookie, for example, "voted", "cookiedata" is the data stored in the cookie– "yes", for example. "cookielocation" is the location where the cookie is stored in the user's browser cache. Unless you know what you're doing, just set this to "/".

Cookietime is how long the cookie will sit in the users system until the browser automatically deletes it. Note that this doesn't prevent the user from deleting the cookie. For simplicity, I usually set the time as follows:

time()+60*60*24*days

Where days is how long the cookie will sit in the user's system (in days, of course).

To retrieve the value of a cookie so you're able to perform logic on it, try using:

if(isset($_COOKIE['cookiename'])) {
   $valueOfCookie = $_COOKIE['cookiename'];
}

Make sure to use the if(isset()) to make sure the cookie has been set, before trying to retrieve the value.

Using these functions, your logic may look something like this when the user submits the form:

  1. Check if the voting cookie is set
  2. If it is, print an error message, else:
  3. Continue to process the form data, and set the vote cookie

However, on a side note, if you're concerned about users potentially deleting their cookies so they can vote again, I might suggest that, rather than using cookies, you store users' IP addresses on the server-side, and deny them voting access if their IP address has already voted.

SnazzyJava
  • 87
  • 12
0

You could do this with sessionStorage, using only JS:

<script>
$(document).ready(function(){
    $("#poll").click(function(){
        var count = '';
        if (document.getElementById("vote1").checked) {
            count = 0;
        }
        if (document.getElementById("vote2").checked) {
            count = 1;
        }

        var jsonV= { "vote": count };

        if ( sessionStorage.getItem( 'voted' ) == 'true' ) {
            alert('You have already voted!');
        }else if ( sessionStorage.getItem( 'voted' ) == null ){
            $.ajax({
              type  : "POST",
              url   : "poll_vote.php",
              data  : jsonV,
              dataType: "json",
                  success : function ( responseText ){
                    console.log("It's working" + responseText);
                     $("#result").html( responseText.vote );
                  },
                  complete : function(){
                      $("#poll").slideUp();
                      sessionStorage.setItem('voted', 'true');
                  },
                  error : function( error,responseText ){
                    // alert("Server not Responding. Sorry for the inconvenience caused. Please Try again Later");
                    console.log( error );
                    $("#result").html( error + responseText );
                    alert( count );
                  }
            });
        }
    });
});
</script>
  • What I have done here is added a session storage item in the complete callback of your ajax call, so once it has completed the item 'voted' will be set.
  • I have then wrapped the ajax call in an if condition which checks the value of the storage item and if it is set then will not allow you to vote (and instead bring up an alert)

Note that you can also you localStorage if you want the item to last longer as sessionStorage is cleared when the browser window is closed while localStorge will last until the user clears their cookies / browsing data.


And here is a little snippet you can use to clear the storage for testing purposes:

$('#clear').click(function(){
    console.log(sessionStorage.getItem( 'voted' ));
    sessionStorage.removeItem('voted');
    console.log(sessionStorage.getItem( 'voted' ));
});

You will need the accompanying HTML with that:

<p id="clear">clear</p>
Michael Doye
  • 7,070
  • 4
  • 35
  • 51