Okay so I am trying to add a functionality to my website that more or less mimics the way that IMDb has a star-rating for movies. I'm using Ajax to submit a rating to the database when a star is clicked and currently the updating of the database is working BUT I am having a hard problem getting the stars to update to show the new user rating without reloading the page.
Essentially I have the response text to the Ajax call just give me the number rating (1-10) that was submitted once it was done so. I need to find out how to acquire that response text correctly and create an event that automatically updates the stars once that response text is received.
Here is my relevant javascript code:
Code:
/*
star_ratings.js
*/
window.onload = function() {
'use strict';
var entityId = <?php echo $entity_id; ?>;
var username = <?php echo '"' . $current_username .'"'; ?>;
U.addEvent(U.$('rating_star_1', 'click', function() {submitRating(1, "entity", "username")}));
<?php
//if there has already been a rating, create blue stars
if (mysqli_num_rows($already_reviewed_query_result) == 1) {
$review_score = $current_user_review_rows["review_score"];
for ($l = 1; $l <= $review_score; $l++) {echo "document.getElementById('rating_star_" . $l . "').src ='../images/blue_star_17px.png'; "; }
} //end of user review conditional / clause
if ($current_username) { //if logged in
for ($star_submit = 1; $star_submit <= 10; $star_submit++ ) {
//get each rating_star_x and create event for starSubmitFxn on click with given parameters
echo "U.addEvent(U.$('rating_star_" . $star_submit . "'), 'click', function(){ starSubmitFxn('" . $star_submit . "', '" . $current_username . "'); } );";
}
}
?>
U.addEvent(U.$('rating_star_1'), 'mouseover', function(){ newStarRating(1, "yellow_full"); } );
U.addEvent(U.$('rating_star_2'), 'mouseover', function(){ newStarRating(2, "yellow_full"); } );
U.addEvent(U.$('rating_star_3'), 'mouseover', function(){ newStarRating(3, "yellow_full"); } );
U.addEvent(U.$('rating_star_4'), 'mouseover', function(){ newStarRating(4, "yellow_full"); } );
U.addEvent(U.$('rating_star_5'), 'mouseover', function(){ newStarRating(5, "yellow_full"); } );
U.addEvent(U.$('rating_star_6'), 'mouseover', function(){ newStarRating(6, "yellow_full"); } );
U.addEvent(U.$('rating_star_7'), 'mouseover', function(){ newStarRating(7, "yellow_full"); } );
U.addEvent(U.$('rating_star_8'), 'mouseover', function(){ newStarRating(8, "yellow_full"); } );
U.addEvent(U.$('rating_star_9'), 'mouseover', function(){ newStarRating(9, "yellow_full"); } );
U.addEvent(U.$('rating_star_10'), 'mouseover', function(){ newStarRating(10, "yellow_full"); } );
<?php
if (mysqli_num_rows($already_reviewed_query_result) == 1) {
echo "U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(" . $current_user_review_rows['review_score'] .", 'blue'); } );";
}
else {
echo "U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(0, 'yellow_full'); } );";
echo "/* \$already_reviewed_query is:*" . $already_reviewed_query . "*/";
}
mysqli_close($dbc);
?>
}
function newStarRating(starNumber, color) {
'use strict';
var i = null;
for (i = 1; i <= 10; i++) {
document.getElementById('rating_star_' + i).src='../images/white_star_17px.png';
} //end of star color reset
var j = null;
for (j = 1; j <= starNumber; j++) {
document.getElementById('rating_star_' + j).src='../images/' + color + '_star_17px.png';
}
}
function starSubmitFxn(starNumber) {
'use strict';
//Get a reference (get element by ID) to the entered username value:
var ajax = getXMLHttpRequestObject();
if (ajax) {
var currentUsername = '<?php echo $current_username; ?>';
var currentEntityId = '<?php echo $entity_id; ?>';
ajax.onreadystatechange = function() {
if (ajax.readyState === 4){
//Check the status code:
if ( (ajax.status >= 200 && ajax.status < 300) || (ajax.status === 304) ) {
for ( var r = 1; r <= 10; r++){
if (ajax.responseText === 'r') {
newStarRating(r, "blue");//end of newStarRating call
} //end of response text check
} //end of loop
} //end of Ajax connectivity check
else { //if Ajax status text is a failure
document.getElementById('ajax_status').innerHTML = 'Error:' + ajax.statusText;
}
} //end of Ajax ready state
}; //end of function for execution on ready state change
var data = 'currentUsername=' + encodeURIComponent(currentUsername) + '¤tEntityId=' + encodeURIComponent(currentEntityId) + '&starNumber=' + encodeURIComponent(starNumber);
ajax.open('POST', '../resources/star_submit.php?' + data, true);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajax.send(data);
}
else {
document.getElementById('ajax_status').innerHTML = "Error: Ajax object doesn't exist";
}
}
Here is the PHP code for the Ajax response:
PHP Code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
you're currently looking for the letter 'r' whereas I assume the response is a number (1-10). Or, at least, a string which can be converted to a number.
You might do something like the following, rather than looping through 1-10:
Code:
var respond = ajax.responseText;
if (!isNaN(respond)) {
respond = respond * 1; // convert to a number, if required
} else {
// invalid response received
}
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
Apparently my post method is not working. Should the value for currentUsername be in quotes once it's in the data variable (that will be added to the URL and sent)?
When I check it in Chrome though, it says that I have an "unexpected token <". This is always a hard error to correct, especially when NetBeans doesn't find any parsing error.
Once I fixed the unexpected token problem... which by the way I am still not sure how I fixed... I was able to keep debugging to find out how far my JSON (I switched it to JSON from originally being just text because I was running out of ideas).
First problem I think it was being returned as text and failing the !NaN test. Secondly, and perhaps more importantly, I forgot to remove the event that was added earlier that resets the blue stars to whatever rating the entity had from the user when the page was loaded. So now I remove that event and replace it with the next rating (as responded from the server upon success).
Final relevant code looked like this:
Code:
/*
star_ratings.js
*/
window.onload = function () {
'use strict';
var entityId = <?php echo $entity_id; ?>;
var username = <?php echo '"' . $current_username .'"'; ?>;
var ajax = getXMLHttpRequestObject();
<?php
//if there has already been a rating, create blue stars
if (mysqli_num_rows($already_reviewed_query_result) == 1) {
$review_score = $current_user_review_rows["review_score"];
for ($l = 1; $l <= $review_score; $l++) {echo "document.getElementById('rating_star_" . $l . "').src ='../images/blue_star_17px.png'; \n"; }
} //end of user review conditional / clause
if ($current_username) { //if logged in
for ($star_submit = 1; $star_submit <= 10; $star_submit++ ) {
//get each rating_star_x and create event for starSubmitFxn on click with given parameters
echo "U.addEvent(U.$('rating_star_" . $star_submit . "'), 'click', function(){ starSubmitFxn(" . $star_submit . ", '" . $current_username . "'); } ); \n";
}
}
?>
U.addEvent(U.$('rating_star_1'), 'mouseover', function(){ newStarRating(1, "yellow_full"); } );
U.addEvent(U.$('rating_star_2'), 'mouseover', function(){ newStarRating(2, "yellow_full"); } );
U.addEvent(U.$('rating_star_3'), 'mouseover', function(){ newStarRating(3, "yellow_full"); } );
U.addEvent(U.$('rating_star_4'), 'mouseover', function(){ newStarRating(4, "yellow_full"); } );
U.addEvent(U.$('rating_star_5'), 'mouseover', function(){ newStarRating(5, "yellow_full"); } );
U.addEvent(U.$('rating_star_6'), 'mouseover', function(){ newStarRating(6, "yellow_full"); } );
U.addEvent(U.$('rating_star_7'), 'mouseover', function(){ newStarRating(7, "yellow_full"); } );
U.addEvent(U.$('rating_star_8'), 'mouseover', function(){ newStarRating(8, "yellow_full"); } );
U.addEvent(U.$('rating_star_9'), 'mouseover', function(){ newStarRating(9, "yellow_full"); } );
U.addEvent(U.$('rating_star_10'), 'mouseover', function(){ newStarRating(10, "yellow_full"); } );
<?php
if (mysqli_num_rows($already_reviewed_query_result) == 1) {
echo "U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(" . $current_user_review_rows['review_score'] .", 'blue'); } );";
}
else {
echo "U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(0, 'yellow_full'); } );";
echo "/* \$already_reviewed_query is:*" . $already_reviewed_query . "*/";
}
?>
}
function newStarRating(starNumber, color) {
'use strict';
var i = null;
for (i = 1; i <= 10; i++) {
document.getElementById('rating_star_' + i).src='../images/white_star_17px.png';
} //end of star color reset
var j = null;
for (j = 1; j <= starNumber; j++) {
document.getElementById('rating_star_' + j).src='../images/' + color + '_star_17px.png';
}
}
function starSubmitFxn(starNumber) {
'use strict';
var ajax = getXMLHttpRequestObject();
if (ajax) {
var currentUsername = '<?php echo $current_username; ?>';
var currentEntityId = <?php echo $entity_id; ?>;
// Create the Ajax object:
ajax.onreadystatechange = function() {
if (ajax.readyState === 4){
//Check the status code:
if ( (ajax.status >= 200 && ajax.status < 300) || (ajax.status === 304) ) {
//document.getElementById('ajax_status').innerHTML = ajax.responseText;
var starResponse = JSON.parse(ajax.responseText);
var starResponseNumber = parseInt(starResponse["1"].value);
U.removeEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating("<? echo $current_user_review_rows['review_score'] ?> ", 'blue'); } );
U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(starResponseNumber, 'blue'); } );
if (!isNaN(starResponseNumber)) {
//newStarRating(ratingNumber, "blue");//end of newStarRating call
var i = null;
for (i = 1; i <= 10; i++) {
document.getElementById('rating_star_' + i).src='../images/white_star_17px.png';
} //end of star color reset
var j = null;
for (j = 1; j <= starResponseNumber; j++) {
document.getElementById('rating_star_' + j).src='../images/blue_star_17px.png';
}
} //end of response text check
} //end of Ajax connectivity check
else { //if Ajax status text is a failure
}
} //end of Ajax ready state
}; //end of function for execution on ready state change
var data = 'currentUsername=' + encodeURIComponent(currentUsername) + '¤tEntityId=' + encodeURIComponent(currentEntityId) + '&starNumber=' + encodeURIComponent(starNumber);
ajax.open('POST', '../resources/star_submit.php?' + data, true);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajax.send(data);
} //end if ajax object exists
else {
} //end if it doesn't exist
} //end of starSubmitFxn
And PHP:
PHP Code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
you should really look into using json_encode(phpArr) to format your data instead of building vars manually. it's faster, and the native feature are tested and patched, making them way more reliable when silly data works its way in, which is inevitable.
__________________ my site (updated 5/13) STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
Okay so for the record I found out why I get an "unexpected token <", it's from the PHP response when my PHP script has en error. Notice how the response from the server starts with an open braces (or whatever that character is called):
Code:
<div class="error"><p>An error occurred in script '/home/kylhur/danconia.us/resources/find_comments.php' on line 6: mysqli_escape_string() expects exactly 2 parameters, 1 given
<br />Date/Time: 10-11-2012 19:30:58
<br /><pre>Array