Stuckfornow
Stuckfornow

Reputation: 290

How to pass php array to ajax function

So I would like to pass the php array values from this form id to my ajax form. Everything works fine except that it will only display the (1) id number. Here is my form code: I am passing the $row[topic_id'] as a value to get the id for jquery.

public function forumview($query){
    $stmt = $this->db->prepare($query);
    $stmt->execute();
    $results = $stmt->fetchAll();

    if($stmt->rowCount()>0){
        foreach($results as $row){

            echo '<tr>';
            echo '<td style="color: #333;"><span class="pull-right">';

    //Problem is here with the $row['topic_id'] portion
    if(isset($_SESSION['user_session'])){
            echo '<a href="#" class="upVoteArrow" 
                   onclick="upVoteIncrementValue('.$row['topic_id'].');">';
        }else{                  
            echo '<a href="#" id="loginForm" class="upVoteArrow" data- 
                  toggle="modal" data-target="#loginModal"><i class="fa fa-arrow-up"></i> 
                  </a>';                
        }
         echo '<span id="voteCount">'.$this->cleanNumber($row['topic_likes']).'</span>';
      }

Here is my Ajax call to send the info to my php file

function upVoteIncrementValue(postID){
   event.preventDefault();
    //var upVoteIncrement   = $("#upVoteIncrement").val();  //not needed

$.ajax({
        type: "POST",
        url: "voting.php",
        data:  {
            "upVoteIncrement": postID,
            },
        dataType: "json",
        cache: false,
        success: function(response){
            if(response){
                var response = $.trim(response);
                if(response){
                    $('#voteCount').html(response);
                }
                else {
                    return false;
                }
            }
        }
    });

Then here is the php file that handles the call.

if(isset($_POST['upVoteIncrement'])){

$upVoteIncrement = $_POST['upVoteIncrement'];

$stmt = $conn->prepare('UPDATE topics SET topic_likes = topic_likes+1 WHERE topic_id = :id LIMIT 1');
$stmt->bindParam(':id', $upVoteIncrement);
$stmt->execute();


$upVote = $conn->prepare('SELECT topic_likes FROM topics WHERE topic_id = :id LIMIT 1');
$upVote->bindParam(':id', $upVoteIncrement);
$upVote->execute();
$upVoteCount = $upVote->fetchAll();

if($upVote->rowCount() > 0){
    foreach($upVoteCount as $row){

        $up = $row['topic_likes'];
        $results[] = $up;
        //exit();  //not needed
    }
}
echo json_encode($results);
}

Essentially I am just making a simple up vote system that the user clicks on and it updates the database incrementing by 1. It increments the values and everything works except it will only increment it for the last posted item. So even if I upvote on a topic from earlier it will only add 1 vote to the last inserted topic. Any advice is much appreciated, thanks in advance!

Upvotes: 0

Views: 159

Answers (2)

Joseph_J
Joseph_J

Reputation: 3669

If your using a loop to populate the row id, which it looks like you are here are your problems.

The loop is creating a hidden input element on every iteration of the loop and you are not changing the id of the element. So you will have a bunch of elements all with the same id. That will cause you problems a few different ways.

I changed your PHP code so that each element will have it's own id. I also changed the your javascript function so that the id value is passed to the function itself.

See if this helps:

PHP:

if(isset($_SESSION['user_session'])){

  echo '<input type="hidden" id="' . $row['topic_id'] . '" name="upVoteIncrement" 
  value="' . $row['topic_id'] . '"><a href="#" class="upVoteArrow" 
  onclick="upVoteIncrementValue(' . $row['topic_id']  . ');">';

}

JS:

function upVoteIncrementValue(postID){
   event.preventDefault();
    //var upVoteIncrement = $("#upVoteIncrement").val(); //Don't need this anymore.

$.ajax({
        type: "POST",
        url: "voting.php",
        data:  {
            "upVoteIncrement": postID, //Use the passed value id value in the function.
            },
        dataType: "html",
        cache: false,
        success: function(response){
            if(response){
                var response = $.trim(response);
                if(response){
                    $('#voteCount').html(response);
                }
                else {
                    return false;
                }
            }
        }
    });

Hope it helps!

I also want to point out that in the code below:

if($upVote->rowCount() > 0){
    foreach($upVoteCount as $row){

        $up = $row['topic_likes'];
        echo $up;
        exit();
    }
}

You are exiting the script on the first iteration of the loop and you will only ever get one result back.

If you need to return an array of data it should look like this:

if($upVote->rowCount() > 0){
    foreach($upVoteCount as $row){

        $up = $row['topic_likes'];
        $results[] =  $up;
        //exit(); 
    }
}

echo json_encode($results);

You will then need to set your datatype to json instead of html.

The response in your ajax will now be an array. To see the array:

success: function(response){
            if(response){
                console.log(response); //Look in your console to see your data.
                var response = $.trim(response);
                if(response){
                    $('#voteCount').html(response);
                }
                else {
                    return false;
                }
            }
        }

Upvotes: 2

2oppin
2oppin

Reputation: 1991

The problem is that in the event handler you addressing element by id, and it's not always the same that you click on.

function upVoteIncrementValue(){
   event.preventDefault();
// Always will be last inserted element
var upVoteIncrement = $("#upVoteIncrement").val();

You can use event to get valid element. It's default argument that passed to handler, but remember to define it without braces:

 <input onclick="upVoteIncrementValue" />

Then your handler:

function upVoteIncrementValue(event){
   event.preventDefault();
var upVoteIncrement = $(event.target).val();

Also if you have several elements with the same ID it's invalid HTML, at least it will hit warning at https://validator.w3.org/ . So you should set id arg for your element only in case if it's unique, and having this mindset will help you to not hit similar issue again.

Upvotes: 1

Related Questions