I am having an issue with my javascript. I am trying to count marks for each correct chosen answer which is determined from db. If incorrect answer then marks is '0', else mark is dependent on answer's mark in db.
But I am having issues with the javascript:
First of all where it says connect.php, this just simply navigates to page where it connects to db, but is this correct or am I suppose to link to page where it will run query looking up answer's marks?
Second it says I have undefined response in my code and I do not what this should be called.
My question is can I have clarification for the above 2. I am trying to use ajax and javascript and will appreciate if a strong programmer can tackle this issue I am having and be able to correctly set up the code so that it is able to count each correct answer marks.
I have a jsfiddle which I am trying to follow but if somebody can edit fiddle to have a dummy version working for counting marks and then be able to provide code snippet stating what the proper code should be, then this will help me very much.
At moment the jsfiddle determines if answers selected are correct or incorrect and fiddle is here: http://jsfiddle.net/bWthd/3/
Actual code:
PHP/HTML:
$qandaquery = "SELECT q.QuestionId, Answer, AnswerMarks, OptionType
FROM Question q
INNER JOIN Answer an ON q.QuestionId = an.QuestionId
INNER JOIN Option_Table o ON q.OptionId = o.OptionId
WHERE SessionId = ?
GROUP BY q.QuestionId
ORDER BY RAND()";
...
$qandaqrystmt->bind_result($qandaQuestionId,$qandaAnswer,$qandaAnswerMarks,$OptionType);
$arrQuestionId = array();
while ($qandaqrystmt->fetch()) {
$arrQuestionId[ $qandaQuestionId ] = $qandaQuestionId;
}
foreach ($arrQuestionId as $key=>$question) {
?>
<div class="queWrap" data-q_id="<?php echo $key; ?>">
$options = explode('-', $arrOptionType[$key]);
if(count($options) > 1) {
$start = array_shift($options);
$end = array_shift($options);
do {
$options[] = $start;
}while(++$start <= $end);
}
else{
$options = explode(' or ', $option);
}
if($arrReplyType[$key] == 'Single'){
foreach($options as $indivOption) {
echo '<div class="ck-button"><label class="fixedLabelCheckbox"><input type="radio"
name="options_<?php echo $key; ?>[]" id="option-' . $indivOption . '" value="' .
$indivOption . '" /><span>' . $indivOption . '</span></label></div>';
}
}else if($arrReplyType[$key] == 'Multiple'){
foreach($options as $indivOption) {
echo '<div class="ck-button"><label class="fixedLabelCheckbox"><input type="checkbox" name="options_<?php echo $key; ?>[]" id="option-' . $indivOption . '" value="' . $indivOption . '" /><span>' . $indivOption . '</span></label></div>';
}
}
<p><input type='text' class='questionIds' name='questionids' value='<?php echo htmlspecialchars($arrQuestionId[$key]); ?>' /></p>
}
JAVASCRIPT/AJAX:
$(function() {
$('.queWrap .ck-button').change(function() {
var $ch_box = $(this),
$qwrap=$ch_box.closest('.queWrap')
q_id = $qwrap.data('q_id'),
val = $ch_box.val();
var dataToServer = {
q_id: q_id,
valueSelected: val
}
$.post('connect.php', dataToServer,function(){
var status=response.status
$qwrap.find('.status').text( status).addClass(status);
if( status=='correct'){
updateScore( response.points)
}
})
})
function updateScore( newScore){
var score= $points.data('score')+newScore;
$points.data('score',score).text( 'Score: '+score)
}
});
UPDATE:
Current code:
function update() {
var score = 0;
$('.queWrap').each(function(element) {
var $qwrap = $(element),
q_id = $qwrap.data('q_id'),
val = $qwrap.find('input:checked').val();
var dataToServer = {
q_id: q_id,
valueSelected: val
}
$.post('connect.php', dataToServer,function(response){
var status = response.status
$qwrap.find('.status').text(status).addClass(status);
if (status == 'correct'){
score += response.points;
$points.data('score', score).text('Score: ' + score);
}
})
});
}
...
//HTML
<div class="status"> </div>
Ok there is no errors but there is no marks appearing and calculating. Is it because of the connect.php I included in the javascript function. Do I need to navigate to page which connects to db connect.php or navigate to a page where it runs a query on finding answer marks for each selected answer? I am running out of time so can you please implement the code for me asap because I have to get this finished. I want the following to happen:
Count marks for each answer selected, if incorrect answer selected then value is 0 for those answers, if correct answer then it's marks are determined from database. Howcan I get each correct answer button to contain it's own answerId?
To determine answerId we can use the questionId displayed in text input (See PHP/HTML code snippet at top) and then depending on values of each answer button, retrieve the answerid matching the answer values for each question.
Below is example database showing Answer Table
AnswerId (auto PK) QuestionId Answer AnswerMarks
1 72 A 2
2 72 C 1
3 73 B 2
4 73 C 2
5 73 E 1
Your updateScore function works wrong. You should store the points for each question in a data element, and in the updateScore() function you should add all these up, and put the sum into the $points element. Something like this:
$(function() {
$('.queWrap .ck-button').change(function() {
update();
});
function update() {
var score = 0;
$('.queWrap').each(function(element) {
var $qwrap = $(element);
var q_id = $qwrap.data('q_id');
var val = $qwrap.find('input:checked').val();
var dataToServer = {
q_id: q_id,
valueSelected: val
};
$.post('connect.php', dataToServer, function(response){
var status = response.status
$qwrap.find('.status').text(status).addClass(status);
if(status == 'correct'){
score += response.points;
$points.data('score', score).text('Score: ' + score);
}
});
});
}
}
And this function should be invoked on every change of the answers. (I am not sure this works just an example).
Related
My site pulls test questions from a database, and some of these questions have images associated with them.
The images pull in fine and everything works as expected, but when trying to pull the answers for these questions, which sometimes also have images, there is a translation issue causing just the reference index to be called and no image displayed (the text still appears that is associated with the answer however).
Question Picture Example
Answer Picture Example - An image should appear in the highlighted area
I can't tell if the issue is caused in the HTML/PHP interpretation of calling an answer or in the function that defines the answer to be called. Code snippets below.
First is the HTML/PHP and JS. All things pertaining to answers are "Rationale" All things pertaining to images are "equations":
<?php
for ($i = 0; $i < $displayCount; $i++) {
$workingDate = date('Y-m-d', time()-($i*24*60*60));
$QID = updateQOTD($ar, $workingDate, $level);
$questionInfo = getQuestion($ar, $QID);
echo $workingDate."<br><br>";
if(isset($questionInfo->VIGNETTE)) {
echo "<strong>Vignette</strong>:<br>";
echo $questionInfo->VIGNETTE;
echo "<br><br>";
}
$equation = getEquation($ar, $QID);
$eq_text = '';
if (isset($equation)) {
$file = $equation->FILE_NAME;
$eq_text = '<img src="/lcms/images/equations/' . $file . '">';
}
echo "<strong>Question</strong>:<br><br>";
$qtext = $questionInfo->TEXT ;
$qtext = preg_replace('/<equation id="\d+"\/>/', $eq_text, $qtext);
echo $qtext;
echo "<br><br>";
?>
<div id='response_<?php echo $i; ?>'></div>
<div class='rationale margin-top-20'><br><strong>Rationale:</strong><br>
<?php echo $questionInfo->RATIONALE; ?>
</div>
<?php
}
?>
<button id="grade" class="btn-theme" type="button">Grade My Choices</button>
<? require_once(getenv("DOCUMENT_ROOT")."/inc/footer.pilot.php"); ?>
<script type="text/javascript">
$(document).ready(function(){
$(".rationale").hide();
$("response_1").hide();
$("response_2").hide();
$("response_3").hide();
$("response_4").hide();
$("response_5").hide();
$("#grade").click(function () {
$(".correctMark").html("<img src='../../images/600px-Green_check.png' />");
$(".incorrectMark").html("<img src='../../images/600px-Red_x.png' />");
$(".rationale").slideDown("fast");
if ($("input[name='question_1']:checked").val() == 'correct') {
$("#response_1").text("Your answer was correct!");
$("#response_1").slideDown("slow");
}
});
});
</script>
And here is the database code call SQL and function defining Rationale:
function getEquation($ar, $QID) {
if (isset($QID) && $QID > 0) {
$selectSql = sprintf("SELECT e.FILE_NAME FROM equation_tbl e, equation_question_link_tbl eq WHERE eq.QUESTION_ID = %s AND e.ID = eq.EQUATION_ID ",
$QID);
$equation = $ar->get_row($selectSql);
return $equation;
}
}
function getQuestion($ar, $QID) {
$selectSql = sprintf("SELECT case_tbl.TEXT as VIGNETTE, question_tbl.TEXT, question_tbl.ANSWER_1, question_tbl.ANSWER_2, question_tbl.ANSWER_3, question_tbl.ANSWER_4, question_tbl.ANSWER_5, question_tbl.ANSWER_6, question_tbl.ANSWER_7, question_tbl.ANSWER_8, question_tbl.RATIONALE FROM question_tbl LEFT JOIN case_tbl ON question_tbl.CASE_ID = case_tbl.ID WHERE question_tbl.ID = %s",
$QID);
$question = $ar->get_row($selectSql);
return $question;
}
function makeAnswerArray($questionInfo) {
$answers[0] = array($questionInfo->ANSWER_1, 'correct');
$answers[1] = array($questionInfo->ANSWER_2, 'incorrect');
$answers[2] = array($questionInfo->ANSWER_3, 'incorrect');
if(isset($questionInfo->ANSWER_4) && $questionInfo->ANSWER_4 > ' ') {
$answers[3] = array($questionInfo->ANSWER_4, 'incorrect');
if(isset($questionInfo->ANSWER_5) && $questionInfo->ANSWER_5 > ' ') {
$answers[4] = array($questionInfo->ANSWER_5, 'incorrect');
if(isset($questionInfo->ANSWER_6) && $questionInfo->ANSWER_6 > ' ') {
$answers[5] = array($questionInfo->ANSWER_6, 'incorrect');
if(isset($questionInfo->ANSWER_7) && $questionInfo->ANSWER_7 > ' ') {
$answers[6] = array($questionInfo->ANSWER_7, 'incorrect');
if(isset($questionInfo->ANSWER_8) && $questionInfo->ANSWER_8 > ' ') {
$answers[7] = array($questionInfo->ANSWER_8, 'incorrect');
}
}
}
}
}
return $answers;
}
Is there any reason why the images associated with Rationales are not pulling through when expected?
I would start by checking the values of $equation with var_dump($equation) and also var_dump($question) to look for any anomalies. I suspect you've got incomplete data creeping in that looks like /lcms/images/equations/NULL or something similar which should be obvious enough, when dumped.
If this is the case, look at extending your handling of these vars to be more strict about the expected value.
Truth be told, it's going to be difficult to help if we cannot run the code. But I would start by checking data integrity of the MySQL result. Bit of a SQL join in there too that only you will know the correct format of, which would be my next port of call.
I have a question:
I'm trying to create a Personal-Message-System on my Website and for this one my Idea was, that the user gets displayed the amount of new messages in each chat...
As in this screenshot
Yes, I am from germany, so the language in the screenshot is german...
You see the red "box" with the number in it? This one I want to create for each chat and I don't know how. With PHP only this would be easy, but I want, that the numbers are right always and refreshes automaticly...
So my HTML-Code is:
<div class="chat_body">
<a href="index.php?section=pn&mode=loadConversation&ConversationID=<?php echo $conversation['id']; ?>">
<div class="user" id='<?php echo $i ?>' data-user-id='<?php echo $user_id?>' data-conv-id='<?php echo $conversation['id'] ?>'>
// Displaying the name, etc... (for clarity i left it out)
<?php
echo "<div class='rightCountUnreadMessages'>";
echo '<div class="badge" id="badge-'.$i.'"></div>';
echo "</div>";
?>
</div>
</a>
</div>
At the top of the page my Javascript, to load the numbers, is:
jQuery(document).ready(function() {
//jQuery(setInterval(function() {
friends_count = document.getElementsByClassName("user").length;
for(var i=1; i < friends_count+1; i++) {
el = document.getElementById(i);
conv_id = el.getAttribute("data-conv-id");
user_id = el.getAttribute("data-user-id");
test = i;
jQuery.post('./Bauteile/Accounts/loadCounts/loadPNCount.php', {user_id_loadPN: user_id, conv_id: conv_id}, function(result){
console.log(result);
console.log(test);
if(result > 99) {
result = "99+";
}
if(result > 0 || result == "99+") {
document.getElementById("badge-"+test).innerHTML = result;
}
})
}
//}, 500));
});
And in the requested document in Javascript has the following content:
<?php
$conv_id = $_POST['conv_id'];
$from_id = $_POST['user_id_loadPN'];
echo (int)mysql_result(mysql_query("SELECT COUNT(*) FROM `messages` WHERE `group_id` = $chat_id AND `from_id` = $from_id AND `read_on` is NULL"), 0);
?>
I know it is difficult to see through all of this, but I hope someone can help me...
I don't know what I do wrong, but the code doesn't work...
I think it is probably because of the for loop but I don't know, how I fix this...
If you have questions please ask...
Thank you in advance
The problem is you have something asynchronous in your loop. To solve this problem you need a closure. You need to wrap the content of the for loop in a function that takes i as a parameter, then call the function in the loop.So try something like this :
function doClosure(i) {
var el = document.getElementById(i),
conv_id = el.getAttribute("data-conv-id"),
user_id = el.getAttribute("data-user-id"),
test = i;
jQuery.post('./Bauteile/Accounts/loadCounts/loadPNCount.php', {user_id_loadPN: user_id, conv_id: conv_id}, function(result){
console.log(result);
console.log(test);
if(result > 99) {
result = "99+";
}
if(result > 0 || result == "99+") {
document.getElementById("badge-"+test).innerHTML = result;
}
});
}
for (var i = 1; i < document.getElementsByClassName("user").length+1; i++) {
doClosure(i);
}
Addition to my post:
I replaced
jQuery.post('./Bauteile/Accounts/loadCounts/loadPNCount.php', {user_id_loadPN: user_id, conv_id: conv_id}, function(result){
with
console.log(user_id + " " + i);
jQuery.post('./Bauteile/Accounts/loadCounts/loadPNCount.php', {user_id_loadPN: user_id, conv_id: conv_id}, function(result){
console.log(result + " " + i);
for debugging...
The console output was:
21 1 line: 254 (= first console.log in this example)
26 2 line: 254
27 3 line: 254
26 4 line: 256 (= sec. console.log in this example)
27 4 line: 256
21 4 line: 256
So, as i suspected the For-loop and the jQuery function doesn't work together very well...
I'm trying to build a simple auto suggest input bar that connects to a MySql database and retrieves data. The issue that I'm running into is that when I type in the name of an object that I know exists in the databse, the text bar doesn't return any results, instead it just provides me with an empty dropdown box.
The best I can tell, the issue has to do with the javascript that is used within the PHP portion of the code. Unfortunately, I can't seem to figure out why it's causing an issue.
<?php
mysql_connect("host", "user", "passsword") OR DIE ('Unable to connect to database! Please try again later.');
mysql_select_db('DBName');
$query = 'SELECT Device_type FROM Device';
$result = mysql_query($query);
$counter = 0;
echo"<script type='text/javascript'>";
echo"this.nameArray = new Array()";
if($result) {
while($row = mysql_fetch_array($result)) {
echo("this.nameArray" .$row ['Device_type'] . "';");
$counter += 1;
}
}
echo("</script>");
?>
When I take out the echo"<script type='text/javascript'>"; and echo"this.nameArray = new Array()"; then It displays the Device_type content on the top of the page when the page is loaded. This obviously isn't what I want, but it does prove that the database connection is at least set up correctly. Since this chunk of PHP is referring to some javascript, I will also prove the function in which it's referring to.
function doSuggestions(text) {
var input = text;
//window.alert(text);
var inputLength = input.toString().length;
var code = "";
var counter = 0;
while(counter < this.nameArray.length) {
var x = this.nameArray[counter]; // avoids retyping this code a bunch of times
if(x.substr(0, inputLength).toLowerCase() == input.toLowerCase()) {
code += "<div id='" + x + "'onmouseover='changeBG(this.id);' onMouseOut='changeBG(this.id);' onclick='doSelection(this.innerHTML)'>" + x + "</div>";
}
counter += 1;
}
if(code == "") {
outClick();
}
document.getElementById('divSuggestions').innerHTML = code;
document.getElementById('divSuggestions').style.overflow='auto';
}
Any suggestions as to why the suggestion box isn't providing suggestions when I start typing? If I type A into the text box, the suggestion box should appear showing me all items in the database that start with A.
there are some errors in your js strings
`echo"var nameArray = new Array()";`
`echo("nameArray.push('" .$row ['Device_type'] . "');");`
that way you'll push device types into the nameArray var.
I am working on a site that generates notation for a random musical rhythm based on some user-selected parameters. It does this by using an ajax call, which returns a random set of <img> elements that represent different notes. I have a function that is designed to scale the rhythm to fit in the screen, regardless of it's actual size.
The function is triggered after a successful ajax call, which is triggered by a click event on a button.
My problem is that the function does not work as desired when running the first time the page is loaded.
After the function runs for the first time, the height attribute of all of the <img> elements is somehow set to 0.
However, the function works great if I run the it again (by clicking the button). It also works fine after a page refresh.
Also, I do not have this issue in IE11, only Chrome (I haven't tested other browsers yet).
I have tried wrapping the code in both $(window).load() and $(document).ready() event handlers, but this didn't help.
The site in action can be found at http://www.rhythmrandomizer.com
Any help would be greatly appreciated!
Below is the relevant code:
Event handler for the button:
$("#randomize").click(function(){
//get general options from form
var timeSignature = $("#timeSignature").val();
var phraseLength = $("#phraseLength").val();
//get note options from form
var checked = [];
$("#noteOptions :checked").each(function() {
checked.push($(this).val());
});
//alert user and exit function if nothing is selected
if (checked.length < 1) {
alert("Please select at least one note value");
return;
}
//format note option ids into a delimited string
var noteOptions = "";
for (var i=0; i < checked.length; i++) {
noteOptions += checked[i] + "a";
}
//remove the final comma and space
noteOptions = noteOptions.substr(0, noteOptions.length - 1);
//ajax call
$.ajax("randomize.php", {
data : {
timeSignature : timeSignature,
phraseLength : phraseLength,
noteOptions : noteOptions
},
type : "GET",
success : function(response) {
$("#rhythm").html(response);
scaleRhythm();
},
error : function(xhr, status, errorThrown) {
console.log(status + " | " + errorThrown);
}
});
});
The php file that returns the rhythm notation:
<?php
//MySQL connection variables
$hostname = 'localhost';
$user = ini_get('mysqli.default_user');
$pw = ini_get('mysqli.default_pw');
$database = 'rhytxfpd_rhythmrandomizer';
//Connect to database
try {
$db = new PDO('mysql:host=' . $hostname . ';dbname=' . $database,$user,$pw);
} catch(PDOException $e) {
echo $e->getMessage();
die();
}
//Get values from GET
$timeSignature = $_GET['timeSignature'];
$phraseLength = $_GET['phraseLength'];
$noteOptString = $_GET['noteOptions'];
//Split up note options string
$noteOptions = explode('a', $noteOptString);
//Create sql query
$sql = 'SELECT
noteName,
noteValue,
noteGraphic
FROM
notes
WHERE';
//append noteOptions as WHERE clauses
foreach ($noteOptions as $opt) {
$sql = $sql . ' noteGroupID = ' . $opt . ' OR';
}
//remove final " OR"
$sql = substr($sql, 0, strlen($sql) - 3);
//query the database and get all results as an array
/* This will return a table with the name, graphic, and value of
* the notes that the user selected prior to submitting the form
*/
$stmt = $db->query($sql);
$result = $stmt->fetchAll();
//Get the total number of options selected
$numOpts = count($result);
/***************************/
/** BEGIN PRINTING RHYTHM **/
/***************************/
//div to begin the first measure
echo '<div class="measure" id="m1' . $measure . '">';
//Print time signature
echo '<img class="note" src="notes/' . $timeSignature . '.png" title="time signature ' .
$timeSignature . '/4" alt="time signature ' . $timeSignature . '/4"/>';
//Prints as many measures as indicated by the phrase length selection
$measure = 1;
while ($measure <= $phraseLength) {
//begin a new div for other measures.
if ($measure != 1) {
echo '<div class="measure" id="m' . $measure . '">';
}
//Prints random measure according to time signature
$beats = 0;
while ($beats < $timeSignature) {
//Generate a random number
$random = rand(0, $numOpts - 1);
//Get the random note from results
$note = $result[$random];
//Continues if chosen note will not fit in the measure
if ($beats + $note['noteValue'] > $timeSignature) {
continue;
}
//Prints random note
echo '<img class="note" src="notes/' . $note['noteGraphic'] . '.png" title="' .
$note['noteName'] . '" alt="' . $note['noteName'] . '"/>';
//Adds random note's value to total number of beats
$beats += $note['noteValue'];
//$beats++;
}
//If last measure
if ($measure == $phraseLength) {
echo '<img class="note" src="notes/1.png" title="double barline" alt="double barline"/>';
echo '</div>';
} else {
echo '<img class="note" src=notes/b.png title="barline" alt="barline"/>';
echo '</div>';
}
//Increment to next measure
$measure++;
}
The scaleRhythm() function:
function scaleRhythm() {
//Get width of rhythm at full resolution
var rhythmWidth = $("#rhythm").width();
//Get current screen/window width
var screenWidth = window.innerWidth;
//Compute ratio between curren screen and window widths
var ratio = screenWidth / rhythmWidth;
//Multiply img note height by ratio, then by 90% to provide some
//breathing room on either side of the rhythm
var newHeight = (400 * ratio) * .9;
//Set img note height to new height or 300px, whichever is smaller
if (newHeight < 300) {
$(".note").css("height",newHeight);
//code to center rhythm horizontally
$("#rhythm").css("margin-top",(300-newHeight)/2);
} else {
$(".note").css("height",300);
$("#rhythm").css("margin-top",0);
}
}
Add this javascript to your <script></script>:
$(function(){ $("#randomize").click(); });
This will cause your page to run the function that populates your random elements then (at the end of that function) run the scale function.
I tested it by running it on your page in the chrome console and it worked.
If you put a breakpoint in the scaleRhythm function you'll notice on page load it's not being run. You've defined the function but it is not being called on page load. In fact none of the code you want run (ie: the ajax call) gets called until the first click happens. So what you need to do is trigger the click event on the button like JRulle said.
$("#randomize").click();
Okay so here is your issue.
The first time you click the button, var rhythmWidth = $("#rhythm").width(); evaluates to "0" because it is empty.
Which causes these subsequent functions to be "0" as well:
var ratio = screenWidth / rhythmWidth;
var newHeight = (400 * ratio) * .9;
I would edit your function to be like so:
var rhythmWidth = $("#rhythm").width();
if (rhythmWidth == 0) { rhythmWidth = 10; } //assign some reasonable value here
since your function does not support a rhythmWidth of "0"
I have a ratings system implemented but can't get it post the correct up to date rating in one of my database tables, it's always behind by one step, i.e. it always stores the last rating just before the current one:
The table 'post_rating' contains a row for every single vote cast on anything, and the table 'posts_rat_main' is where I'm having trouble. I want it to store an overall rating made up of all the individual votes on an item on the site, and keep queries to a minimum, but as said it's always one vote behind the current running total.
Main page
// set up the ratings
$votes = mysql_query("SELECT rat_rating FROM post_rating WHERE rat_ID = $post_ID");
$votesnr = 0;
$totalvotes = 0;
while($vote = mysql_fetch_array($votes)){
$votesnr++;
$totalvotes += $vote['rat_rating'];
}
if($votesnr == 0){
$rating = 0;
}
else {
$rating = $totalvotes/$votesnr;
}
$roundedrating = floor($rating) + round($rating - floor($rating)) / 2 ;
?>
<div>Total Rating</div>
<div class="star-rating" id="rating1result<?php echo $roundedrating; ?> "style="background-position:0 -<?php echo $roundedrating * 32; ?>px;">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
<div class="result">
<span style="color:green"><?php echo round($rating,2); ?></span> (<?php echo $votesnr; ?> votes)
</div>
<script type="text/javascript">
$(function(){
$('.star').mouseover(function (){
var star = $(this).index()+1;
var x =(32 * star);
$(this).parent().css('backgroundPosition... ' +(-x)+ 'px');
});
$('.star-rating').mouseout(function (){
var originalresult = $(this).attr('id').split('result')[1];
var y =(32 * originalresult);
$(this).css('background-position','0%' +(-y)+ 'px');
});
});
$('.star').click(function (){
var id = $(this).parent().attr('id').split('ratin...
var vote = $(this).index() +1;
$.ajax({
type: "POST",
url:"save_vote.php",
data: 'id='+ id + '&vote='+ vote + '&stid=<?php echo $post_ID ?>' + '&totv=<?php echo $totalvotes ?>' + '&votes=<?php echo $votesnr ?>'
});
$(this).parent().removeAttr("id");
$(this).parent().html(" ");
window.location.href = "posts/post_view.php?id=<?php echo $post_ID ?>";
});
</script>`
This all works well with the 'post_rating' table, the handler scrip where I suspect the problem is reads:
$id = intval($_POST['id']);
$vote = intval($_POST['vote']);
$post_ID = intval($_POST['stid']);
$votesnr = $_POST['votes'];
$tot_v = $_POST['totv'];
// set up the ratings
$votesnr = $votesnr;
$totalvotes = $tot_v;
if($votesnr == 0){
$rating = 0;
}
else {
$rating = $totalvotes/$votesnr;
}
$new_rat = round($rating,2);
// Sling in the data
$insert_rat = "INSERT INTO post_rating";
$insert_rat.= " (rat_ID,";
$insert_rat.= " rat_rating,";
$insert_rat.= " rat_user_ID,";
$insert_rat.= " rat_user_name,";
$insert_rat.= " rat_date)";
$insert_rat.= " VALUES";
$insert_rat.= " ('$post_ID',";
$insert_rat.= " '$vote',";
$insert_rat.= " '$member_ID',";
$insert_rat.= " '$member_name',";
$insert_rat.= " NOW())";
$story_update = "UPDATE posts_rat_main";
$story_update.= " SET rating = '$new_rat'";
$story_update.= " WHERE st_ID = '$post_ID'";
mysql_query($insert_rat) or die(mysql_error());
mysql_query($story_update) or die(mysql_error());
So whenever I update the table 'posts_rat_main' it updates it with the figure one vote behind the current vote!? I've got half of this from a tutorial and messed about it with to no avail. I'm lousy with javascript and just can't figure it out but suspect the problem lays in my 'save_vote' handler script which seems very simple.
My latest attempt was to nick the script commented '// set up the ratings', from the 'main page' and paste it into the save_vote handler script as shown here, but to no avail. I'm fairly stumped, any ideas?
Also as a secondary note I've found this script to be a little unresponsive at times, requiring sometimes 2 or 3 clicks on the stars before it will register the vote, and I can't imagine why that is?
Any help much appreciated, cheers.
The easy answer is that you have to add $vote to $totalvotes and +1 to votesnr:
$rating = ($totalvotes + $vote) / ($votesnr + 1);
This will also allow you to remove the if/else, since the denominator will at least be 1.
The longer answer
If there is an index for rat_id, rat_rating on post_rating, then it is probably a better idea to just do a group by sql select query when you want the results. Unless you really have a problem, a preo-ptimization such as this is not worth the time or trouble.
If you must have a separate table to store the results, then at least use a trigger on post_rating to compute the result instead of doing in it in php.