I am building a simple quiz app in Codeigniter where the user is presented an image and they are to guess if it's right or wrong. Similar to 'hot or not'.
There are 25 questions, all either Yes or No answers. I could take the easy option of creating 25 pages and carry over previous results in hidden fields but this seems a bit longwinded and silly.
I have a view file where the only thing that changes is the image. So I'm thinking I can pass in the image path as a variable and change it dynamically but I cannot work out at a more abstract level how to record the result of each answer and then at the end show the results and insert into a database.
The problem I'm having is how to load the next image in the sequence and record that result.
P.s
The images will always be in the same order. It doesn't really matter if they are random, although that would be nice!
You could accomplish that, by inserting the questions on your database, with the following fields:
ID - the id of the question.
Image - the name of the image for this question for example "question1Image.jpg"
Correct Answer - the correct answer for this question, if the answers are all YES/NO you can use an INT. 1 for YES and 0 for NO.
Now that you have your questions on your database, on your controller e may create something like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Quizz extends CI_Controller {
public function questions($idquestion){
$this->load->model('questions_model');
//fetch the questions from the database
$questions = $this->questions_model->get_questions();
//if it's a post we'll check if the answer is correct and pass the next question to the view
if($this->input->post()){
$answered_question = $this->questions_model->get_question($idquestion-1);
$question = $this->questions_model->get_question($idquestion);
if($answered_question['correct_answer']==$this->input->post('answer')){
//if the user answered correctly do something here
}
$data['question'] = $question;
//the id of the next question you'll use it for the next post
$data['next_question'] = $idquestion+1;
$this->load->view('your_view', $data);
}
//it's the first time the user uses this so we'll load the first answer
else{
$question = $this->questions_model->get_question(1);
$data['question'] = $question;
//the id of the next question you'll use it for the next post
$data['next_question'] = 2;
$this->load->view('your_view', $data);
}
}
}
On your view you can have something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Question page</title>
</head>
<body>
<?php //we'll use the codeigniter form helper to generate manually the form
echo form_open('quizz/questions/'.$next_question); ?>
<!-- This will load the image dynamically-->
<img src="<?=base_url('public/images/'.$question['image'])?>">
<label><input type="radio" name="answer" value="1">YES</label>
<label><input type="radio" name="answer" value="0">NO</label>
<button type="submit" >Submit</button>
<?=form_close();?>
</body>
</html>
The model:
<?php
class questions_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function get_questions()
{
return $this->db->get('questions_table')->result_array();
}
public function get_question($idquestion)
{
$this->db->select('questions_table.*');
$this->db->from('questions_table');
$this->db->where('questions_table.id', $idquestion);
return $this->db->get()->result_array();
}
}
in my opinion you got two options , with Ajax or without Ajax.
easy one first, without ajax :
best way to pass data from each question to other one is by using session variable to sort it.
for example you sort the answer in an array called $answers something like this :
$answers = $this->session->userdata('answers');
$answers[] = ** NEW ANSWER HERE **
$this->session->set_userdata('answers', $answers);
in order to get images you can sort all questions ( images ) in an array in your controller/model and check how many items your $answers in your session contains to determine which image is to be shown next ! simple as that ! :-)
now with ajax, everything will be almost the same only thing that changes is that you need to be a little bit handy with jquery/js in order not to refresh the page and just change the image ( question ).
hope it helped.
By creating your quiz in a database to store answers with basic tables like :
| question |
|============|
| id (PK) |
| no |
| image_path |
| choice |
|=============|
| id (PK) |
| question_id |
| value |
| answer |
|=====================|
| user_id (PK, FK) |
| question_id (PK, FK)|
| choice_id (PK, FK) |
| user |
|=====================|
| id (PK) |
| session_id or email |
With a schema like this you can easily use the key no
to present the questions in a coherent order or RAND()
for a randomized order. The choice is optionnal, but if you ever want to extend your quiz you can use it to expand the choices.
To find the next question for a given user could be something like
SELECT *
FROM question as q
JOIN answer as a
ON q.id = a.question_id
WHERE q.id NOT IN (SELECT question_id FROM answer WHERE user_id = :user_id)
AND a.user_id = :user_id
ORDER BY q.no -- or ORDER BY RAND()
LIMIT 1;
This way you will get the first question that the user hasn't answered yet. Other than that, it's up to you how much info you want to keep about your user.
EDIT (to add from first comment)
You will need 2 actions in your controller, one to fetch what to display and sent id to the view and the other to grab the data from the user and store it to the DB.
In your model you will need 2 methods (at least) which would be one to get the next question and one to save the answer. I don't know the specifics of code igniter but here are the main lines:
Controller:
displayAction()
get user id from user model (through session variable or session id)
If you don't have a reference for the user, you need to create one and return it
get next question from question model (user id as param)
send the question data to the view
saveAction()
get user id (through session variable or session id)
get question id (from get or post param)
if you use a database to store choices, validate that the choice is possible, based on the current question
send user id, question id and the choice made to the answer model for storage
redirect to displayAction()