I have developed a small evaluation in a simple way that has 4 response options to the question and a timer of time allowed to solve the questions.
There are no problems in the code, on the contrary, I like the simple way in which it fulfills what was intended.
Through the TestPage.php file we obtain the questions registered in the data table.
<?php
session_start();
$conn = mysqli_connect("localhost","root","","1_examen") or die("Connection failed".mysqli_connect_error());
date_default_timezone_set("Asia/Kolkata");
$imageview = 0;
$val = $_GET["val"];
if(isset($_COOKIE["clock"]))
$clock = $_COOKIE["clock"];
else
$clock = 300;
$sql = "SELECT * FROM Question WHERE Id=".$val;
$result = $conn->query($sql);
$row = mysqli_fetch_assoc($result);
$question = $row["Question"];
$a1 = $row["A1"];
$a2 = $row["A2"];
$a3 = $row["A3"];
$a4 = $row["A4"];
$image = $row["Image"];
$answer = $row["Answer"];
if($image != null)
$imageview = 1;
if(isset($_POST["submit"]))
{
$temp = $val - 1;
$ans = $_POST["q"];
$_SESSION["answer"][$temp]=$ans;
if($ans == $answer)
{
$_SESSION["result"][$temp] = 1;
}
else
{
$_SESSION["result"][$temp] = 0;
}
if($val == 10)
header('Location:Result.php');
else
header('Location:TestPage.php?val='.($val+1));
}
?>
<html>
<head>
<title></title>
<script>
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function () {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
var temp = timer-1;
document.cookie = "clock="+temp;
if (--timer < 0) {
alert("Times Up");
location.href="Result.php";
}
}, 1000);
}
</script>
<script>
window.onload = function () {
var fiveMinutes = <?php echo $clock; ?>,
display = document.querySelector('#time');
startTimer(fiveMinutes, display);
};
function select(){
var radios = document.getElementsByName("q");
var formValid = false;
var i = 0;
while (!formValid && i < radios.length) {
if (radios[i].checked) formValid = true;
i++;
}
if (!formValid) alert("Please Select Your Answer !!!");
return formValid;
}
</script>
<fieldset id = "timer">
<h4>Time Left : <span id="time"></span></h4>
</fieldset>
<center>
<fieldset id="field">
<h3>ONLINE ENTRANCE TEST</h3>
<hr>
<form action="" method="POST" name="form" onsubmit="return select()">
<?php echo "<h4 id='h41'>Q".$val." ".$question."</h4>"; ?>
<hr>
<?php
if($imageview == 1)
{
echo "<img style='width:100px;height:100px;' src='data:image/jpeg;base64,".base64_encode($image)."'/>";
echo "<hr>";
}
?>
<ul class="answers">
<table>
<tr><td>A)</td><td><input type="radio" name="q" id="q" value="<?php echo $a1;?>" id="q1a"><?php echo $a1;?></td></tr>
<tr><td>B)</td><td><input type="radio" name="q" id="q" value="<?php echo $a2;?>" id="q1b"><?php echo $a2;?></td></tr>
<tr><td>C)</td><td><input type="radio" name="q" id="q" value="<?php echo $a3;?>" id="q1c"><?php echo $a3;?></td></tr>
<tr><td>D)</td><td><input type="radio" name="q" id="q" value="<?php echo $a4;?>" id="q1d"><?php echo $a4;?></td></tr>
</table>
</ul>
<hr>
<input type="submit" name="submit" value="Next ->" id="submitbutton">
</form>
</fieldset>
</center>
The evaluation is carried out through the MainPage.php file , the questions appear through MainPage.php?val=1
Question 1: val=1
, question 2: val=2
, question 3: val=3
and so on.
<?php
session_start();
$conn = mysqli_connect("localhost","root","","1_examen") or die("Connection failed".mysqli_connect_error());
date_default_timezone_set("Asia/Kolkata");
setcookie("clock", "", time() - 3600);
if(isset($_POST["submit"]))
{
$name = $_POST["name"];
$_SESSION["name"] = $name;
$_SESSION["result"] = array(0,0,0,0,0,0,0,0,0,0);
$_SESSION["answers"]=array("","","","","","","","","","");
header('Location:TestPage.php?val=1');
}
?>
<html>
<head>
<title></title>
<script>
function select(){
var x = document.forms["form"]["name"].value;
if (x == "") {
alert("Please Enter Your Name");
return false;
}
}
</script>
</head>
<body>
<center>
<fieldset id="field">
<h3>ONLINE ENTRANCE TEST</h3>
<hr><br>
<form action="" method="POST" name="form" onsubmit="return select()">
Please Enter Name: <input type="text" id="name" name="name" autofocus><br><br>
<hr><br>
<input type="submit" name="submit" value="Begin Test" id="submitbutton">
</form>
</fieldset>
</center>
</body>
</html>
Using the following PHP
Result.php file , the score and errors for incorrect answers are displayed, the selected question and the correct answer are displayed.
<?php
session_start();
$conn = mysqli_connect("localhost","root","admin","Examination") or die("Connection failed".mysqli_connect_error());
date_default_timezone_set("Asia/Kolkata");
$score = 0;
$results = $_SESSION["result"];
$name = $_SESSION["name"];
$answers = array();
setcookie("clock", "", time() - 3600);
for($i=0;$i<sizeof($results);$i++)
{
if($results[$i] == 1)
$score++;
}
$t=0;
$sql = "SELECT * FROM question";
$result = $conn->query($sql);
while($row = mysqli_fetch_assoc($result)){
$answers[$t] = $row["Answer"];
$t++;
}
if(isset($_POST["submit"])){
$sql = "INSERT INTO user(Name,Score) values('$name',$score)";
$conn->query($sql);
header('Location:MainPage.php');
}
?>
<html>
<head>
<title></title>
</head>
<body>
<center>
<fieldset id="field">
<h3>ONLINE ENTRANCE TEST</h3>
<hr>
<form action="" method="POST" name="form">
<h4>Congrats <?php echo $name;?> , Your Score : <?php echo $score;?>/10. !!!</h4>
<hr><br>
<div style="overflow-x:auto;">
<table border="1px" id="table">
<tr><th>Question</th><th>Your Answer</th><th>Correct Answer</th><th>Points Scored</th></tr>
<?php
for($i=0;$i<10;$i++)
{
$temp = $i+1;
if($results[$i] == 0)
echo "<tr style='background-color: #FADBD8 ;'>";
else
echo "<tr style='background-color: #D5F5E3 ;'>";
echo "<td>".$temp."</td><td>".$_SESSION["answer"][$i]."</td><td>".$answers[$i]."</td><td>".$results[$i]."</td></tr>";
}
?>
</table>
</div>
<hr><br>
<input type="submit" name="submit" value="Back To Main Page" id="submitbutton">
</form>
</fieldset>
</center>
</body>
</html>
The structure of the table is as follows:
CREATE TABLE `question` (
`id` int(11) NOT NULL,
`question` varchar(150) NOT NULL,
`a1` varchar(100) NOT NULL,
`a2` varchar(100) NOT NULL,
`a3` varchar(100) NOT NULL,
`a4` varchar(100) NOT NULL,
`image` longblob,
`answer` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What I want to achieve in this small code is to give the possibility that the user can go back or see or select a specific question by saying if I do not want to start from the beginning to the end, if not from the end to the beginning, give that possibility to This must generate the buttons for the existing questions but everything is dynamic, that is, without having to reload the page.
What I want to achieve is the following:
I would handle everything in the front, using an array of questions, for each of which you draw a box with the question number and a container with the text of the answers and their respective set of options. The latter is invisible.
As you go forward or backward, the box is styled and the question changes, the option container for that question becomes visible.
I set the counter to one minute so you can see what happens at the end. Actually, what should happen is that when you submit the responses, or when the timer runs out, you send the entire form to the backend.
Bonus track
Para traerte los datos desde PHP a un frontend como el que te mostré, te traes todas las preguntas de la tabla y las vas metiendo en un array. A diferencia de lo que hice yo, tú además le asignas un atributo
name
a cada pregunta que te permite inferir el ID de la fila.Al final de ese bucle, si tus preguntas fueran como las que puse en el ejemplo, el array tendría la forma:
Eso lo ejecutas antes de empezar a imprimir el HTML, de la forma
Si te fijas, cuando escribes tu HTML (esto no es bonito pero funciona) declaras la variable
preguntas como
Y con eso llenaste el array de preguntas en el frontend, con lo que ya puedes pintar tu prueba de alternativas.
Ahora bien, yo le puse un atributo
name
a cada grupo de opciones usando el índice de la pregunta en el array. Tú debieras usar el atributoname
que estás enviando desde el backend (porque no sabemos si tus ID son estrictamente correlativos o puede que hayas borrado una fila)Entonces, donde yo puse:
Tú en vez de usar
name="respuesta_${index}"
le asignarías a las opciones el atributoname
de la pregunta:Ahora, para enviar el formulario, hay que hacer otro cambio. Yo envolví las preguntas en un div:
Tú podrías reemplazar eso con un
form
Luego, si presionas el botón de enviar, se envía el formulario:
Lo mismo cuando se acaba el tiempo:
Ahora lo que te faltaría sería hacer un script
evaluar.php
que recibe las respuestas. Éstas vendrían en la forma:Pero esto es ineficiente porque tendrías que escribir 100 veces casi lo mismo. Entonces, como tú ya sabes cuántas preguntas enviaste, puedes ejecutar la misma consulta del inicio, pero ahora haciendo:
En el fondo, tú enviaste los nombres que iban a tener cada grupo de opciones. Entonces lees ese mismo valor en la superglobal
$_POST
. Para sumar 1 al puntaje debe cumplirse que la pregunta haya sido respondida (isset($_POST[$name])
) y que la respuesta calce con la columnaanswer
de tu tabla.Al final de esa iteración ya conoces el puntaje final y puedes imprimirlo en pantalla con bombos y platillos.
Edit: faltaba algo fundamental
En el primer ejemplo (snippet) cada vez que se seleccionaba una respuesta se marcaba en verde el recuadro, pero no se llenaba el atributo
respuesta
de la respectiva pregunta. En el fondo, donde decía:Should say: