1

I'm using a star ratings system to display rating data from SQL. Each item that can be rated has unique identifyer variable $id and each rating in ratings tabl has unique identifyer $storyidr. I would like this script to display:

  1. the average rating
  2. the number of times the item has been rated.

The values are retirevable but they display on the page together and I can't see how to seperate them. FOr example, for an item that has an average rating of 4 and has been rated 200 times. when user clicks the data returns via AJAX looking like:

  • For 'response1' 4"200"
  • For 'response2' 4"200"

I would like to be able to seperate them to look like:

  • For 'response1' 4
  • For 'response2' 200

html page

   <div id="products" style="">
     <div class="rateit" data-storyidr="<?php echo $id; ?>">
     </div>
      <div class="averagevote">
        <div style="display:block;" id="response<?php echo $id; ?>"><?php echo $avgratep; ?></div><br>
         <div style="display:block;" id="response2<?php echo $id; ?>">RaTeD <?php echo $rankcount; ?> TiMeS</div>
        </div>
       </div>
   <?php endwhile; mysqli_close($connection); ?>

   <script type ="text/javascript"> 
      $('#currentslide .rateit').bind('rated reset', function (e) { 
          var ri = $(this); 
          var value = ri.rateit('value'); 
          var storyidr = ri.data('storyidr'); 
          ri.rateit('readonly', true); 
      $.ajax({
      dataType : 'json', 
      url: 'rate.php', 
      data: {storyidr: storyidr, value: value}, 
      type: 'POST', 
      success: function (data) { 
          $('#response'+storyidr).replaceWith('Avg rating ' + data.avg + '/5'); 
          $('#response2'+storyidr).replaceWith('Rated ' + data.cnt + ' times');

      }, 
           error: function (jxhr, msg, err) {
           $('#response').append('<li style="color:red">' + msg + '</li>');
      }
  }); 
   }); 
    </script>

PHP

 <?PHP  
            $storyidr=$_POST['storyidr'];
        $mysqli = mysqli_connect($dbhost,$dbusername,$dbpasswd,$database_name) or die ("Couldn't connect to server.");
         if (mysqli_connect_errno($mysqli))
           {
           echo "Failed to connect to MySQL: " . mysqli_connect_error();
           }
        $sql  = "INSERT INTO ratings (storyidr, rank, entry_date) VALUES ('$_POST[storyidr]','$_POST[value]',now());"; 
        $sql .= "SELECT AVG(rank) AS avrank, COUNT(rank) AS countrank FROM ratings WHERE storyidr = $storyidr";
        if($mysqli->multi_query($sql))
        {   $mysqli->next_result();
        if ($result = $mysqli->store_result())
        { 
        $data = mysqli_fetch_assoc($result);
        $avrank = $data['avrank'];
        $countrank = $data['countrank'];
        $avrankr = round($avrank,2);
        if(is_null($avrank)){$avrank ="null";}
                  echo json_encode(array('avg' => $avrankr, 'cnt' => $countrank));

        }
        }
    ?>
3
  • 1
    $.ajax({dataType : 'json', ... }); Commented Jun 9, 2014 at 20:12
  • You JS file, where you've got part with AJAX call. Just like other options... Commented Jun 9, 2014 at 20:15
  • 1
    @lazel Removing brackets and adding lines of code to question are not appropriate. Commented Jun 11, 2014 at 20:27

2 Answers 2

1

You should only use json_encode() once and only echo the result of that function. Doing it more than once invalidates your json:

    else
    {
       $results = array();
       $results['av'] = $avrankr;
       $results['cnt'] = $countrank;

       echo json_encode($results);
    }

Then, in your javascript, you can access data.av and data.cnt directly:

$('#response'+storyidr).replaceWith('Avg rating ' + data.av +'/5'); 
$('#response2'+storyidr).replaceWith(data.cnt); 

You could also set the dataType parameter in your ajax call as mentioned by @barell, but normally jQuery will figure that out correctly already.

Edit: To avoid the undefined errors you are getting you should do something like:

$results = array('status' => 'fail');
...
if () {
    ...

      if ($result)
      {
        $results['status'] = 'success';
        $results['av'] = $avrankr;
        $results['cnt'] = $countrank;
      }
}

echo json_encode($results);

Now you can check for data.status first in the success callback of your ajax call and take the appropriate action:

success: function (data) {
   if (data.status === 'fail') {
      // show a warning message somewhere, this is just an example
      alert('No results found!');
   } else {
      $('#response'+storyidr).replaceWith('Avg rating ' + data.av + '/5'); 
      $('#response2'+storyidr).replaceWith('RaTeD ' + data.cnt + ' TiMeS'); 
   }
},
Sign up to request clarification or add additional context in comments.

7 Comments

Made suggestions, I'm getting an error: "Avg Rating is undefined" I'll edit code to include changes. I'm thinking it's a jquery error? thank you @jeroen! please offer suggestable fix if possible!
@buzrw It would seem you have entered the if loop in your php script. You should do a console.log(data) in your success function (in javascript) to see what it contains exactly.
I didn't think php would give a 'undefined' error code. I thought that was a jquery error @jeroen
@buzrw It is, but when you enter the if(!$result) part in your php script, you are not setting the correct array variables so they will be undefined in your javascript when you try to access them. You should check for data.status first and to make it complete you should add $results['status'] = 'success'; in the else section so that it is always defined when you get the results back in your ajax call.
you just solved it. Also, I needed this all along: dataType : 'json', Without it data.avg and data.cnt aren't understood. I was going off an aspx based code when writing this and that may explain me not including the 'datatype'. Thank you so much.
|
1

I think the problem is you don't set the correct header. In the php file, before any output, put this:

header('Content-type: text/json');

And also, instead of write two objects, write it as an array:

echo json_encode(array('avg' => $avrankr, 'cnt' => $countrank));

Now it should work

Then, in your Javascript you will access this data like this:

$('#response'+storyidr).replaceWith('Avg rating ' + data.avg +'/5');
$('#response'+storyidr).replaceWith(data.cnt); // Suppose you want the count here

4 Comments

I think this is on the right track but I'm getting a jquery error that says the value for data.avg is undefined
If you are using the updated version of your code, it's data.av, because of this line: $results['av'] = $avrankr;
@ lazel I've posted in my most current code. I can't seem to find the error. I looked at what you said and I'm using .av as suggested. Any help would be amazing and thank you in advance.
I've made a little change in your code, just added the right header before you send out data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.