I have this query below:
SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, GROUP_CONCAT(DISTINCT Answer ORDER BY Answer SEPARATOR '') AS Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId
AND an.SessionId = q.SessionId
WHERE s.SessionName = "GHWSW1" AND q.QuestionId = 1
GROUP BY an.SessionId, an.QuestionId
ORDER BY q.QuestionId, an.Answer
The query above outputs this result below:
SessionId SessionName QuestionId QuestionContent Answer QuestionMarks
1 GHWSW1 1 Here are 2 answers BD 5
So I included the query in the code below and set up a html table:
$assessment = "GHWSW1";
$number = 1;
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent,
GROUP_CONCAT(DISTINCT Answer ORDER BY Answer SEPARATOR '') AS Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ? AND q.QuestionId = ?
GROUP BY an.SessionId, an.QuestionId
ORDER BY q.QuestionId, an.Answer
";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("si", $assessment, $number);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}
?>
</head>
<body>
<form id="QandA" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<?php
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
foreach ($searchQuestionContent as $key=>$question) {
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">'.htmlspecialchars($searchAnswer[$key]).'</td>' ;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo "</table>" . PHP_EOL;
?>
So the HTML table displays it like this:
QuestionId QuestionContent Answer QuestionMarks
1 Here are 2 answers BD 5
But I want it like this in the html table:
QuestionId QuestionContent Answer QuestionMarks
1 Here are 2 answers B 5
D
The second Answer D should be in a seperate row and the other rows should have a rowspan. But how can this be achieved?
Session Table:
SessionId (auto) SessionName
1 AAA
Question Table:
SessionId QuestionId (auto) QuestionContent
1 1 What is 2+2?
Answer Table:
AnswerId (auto) SessionId QuestionId Answer
1 1 1 B
2 1 1 D
try this
foreach ($searchQuestionContent as $key=>$question) {
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">'.htmlspecialchars($searchAnswer[$key]).'</td>' ;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
echo '</tr>';
}
you forget to close the tr tag
Remove the GROUP BY clause and add make the foreach loop look like this:
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;
Related
I cant get my pdo prepared statement code to pull the records! Only if I write it in MySQLi code.
filter_month.php with both codes below.
filter_month.php--------PDO-Conversion---Prevent SQL Injection Not working!
<?php
{
include 'db_connection2.php';
$query = " SELECT
g.name as `group`,
COUNT(ar.present) as attended
FROM
attendance_record ar
INNER JOIN
_person p
ON ar.personid = p.id
INNER JOIN
_person_group g
ON ar.groupid = g.id
-- WHERE
AND
year(date) = ? AND month(date) = ?
AND
ar.present = 1
GROUP BY g.name
ORDER BY ar.date, g.name ASC
";
$stmt = $pdo->prepare($query);
$stmt->execute([$_POST["year"]],[$_POST["month"]]);
$stmt->fetchAll(PDO::FETCH_ASSOC);
//-----------------------------Table------------------------------------//
$output .= '
<table class="table table-bordered">
<tr>
<th style="text-align:center;" width=".001%"><font size=2><span>Class</span></th>
<th style="text-align:center;" width=".001%"><font size=2><span>Attended</span></th>
</tr>
';
foreach($stmt as $row)
{
$output .= '
<tr>
<td style="text-align:center;">' . $row['group'] . '</td>
<td style="text-align:center;">' . $row['attended'] . '</td>
</tr>
';
}
$output .= '</table>'; }
$pdo=null;
// By this way you can close connection in PDO.
?>
filter_month.php -----mysqli-----This code works!
<?php
{
include 'db_connection.php';
$query = " SELECT
g.name as `group`,
COUNT(ar.present) as attended
FROM
attendance_record ar
INNER JOIN
_person p
ON ar.personid = p.id
INNER JOIN
_person_group g
ON ar.groupid = g.id
-- WHERE
AND
YEAR(date) = '".$_POST["year"]."'
AND
Month(date) = '".$_POST["month"]."'
AND
ar.present = 1
GROUP BY g.name
ORDER BY ar.date, g.name ASC
";
$result = mysqli_query($conn, $query);
$conn->close();
//-----------------------------Table------------------------------------//
$output .= '
<table class="table table-bordered">
<tr>
<th style="text-align:center;" width=".001%"><font size=2><span>Class</span></th>
<th style="text-align:center;" width=".02%"><font size=2><span>Attended</span></th>
</tr>
';
while($row = mysqli_fetch_array($result))
{
$output .= '
<tr>
<td style="text-align:center;">' . $row['group'] . '</td>
<td style="text-align:center;">' . $row['attended'] . '</td>
</tr>
';
}
$output .= '</table>';
echo $output;
}
?>
I have tried many different ways to write the code but, cant get to pull records. Just now learning about pdo.
Also trying to add an image of the client side reportmonthpage.php but cant figure out how to post image.
Here is just my filter_year.php, not year and month, and it works. If I remove the brackets as you have suggested it wont pull records any longer.
<?php
{
include 'db_connection2.php';
$query = "SELECT
g.name as `group`,
COUNT(ar.present) as attended
FROM
attendance_record ar
INNER JOIN
_person p
ON ar.personid = p.id
INNER JOIN
_person_group g
ON ar.groupid = g.id
-- WHERE
AND
YEAR(date) = ?
AND
ar.present = 1
";
$stmt = $pdo->prepare($query);
$stmt->execute([$_POST["year"]]);
$result = $query;
$output .= '
<table class="table table-bordered">
<tr>
<th style="text-align:center;" width=".001%"><font size=2><span>Total Year Attendance</span></th>
</tr>
';
foreach($stmt as $row)
{
$output .= '
<tr>
<td style="text-align:center;">' . $row['attended'] . '</td>
</tr>
';
}
$output .= '</table>';
}
$pdo=null;
// By this way you can close connection in PDO.
?>
You want an array in the execute function and you've misplace brackets in such a way that you do not have an array.
[$_POST["year"]],[$_POST["month"]] should be [$_POST["year"],$_POST["month"]] to create the array. You have too many brackets.
Here is what I came up with that works! I'm sure it must be wrong, but it works!
<?php
{
include 'db_connection2.php';
$query = " SELECT
g.name as `group`,
COUNT(ar.present) as attended
FROM
attendance_record ar
INNER JOIN
_person p
ON ar.personid = p.id
INNER JOIN
_person_group g
ON ar.groupid = g.id
-- WHERE
AND
month(date) = ? AND year(date) = ?
AND
ar.present = 1
GROUP BY g.name
ORDER BY ar.date, g.name ASC
";
$stmt = $pdo->prepare($query);
$stmt->execute([$_POST["month"],$_POST["year"]] );
$result = $query;
//-----------------------------Table------------------------------------//
$output .= '
<table class="table table-bordered">
<div align="center"><font size=4>
Total present (by Class)-------PDO------ Not Working Code</font>
</div>
<tr>
<th style="text-align:center;" width=".001%"><font size=2><span>Class</span></th>
<th style="text-align:center;" width=".001%"><font size=2><span>Attended</span></th>
</tr>
';
foreach($stmt as $row)
{
$output .= '
<tr>
<td style="text-align:center;">' . $row['group'] . '</td>
<td style="text-align:center;">' . $row['attended'] . '</td>
</tr>
';
}
$output .= '</table>'; }
$pdo=null;
// By this way you can close connection in PDO.
?>
Thank you all for your time!
Im using a while loop to go through a DB and pull out some questions and answers. That mostly works apart from the facts the the question order isnt correct.
My question is how do I get the questions to print correctly
Eg :
Q1
Q2
A to Q1
Q3
A to Q2
Blank
A to Q3
Heres an image of what I mean:
Here is the code im using minus the query because I know it works. I think its the if statement thats wrong.
$result = mysqli_query($conn, "SELECT
q.QText, q.id AS QId, ua.id, a.AText, ca.id, ca.Answer_ID,
case when a.id = ua.Answer_ID then 'x' else NULL end as IsUserAnswer ,
case when a.id = ca.Answer_ID then 'x' else NULL end as IsCorrectAnswer
FROM user_answers ua
INNER JOIN question q ON q.id = ua.Question_ID
INNER JOIN answer a ON a.Question_ID = q.id
INNER JOIN correct_answer ca ON ca.Question_ID = q.id
WHERE ua.Test_ID=1
ORDER BY q.ID") or die(mysqli_error($conn));
$lastQuestionID = 0;
while ($data2 = mysqli_fetch_array($result))
{
if ($data2['QId'] != $lastQuestionID)
echo '<p>Q. ' . $data2['QText'] . '</p>
<table class="striped centered">
<thead>
<tr>
<th>Answer</th>
<th>Your Answer</th>
<th>Correct Answer</th>
</tr>
</thead>';
$lastQuestionID = $data2['QId'];
echo '
<tr>
<td>' . $data2['AText'] . '</td>
<td>' . $data2['IsUserAnswer'] . '</td>
<td>' . $data2['IsCorrectAnswer'] . '</td>
</tr>';
}
echo "</table>";
Your table closing is defined incorrectly. Do this instead:
$result = mysqli_query($conn, "Query") or die(mysqli_error($conn));
$lastQuestionID = 0;
$isTableOpen = false;
while ($data2 = mysqli_fetch_array($result)) {
if ($data2['QId'] != $lastQuestionID) {
if ($isTableOpen) {
echo '</table>';
}
$isTableOpen = true;
echo '<p>Q. ' . $data2['QText'] . '</p>
<table class="striped centered">
<thead>
<tr>
<th>Answer</th>
<th>Your Answer</th>
<th>Correct Answer</th>
</tr>
</thead>';
}
echo '
<tr>
<td>' . $data2['AText'] . '</td>
<td>' . $data2['IsUserAnswer'] . '</td>
<td>' . $data2['IsCorrectAnswer'] . '</td>
</tr>';
$lastQuestionID = $data2['QId'];
}
if ($isTableOpen) { // Close last open table
echo '</table>';
}
I have 2 small questions I need help on which deals with the code below:
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;
Question 1: If you look at the table above, I have a a column where it will contain text inputs. Now each text input will belong to each answer in the "Answer" column. My question is that is the text input set up correctly with me including a [] in the name attribute to set up an array? Should I include [] and is there anything else I should include in the text input code?
Question 2: At the moment the code above makes the table look like this example in JSFIDDLE1. But I want the table to be displayed as this example JSFIDDLE2. As you can see the blank rows in the other table have been rowspan so that it looks like the question and the total marks looks like its in one cell. How can I get the table above to look like JSFIDDLE2?
UPDATE:
Below is the full code, I am still receiving undefined index whenver $rowspans[.... is used. Is the code below correct:
$assessment = $_SESSION['id'] . $sessionConcat;
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, an.Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ?
ORDER BY q.QuestionId, an.Answer
";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s", $assessment);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}
?>
</head>
<body>
<form id="QandA" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<?php
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
$rowspans = array_count_values($searchQuestionId);
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($rowspans[$searchQuestionId[$key]]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>'; echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;
?>
<p><input id="submitBtn" name="submitMarks" type="submit" value="Submit Marks" /></p>
</form>
Q1. Yes, you could even specify a name between the [].
Q2. It seems that $searchQuestionId is filled before your loop, right? In that case you could use array_count_values to store the frequency of each ID and access that array during the loop:
before your loop: $rowspans = array_count_values($searchQuestionId);
access rowspan value during loop with: $rowspans[$searchQuestionId[$key]].
You'll have to remove the line $searchQuestionId[$key] = ''; or else you won't be able to access the correct $rowspan key.
Finally, you'll have to set up some more if statements to skip the <td>s on certain rows.
$previous_question_id = null;
$rowspans = array_count_values($searchQuestionId);
foreach ($searchQuestionContent as $key=>$question) {
// removed logic, not necessary to set empty strings if you're skipping them
echo '<tr class="questiontd">'.PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
echo '<td class="optiontypetd" rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($question).'</td>' . PHP_EOL;
}
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
echo '<td class="noofmarkstd" rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
// moved this to the end
if ($previous_question_id != $searchQuestionId[$key]) {
$previous_question_id = $searchQuestionId[$key];
}
}
I want to calculate difference between the "Total Marks" in a question, and the text inputs for each answer in a question. Also if a question has only one answer, then it should display the text input as a readonly and display the same value as the number under the "Total Mark" for that question in that text input.
Below is a screenshot which shows the table and the written problem I have with both scenarios:
Below is the current jquery variable which should be doing the calculation and display the readonly textbox when necessary. But at the moment it is not working. Also at the moment I have display the number for total marks to be fixed as "5" when doing the calculations, well this is incorrect as that it should be the number for within each row, so I believe the variable $sessionMarks that should be the number, not 5.
$(function(){
var questions = $('#markstbl td[class*="_ans"]').length-1;
//disable single entry
for (var i=0;i<=questions;i++){
if($("[class*=q"+i+"_mark]").length ==1){
$("[class*=q"+i+"_mark]").attr("disabled","disabled")
}
}
//find each question set and add listeners
for (var i=0;i<=questions;i++){
$('input[class*="q'+i+'"]').keyup(function(){
var cl = $(this).attr('class').split(" ")[1]
var questionno = cl.substring(cl.indexOf('q')+1,cl.indexOf('_'))
var t=0;
$("[class*=q"+questionno+"_mark]").each(function(){
var num = (isNaN(parseInt($(this).val())))?0:parseInt($(this).val());
t+=parseInt(num);
})
var fixedno = 5;
$(".q"+questionno+"_ans").text((t>fixedno)?fixedno:t);
})
}
})
Below is the code for the table, from the query it outputs the details of each question from the database and then it displays it in a table:
<?php
$assessment = $_SESSION['id'] . $sessionConcat;
include('connect.php');
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, an.Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ?
ORDER BY q.QuestionId, an.Answer
";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s", $assessment);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}
?>
....
<tbody>
<tr>
<?php
$previous_question_id = null;
$rowspans = array_count_values($searchQuestionId);
$output = "";
$questionid = 0; //whole question
$questionno = 0; //part of question
foreach ($searchQuestionContent as $key => $question) {
if ($previous_question_id != $searchQuestionId[$key]){
$questionno=0;
}
// removed logic, not necessary to set empty strings if you're skipping them
$output.= '<tr class="questiontd">' . PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
$output.= '<td class="questionnumtd" name="numQuestion" rowspan="' . $rowspans[$searchQuestionId[$key]] . '">' . htmlspecialchars($searchQuestionId[$key]) . '</td>' . PHP_EOL;
$output.= '<td class="questioncontenttd q{$questionno++}_mark{$questionid}" rowspan="' . $rowspans[$searchQuestionId[$key]] . '">' . htmlspecialchars($question) . '</td>' . PHP_EOL;
}
$output.= '<td class="answertd" name="answers[]">';
$output.= $searchAnswer[$key];
$output.= '</td>';
$output.= '<td class="answermarkstd"><input class="individualMarks" q_group="1" name="answerMarks[]" id="individualtext" type="text" /></td>' . PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
$output.= '<td class="noofmarkstd q{$questionid++}_ans" q_group="1" rowspan="' . $rowspans[$searchQuestionId[$key]] . '">' . htmlspecialchars($searchMarks[$key]) . '</td>' . PHP_EOL;
}
// moved this to the end
if ($previous_question_id != $searchQuestionId[$key]) {
$previous_question_id = $searchQuestionId[$key];
}
}
echo $output;
?>
</tr>
</tbody>
Update:
In the sample HTML which is in this fiddle, I can get it to work (except I want the calculation to be total marks minus number entered in text input, not what it is doing now which is when I enter a number in text input it performs an addition from 0 to whatever number entered in text input), but when I tried to edit the code above to do the same thing, then it doesn't work, nothing happens.
The sample html is below:
<form id="Marks" action="/u0867587/Mobile_app/individualmarks.php" method="post">
<table border='1' id='markstbl'>
<thead>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>
</thead>
<tbody>
<tr class="questiontd">
<td class="questionnumtd" name="numQuestion" rowspan="3">1</td>
<td class="questioncontenttd" rowspan="3">Name three features in a ROM</td>
<td class="answertd" name="answers[]">A</td>
<td class="answermarkstd">
<input class="individualMarks q0_mark_0" q_group="1" name="answerMarks[]" id="individualtext" type="text" />
</td>
<td class="noofmarkstd q0_ans" q_group="1" rowspan="3">5</td>
</tr>
<tr class="questiontd">
<td class="answertd" name="answers[]">B</td>
<td class="answermarkstd">
<input class="individualMarks q0_mark_1" q_group="1" name="answerMarks[]" id="individualtext" type="text" />
</td>
</tr>
<tr class="questiontd">
<td class="answertd" name="answers[]">D</td>
<td class="answermarkstd">
<input class="individualMarks q0_mark_2" q_group="1" name="answerMarks[]" id="individualtext" type="text" />
</td>
</tr>
<tr class="questiontd">
<td class="questionnumtd" name="numQuestion" rowspan="1">2</td>
<td class="questioncontenttd" rowspan="1">Here is a single answer</td>
<td class="answertd" name="answers[]">True</td>
<td class="answermarkstd">
<input class="individualMarks q1_mark_0" q_group="1" name="answerMarks[]" id="individualtext" type="text" />
</td>
<td class="noofmarkstd q1_ans" q_group="1" rowspan="1">5</td>
</tr>
</tbody>
</table>
</form>
Below is what the database tables looks like, (this will follow the same data as the ones in the screenshot)
Session Table: (Where the exam details is stored)
SessionId SessionName
1 AAA
Question Table: (Where questions for each exams are stored)
SessionId QuestionId QuestionContent Total Marks
1 1 Name three features in a ROM 5
1 2 Here is a single answer 5
Answer Table: (Stores answers for each question in each exam)
AnswerId(auto) SessionId QuestionId Answer
1 1 1 A
2 1 1 B
3 1 1 D
4 1 2 True
Individual_Answer Table: (Stores each individual mark for each individual answer)
AnswerId AnswerMarks
1 2
2 2
3 1
4 5
It is not good practice to get and put values from html elements using html() which somehow belong to calculation or integers values, Therefore always use hidden fields for this type of problems, like I have included two hidden fields one for original value and one for the final value and at the end you can get the total marks values easily from the hidden field.
The code is updated for dynamic data. Use your own code for queries, mine is a rough code.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(function() {
var questions = $('#markstbl td[class*="_ans"]').length;
//disable single entry
for (var i=1;i<=questions;i++){
if($("[class*=q"+i+"_marks]").length ==1){
var t_marks = $("[class*=q"+i+"_ans]").html();
alert(t_marks);
$("[class*=q"+i+"_marks]").val(t_marks).attr("disabled","disabled");
//$("[class*=q"+i+"_mark]").attr("disabled","disabled");
}
}
//find each question set and add listeners
for (var i=0;i<=questions;i++){
$('input[class*="q'+i+'"]').keyup(function(){
var cl = $(this).attr('class').split(" ")[1]
var questionno = cl.substring(cl.indexOf('q')+1,cl.indexOf('_'));
var tot_marks = $(".q"+questionno+"_ans_org").val();
var ans_t=0;
$("[class*=q"+questionno+"_marks]").each(function(){
var num = (isNaN(parseInt($(this).val())))?0:parseInt($(this).val());
ans_t+=parseInt(num);
});
ans_t=tot_marks-ans_t;
var ans = (parseInt(ans_t)<0)?tot_marks:ans_t;
$(".q"+questionno+"_ans").val(ans);
$(".q"+questionno+"_ans_text").html(ans);
});
}
});
</script>
</head>
<body>
<form id="Marks" action="/u0867587/Mobile_app/individualmarks.php" method="post">
<?php
$ident = mysqli_connect('localhost','root','');
mysqli_select_db($ident,'testdata');
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, an.Answer, q.QuestionMarks
FROM session s
INNER JOIN question q ON s.SessionId = q.SessionId
JOIN answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
ORDER BY q.QuestionId, an.Answer
";
$res = mysqli_query($ident,$query);
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
while ($row = mysqli_fetch_array($res)) {
$searchQuestionId[] = $row['QuestionId'];
$searchQuestionContent[] = $row['QuestionContent'];
$searchAnswer[] = $row['Answer'];
$searchMarks[] = $row['QuestionMarks'];
}
?>
<form id="Marks" action="/u0867587/Mobile_app/individualmarks.php" method="post">
<table border='1' id='markstbl'>
<thead>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>
</thead>
<tbody>
<?php
$row_span = array_count_values($searchQuestionId);
$output = '';
$rowCount = 1;
$newQuest_id = true;
foreach($searchQuestionId as $key=>$questionId){
if($newQuest_id == true){
$output.= '<tr class="questiontd">';
$output.= '<td class="questionnumtd" name="numQuestion" rowspan="'.$row_span[$questionId].'">'.$questionId.' <input type="hidden" name="q'.$questionId.'_ans_org" class="q'.$questionId.'_ans_org" value="'.$searchMarks[$key].'"><input type="hidden" name="q'.$questionId.'_ans" class="q'.$questionId.'_ans" value="'.$searchMarks[$key].'"></td>';
$output.= '<td class="questioncontenttd" rowspan="'.$row_span[$questionId].'">'.$searchQuestionContent[$key].' </td>';
}
$output.= '<td class="answertd" name="answers[]">'.$searchAnswer[$key].'</td>';
$output.= '<td class="answermarkstd">';
$output.= '<input class="individualMarks q'.$questionId.'_marks" q_group="1" name="answerMarks[]" id="individualtext" type="text" />';
$output.= '</td>';
if($newQuest_id == true){
$output.= '<td class="noofmarkstd q'.$questionId.'_ans_text" q_group="1" rowspan="'.$row_span[$questionId].'">'.$searchMarks[$key].'</td>';
$newQuest_id = false;
}
$output.= '</tr>';
if($row_span[$questionId] == $rowCount){
$newQuest_id = true;
}
$rowCount++;
}
echo $output;
?>
</tbody>
</table>
</form>
</form>
</body>
</html>
I don't know how to explain this but what I want to do is kind of merge two database field together and output the new field using php. For example:
Answer Table:
AnswerId: 10
AnswerContent: Manchester
AnswerId :11
AnswerContent: Leeds
AnswerId:12
AnswerContent:Birmingham
StudentAnswer Table:
Student: Bob
StudentAnswer:10
Student: Jim
StudentAnswer:11
What I want to do is that when I run the query which I will show below with my php coding, for the StudentAnswer field I want it to display the name of the answer rather than the answer id. How can this be achieved?
Below is the code:
<?php
if (isset($_POST['submit'])) {
$query = "
SELECT * FROM Question q
INNER JOIN StudentAnswer sa ON q.QuestionId = sa.QuestionId
JOIN Answer a ON sa.QuestionId = a.QuestionId
WHERE
('".mysql_real_escape_string($sessionid)."' = '' OR q.SessionId = '".mysql_real_escape_string($sessionid)."')
AND
('".mysql_real_escape_string($questionno)."' = '' OR q.QuestionNo = '".mysql_real_escape_string($questionno)."')
AND
('".mysql_real_escape_string($studentid)."' = '' OR sa.StudentId = '".mysql_real_escape_string($studentid)."')
AND(CorrectAnswer = '1')
ORDER BY $orderfield ASC";
$num = mysql_num_rows($result = mysql_query($query));
mysql_close();
?>
<p>
Your Search:
<strong>Session ID:</strong> <?php echo (empty($sessionid)) ? "'All Sessions'" : "'$sessionid'"; ?>,
<strong>Question Number:</strong> <?php echo (empty($questionno)) ? "'All Questions'" : "'$questionno'"; ?>,
<strong>Student Username:</strong> <?php echo (empty($studentid)) ? "'All Students'" : "'$studentid'"; ?>,
<strong>Order Results By:</strong> '<?php echo $ordername; ?>'
</p>
<p>Number of Records Shown in Result of the Search: <strong><?php echo $num ?></strong></p>
<table border='1'>
<tr>
<th>Session ID</th>
<th>Question Number</th>
<th>Question</th>
<th>Correct Answer</th>
<th>StudentAnswer</th>
<th>Correct Answer Weight</th>
<th>Student Answer Weight</th>
<th>Student ID</th>
</tr>
<?php
while ($row = mysql_fetch_array($result)) {
echo "
<tr>
<td>{$row['SessionId']}</td>
<td>{$row['QuestionNo']}</td>
<td>{$row['QuestionContent']}</td>
<td>{$row['AnswerContent']}</td>
<td>{$row['StudentAnswer']}</td>
<td>{$row['Weight%']}</td>
<td></td>
<td>{$row['StudentId']}</td>
</tr>";
}
?>
</table>
<?php
}
?>
Thank You
I think you could use:
SELECT q.*, a.AnswerContent FROM Question q
INNER JOIN StudentAnswer sa ON q.QuestionId = sa.QuestionId
INNER JOIN Answer a ON sa.QuestionId = a.QuestionId
WHERE ....
I mean, you should return the text for the answer (you're still joining tables, so you do have that field).