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.
Related
I have PHP loop. I take the id, lat, lon data from record, passed it to script to do some calculations, then I passed this data to AJAX which will save the results of that calculation in MySQL DB, if it's successful then it will add the line of confirmation text to a results div.
My Code (I did trim it to keep focus on the issue)
<div id="distance_results"></div>
<?php
$result = $mysqli->query("SELECT * FROM test")
while($row = $result->fetch_array()) {
$id = $row['id'];
$city = $row['city'];
$lat = $row['lat'];
$lon = $row['lon'];
$driving_from = "51.528308,-0.3817765";
$driving_to = "$lat,$lon";
?>
<script>
var id = '<?php echo $id ?>';
var city = '<?php echo $city ?>';
var start = '<?php echo $driving_from ?>';
var end = '<?php echo $driving_to ?>';
// code
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
// code
var mi = response.routes[0].legs[0].distance.value;
console.log(id);
console.log(city);
console.log(mi);
//Ajax Begin
$.ajax({
type: 'post',
url: 'test-dc-upd.php',
data: {'updateid': id, 'distance': mi},
success: function() {
html="Distance between London and " + city + " is " + mi;
$("#distance_results").append("<p>"+html+"</p>");
}
});
//Ajax End
} else {}
});
</script>
<?php } ?>
AND CODE FOR "test-dc-upd.php"
$id = $_POST['updateid'];
$distance = $_POST['distance'];
$result = $mysqli->query("UPDATE test SET distance='$distance' WHERE id='$id' LIMIT 1");
So PHP is looping thru MySQL DB, when but when I look at console:
'mi' values are calculated well according to lat / lon;
PROBLEMS:
1) 'id' and 'city' values stay the same (values of last record in the loop);
2) AJAX is updating value of last record in the loop only
So it obvious there is a some issue with the loop.
Any suggestion to what i do wrong?
Change this
$("<p>"+ html +"</p>").append("#distance_results");
To
$("#distance_results").append("<p>"+ html +"</p>");
Your jquery code is wrong. First you have to put selector and in append function the html code.
Nita, change the success function from:
success: function() {
html="Distance between CITYX and " + city + " is " + mi;
$("<p>"+ html +"</p>").append("#distance_results");
}
});
To
success: function() {
html="Distance between CITYX and " + city + " is " + mi;
$("#distance_results").append(<p>"+ html +"</p>);
// this will append the dynamic content to #distance_results
}
});
Explanation:
To put a dynamic content is some html object you have to first prepare
the content than select the html object and put the content into it.
In a loop calling ajax request is not a good practice we can easily pass array of values to javascript using the function implode like this
this implode function is for single dimensional array,
var ar = <?php echo '["' . implode('", "', $ar) . '"]' ?>;
For your question you need to create a multi dimensional array for the result like this ..
<?php
$result = $mysqli->query("SELECT * FROM test");
$arr= array();
while($row = $result->fetch_array()) {
$arr[]=array('id'=>$row['id'],'city'=>$row['city],'lat'=>$row['lat']...etc);
}
?>
afetr that you can pass each item in the array to javascript like this
var idArray= <?php echo '["' . implode(', ', array_column($arr, 'id')); . '"]' ?>;
var cityArray= <?php echo '["' . implode(', ', array_column($arr, 'city')); . '"]' ?>;
you can get each tag as array in javascript after that using a sing ajax request pass all javascript array to php script. and manipulate in the server side .
Your ajax request is like this
$.ajax({
type: 'post',
url: 'test-dc-upd.php',
data: {
'idArray':idArray,
'cityArray':cityArray, //etc you need pass all array like this
},
success: function(data) {
// your success code goes here
}
});
Note that array_column() function only supported by php 5.3 or above
I manage to do it a little different way i was hoping for ( But distance and travel time has been calculate for more then 3000 locations).
So what i did is to make sure mysql (test-dc.php) finds record where distance and travel time has not been calculated, makes calculation, update record with Ajax. Ajax on succesion opens the (test-dc.php) again, And is looping thru all results till there is nothing else to calculate. Had to refesh few times but thats fine, job done.
Adjustment to Mysql query:
$result = $mysqli->query("SELECT * FROM test WHERE distance='' LIMIT 1")
and to AJAX:
success: function() {
html="Distance between London and " + city + " is " + mi;
$("#distance_results").append("<p>"+html+"</p>");
location.href = "test-dc.php"
}
So that did the trick, but i still belive there is a better way of achiving the same result, i will be happy if someone could help me to figure it out.
I have searched the web and mostly using jquery and some library to do so. I wonder how we can do it using pure javascript to make an Infinite Page Scroll Effect like twitter does without having to include any library(here i put the search php and html code for reference, and i wanna realize the effects in the search results. I use laravel as a backend). And i am just starting to learn javascript , please treat me as a 10 year old boy. Thanks
//HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Risky Jobs - Search</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div class="searchWrapper">
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method='get' >
<input type="search" name="search">
</form>
</div>
<h3>Risky Jobs - Search Results</h3>
</body>
</html>
// PHP
function build_query($user_search, $sort){
$search_query = "SELECT * FROM posts";
$clean_search = str_replace(',',' ',$user_search);
$search_words = explode(' ', $clean_search);
//to become a array
$final_search_words = array();
if(count($search_words) > 0){
foreach($search_words as word){
if(!empty($word)){// there are circustances that the user input two or more blank so it will result to a blank result
$final_search_words[] = $word;
}
}
}
// Generate a WHERE clause using all of the search keywords
$where_list = array();
if(count($final_search_words) > 0){
foreach($final_search_words as $word){
$where_list[] = "content Like '%$word%'";
}
}
$where_clause = implode(' OR ', $where_list);
//Add the keyword WHERE clause to the search query
if(!empty($where_clause)){
$search_query .= " WHERE $where_clause";
}
// Sort the search query using the sort setting
switch ($sort) {
// Ascending by title
case 1:
$search_query .= " ORDER BY title";
break;
// Desending by title
case 2:
$search_query .= " ORDER BY title DESC";
break;
// Ascending by created_at
case 3:
$search_query .= " ORDER BY created_at";
break;
// Descending by created_at
case 4:
$search_query .= " ORDER BY created_at DESC";
break;
default:
// No sort setting provided, so don't sort the query
//break;
}
return $search_query;
} //END OF build_query() FUNCTION
// This function builds heading links based on the specified sort setting
function generate_sort_links($user_search, $sort){
$sort_links = '';
switch ($sort) {
case 1:
$sort_links .= '<li>Title</td><td>Description</li>';
$sort_links .= '<li>created_Time</td><td>Description</li>';
break;
case 3:
$sort_links .= '<li>created_Time</td><td>Description</li>';
$sort_links .= '<li>Title</td><td>Description</li>';
break;
default:
$sort_links .= '<li>created_Time</td><td>Description</li>';
}
return $sort_links;
}//end of generate_sort_links
// This function builds navigational page links based on the current page and the number of pages
function generate_page_links($user_search, $sort, $cur_page, $num_pages) {
$page_links = '';
// If this page is not the first page, generate the "previous" link
if($cur_page >1){
$page_links .= '<- ';
}else{
$page_links .= '<- ';
}
// Loop through the pages generating the page number links
//loop through all the pages
for($i = 1; $i <= $num_pages; $i++){
if($cur_page == $i){
$page_links .= ' ' . $i;
//if current page, get rid of the url
}else{
$page_links .= ' ' . $i . '';
//if not current page, add the url to make it point to next page or previous page
}
}
//// If this page is not the last page, generate the "next" link
if($cur_page < $num_pages){
$page_links .= ' ->';
//if not last page, make -> have a url and can point to the previous one
}else{
$page_links .= ' ->';
}
return $page_links;
}//end of generate_page_links function
// Grab the sort setting and search keywords from the URL using GET
$sort = $_GET['sort'];
$user_search = $_GET['usersearch'];
//// Calculate pagination information
$cur_page = isset($_GET['page']) ? $_GET['page'] : 1;
$result_per_page = 5;// number of results per page
$skip = (($cur_page -1) * $results_per_page);
// Start generating the search results
echo '<div class="filter">';
echo generate_sort_links($user_search, $sort);
echo '</div>';
// Connect to the database
require_once('dbinfo.php');
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// Query to get the total results
$query = build_query($user_search, $sort);
$result = mysqli_query($dbc, $query);
$total = mysqli_num_rows($result);
$num_pages = ceil($total / $results_per_page);
// // Query again to get just the subset of results
$query = $query . " LIMIT $skip, $results_per_page";
//limit 10,5 means skip the 10 and return 5
//$skip = (($cur_page -1) * $results_per_page);
$result = mysqli_query($dbc, $query);
while ($row = mysqli_fetch_array($result)) {
echo '<div class="search_item">';
echo '<div>' . $row['title'] . '</div>';
echo '<div>' . $row['created_at'] . '</div>';
echo '<div>' . substr($row['content'], 0,300) . '</div>';
echo '</div>';//end of search_item wrap
}
// Generate navigational page links if we have more than one page
if($num_pages >1 ){
echo generate_page_links($user_search, $sort, $cur_page, $num_pages);
}
mysqli_close($dbc);
Here you can find an easy way to do an infinite scroll:
JS:
var callback = function test() {
// Log how the height increases to the console
console.log(document.getElementById('infinite').style.height)
// equivalent to $('#infinite') in jQuery
var el = document.getElementById('infinite');
var newHeight = document.getElementById('infinite').offsetHeight + 200;
// Update the height property of the selected element
el.style.height = newHeight + 'px';
}
window.addEventListener('scroll', callback, false);
Basically adding an event listener attached to the scroll, so, every time we scroll, that function is triggered and increase the height property of the element.
You will just need a div as:
<div id='infinite' style='height: 2000px'></div>
Here's a fiddle
Hope it helps :)
What you need to do is an Ajax call on scroll, which appends the products. This question has been asked before and answered over here: On Scroll down how to make ajax call and get the respone data
The code executes an ajax call when a user reaches at end of page. By keeping track of the amount of products, you could send the offset and limit with the ajax call so you could use that within your database query.
EDIT:
Look what I just found: http://www.smarttutorials.net/infinite-scroll-using-jquery-ajax-php-and-mysql/ If this doesn't help...
EDIT 2:
No wordpress so code removed
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"
This question already has answers here:
How to select the nth row in a SQL database table?
(33 answers)
Closed 9 years ago.
I am trying to load content as the user scrolls from my database. I am trying to load 10 items at a time in order. currently I have achieved everything I want to do except I am loading the first 10 items every time. I don't really know how to keep track of what items were loaded last. If I made a variable it would reset anyways everytime the script is called.
What do I need to change in order for it to load the next 10 items instead of the first 10?
php:
<?php
// database connection info
$conn = mysql_connect('localhost','root','') or trigger_error("SQL", E_USER_ERROR);
$db = mysql_select_db('test',$conn) or trigger_error("SQL", E_USER_ERROR);
//offset
$offset=0;
// number of rows to show per page
$rowsperpage = 10;
// get the info from the db
$sql = "SELECT ID, confession, image FROM test LIMIT $offset, $rowsperpage";
$result = mysql_query($sql, $conn) or trigger_error("SQL", E_USER_ERROR);
// while there are rows to be fetched...
while ($list = mysql_fetch_assoc($result)) {
echo '<table border="0" width="600px">';
echo "<tr>";
echo "<td><p>" . '<img src="' . $list['image'] . '" hspace="10" border="1" style="float:left;">' . "</p>";
echo "<p>" . "#" . $list['ID'] . ": " . $list['confession'] . "</p></td>";
echo "</tr>";
echo "</table>";
echo "<br>";
//next ten rows
$offset+=10;
}
?>
javascript:
//load content as page scrolls
function yHandler() {
var content = document.getElementById('content');
var contentHeight = content.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
if (y >= contentHeight) {
// Ajax call to get more dynamic data goes here
content.innerHTML += '<div class="newData"></div>';
document.onload = $.post('test5.php', function (data) {
$('.newData').html(data);
});
}
}
window.onscroll = yHandler;
You need to set some counter to this, for example:
<input type="hidden" value ='counter_value'>
And when you send request, you have to send it with counter value, and in php file dependce on counter value select next 10 items from db. After thet using java script increase counter value by ++. And when you will send again request the value will be +1, and in php make logic to select next items
For example, when you reached the bottom of the page, you want to download next items.
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
///here you have to send ajax to php file to get items
var counter= $('#idOfInputwithCouner').attr('value');
$.ajax({
url: 'youPhpFile.php',
data: "counter=" + counter,
type: 'POST',
processData: false,
contentType: false,
success: function (data) {
alert('data'); //here you will get data from php file
$('#idOfInputwithCouner').attr('value',counter +1); //increase input value
}
})
}
});
you may use pagination logic here, send pageNumber with each call and retrieve data accordingly,
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).