I am currently creating a Rails quiz application with a timer that counts down the seconds left to answer the question.
In my first version, I did this a simple way: creating a variable for the timer, an instance for seconds, and then making it part of the quiz's Javascript, like so:
Quiz = function() {
this.quizCurrent = 0;
this.score = 0;
this.seconds = 10;
this.timing = this.seconds;
this.container = $('#trivia');
this.participationId = null;
}
Quiz.prototype.init = function() {
$('#trivia').on('click', '.btn.btn-primary-questions', this.checkAnswer.bind(this));
$('div.timer strong').text(this.seconds)
this.start();
}
I would now like to move this to the backend using Rails. A previous question references the countdown gem, but that seems to present two issues:
1) I will need to repeatedly call the date/time and validate for each question (which I don't think I can do with countdown), and;
2) I ideally could then pass this value into the Javascript as a variable.
In the documentation for that gem, it shows how you can pass the countdown time into the view directly. However, I am using the countdown value (in other words, when it hits zero) to force the user to the next question while recording a wrong answer, like below, as part of my validation:
Quiz.prototype.timer = function() {
var that = this;
this.timing--;
$('div.timer strong').text(this.timing);
if (this.timing <= 0) {
self.stop();
$.getJSON('/api/skip_question/' + this.participationId, function() {
that.nextQuestion();
})
}}
Any ideas on how I can "check" the time on the backend while still having the quiz check to make sure time hasn't run out?
I don't know anything about the countdown gem, but a simple solution comes to mind.
Lets say you keep a timestamp on the backend and when your js quiz starts it lets the back end know that the quiz has started.
$.getJSON('/api/start_quiz/', function() {
//do whatever javascript starts the quiz.
})
on the backend, lets assume you have a QuizAttempt model with corresponding database value 'attempt_timestamp':
def start_quiz
QuizAttempt.create(user_id: current_user.id, attempt_timestamp: Time.now)
end
Then you could have a before filter that determines if time has run out on your skip_question and answer_question endpoints. (in my example there's an 8 minute time limit.
before_filter :check_time, only: [:skip_question, :answer_question]
def check_time
#get last attempt
last_attempt = QuizAttempt.where(user_id: current_user.id).last
if (last_attempt.attempt_timestamp + 8.minutes) < Time.now
#time is up
return false
end
end
Side Idea: you could also add an endpoint that responds with the recorded timestamp for the purpose of syncronizing the js clock with the timestamp in the db.
Edit: another possible place to keep said timestamp might be in the session rather than the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With