/** * /sQuiz/sQuiz.js * @version 1.4 * @desc sQuiz main class file * @author Fándly Gergő Zoltán (gergo@systemtest.tk, systemtest.tk) * @copy 2017 Fándly Gergő Zoltán * License: sQuiz for creating small jQuery based quizs in an implementable way Copyright (C) 2017 Fándly Gergő Zoltán This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **/ (function($){ /** * sQuiz(element, quiz) * @desc Creating a new quiz based on a json file * @param $ element Container in which the quiz will be running * @param string quiz A JSON string/JSON object containing an sQuiz parameter list */ $.sQuiz=function(element, quiz){ this.element=(element instanceof $)?element:$(element); this.quiz=(typeof quiz=="object")?quiz:JSON.parse(quiz); this.current=-1; this.currentQustion; this.reg; this.countdown; this.elapsedPerTest=(this.quiz.timeLimitPerTest>0)?0:-2; this.elapsed=(this.quiz.timeLimit>0)?0:-2; this.answers=[]; this.quizDoneCallback; this.quizDoneOptions; }; $.sQuiz.prototype={ /** * sQuiz.setRegionalization(lang) * @desc Assing an Object which has all the needed vars for language (startQuiz, timeRemaining, etc. Full list in /sQuiz/lang.json), or leave it on default for English * @param object lang Object storing language settings */ setRegionalization: function(lang){ this.reg=lang; }, /** * sQuiz.setQuizDoneCallback(callback) * @desc Assign a function to run when the quiz is finished * @param function callback Function to call */ setQuizDoneCallback: function(callback){ this.quizDoneCallback=callback; }, /** * sQuiz.setQuizDoneOptions(options) * @desc Set options to offer when quiz is finished. Set download to true, to offer downloading. Set upload to true, to offer online submit to upload_url. Set custom to a JS function call to do self made stuff. Custom action's label regionalization is customAction. * @param object options Object containing the settings */ setQuizDoneOptions: function(options){ this.quizDoneOptions=options; }, /** * sQuiz.secToTime(sec) * @desc Function for converting seconds to traditional MM:SS format * @param int sec Seconds to convert * @return string */ secToTime: function(sec){ var mins=Math.floor(sec/60); var secs=sec%60; var minstr=(mins.toString().length==1)?"0"+mins.toString():mins.toString(); var secstr=(secs.toString().length==1)?"0"+secs.toString():secs.toString(); var time=minstr+":"+secstr; return time; }, /** * sQuiz.quizDone() * @desc Function to call when a test is finished */ quizDone: function(){ var points=0; $.each(this.answers, function(key, val){ if(val.correct){ points++; } }); var self=this; this.element.slideUp(function(){ var buttons="
"; if(self.quizDoneOptions.download==true){ buttons+=""; } if(self.quizDoneOptions.upload==true){ buttons+=""; } if(self.quizDoneOptions.custom!=undefined){ buttons+=""; } buttons+="
"; self.element.html("

"+self.reg.quizFinished+"


"+self.reg.resultsGot+": "+points.toString()+"/"+self.quiz.questions.length+"



"+buttons); $("#sqDownloadResults").on("click", function(){ var json=JSON.stringify(self.answers); var send="text/json;charset=utf-8,"+encodeURIComponent(json); $("")[0].click(); }); $("#sqUploadResults").on("click", function(){ var json=JSON.stringify(self.answers); var submitter=prompt(self.reg.yourname+":"); $.ajax({ url: (self.quizDoneOptions.upload_url!=undefined)?self.quizDoneOptions.upload_url:"", type: "POST", data: { "submitResult": json, "submitResult_submitter": submitter }, success: function(res){ alert(self.reg.idForResult+": "+res); } }); }); self.element.slideDown(); }); if(this.quizDoneCallback!=undefined){ this.quizDoneCallback(this.answers, this.quiz); } }, /** * sQuiz.nextQuestion() * @desc Start the next question. Should be called only internally! */ nextQuestion: function(){ var self=this; this.current++; if(this.current>=this.quiz.questions.length){ this.quizDone(); } else{ var type=this.quiz.questions[this.current].type; this.element.slideUp(function(){ var timer="

"+(self.quiz.timeLimit>0?""+self.reg.timeLeft+":
":"")+(self.quiz.timeLimitPerTest>0?""+self.reg.timeLeftPerTest+": ":"")+"

"; var submitbutton="

"; self.element.html(timer+"
"+submitbutton); self.element.children("#sqTimeLeft").html(self.secToTime(self.timeLimit)); self.element.children("#sqTimeLeftPerTest").html(self.secToTime(self.timeLimitPerTest)); self.currentQuestion=new $["sQuiz_module_"+type](self, self.quiz.questions[self.current]); $("#sqSubmitButton").on("click", function(){ self.currentQuestion.submit(); $("#sqSubmitButton").unbind(); $("#sqSubmitButton").fadeOut(function(){ $(this).html(""+self.reg.nextQuestion); $(this).fadeIn(); }); $("#sqSubmitButton").on("click", function(){ self.nextQuestion(); }); }); self.currentQuestion.load(); self.element.slideDown(function(){ self.startTimer(); }); }); } }, /** * sQuiz.init() * @desc set up styles and so for the container */ init: function(){ var self=this; if(this.reg==undefined){ this.reg={ "downloadResults":"Download results", "uploadResults":"Upload results", "customAction":"Custom action name goes here", "quizFinished":"Quiz finished!", "resultsGot":"You've got the following results", "yourname":"Your name", "idForResult":"Share this ID with anybody you want to know your results", "timeLeft":"Time left for entire quiz", "timeLeftPerTest":"Time left for this question", "submit":"Submit", "nextQuestion":"Next question", "startQuiz":"Start quiz", "answer":"Answer" }; } this.element.hide(); this.element.addClass("sq sq-container"); this.element.html("

"+this.quiz.name+"

"+this.quiz.description+"


"); $("#sqStart").on("click", function(){ self.nextQuestion(); }); this.element.slideDown(); }, /** * sQuiz.startTimer * @desc Starts the countdown */ startTimer: function(){ if(this.quiz.timeLimitPerTest>0 || this.quiz.timeLimit>0){ var self=this; this.elapsedPerTest=0; if(self.quiz.timeLimitPerTest>0){ self.elapsedPerTest++; self.element.children("#sqTimer").children("#sqTimeLeftPerTest").html(self.secToTime(self.quiz.timeLimitPerTest-self.elapsedPerTest)); if(self.elapsedPerTest>=self.quiz.timeLimitPerTest){ $("#sqSubmitButton")[0].click(); } } if(self.quiz.timeLimit>0){ self.elapsed++; self.element.children("#sqTimer").children("#sqTimeLeft").html(self.secToTime(self.quiz.timeLimit-self.elapsed)); if(self.elapsed>=self.quiz.timeLimit){ $("#sqSubmitButton")[0].click(); } } this.countdown=window.setInterval(function(self){ if(self.quiz.timeLimitPerTest>0){ self.elapsedPerTest++; self.element.children("#sqTimer").children("#sqTimeLeftPerTest").html(self.secToTime(self.quiz.timeLimitPerTest-self.elapsedPerTest)); if(self.elapsedPerTest>=self.quiz.timeLimitPerTest){ $("#sqSubmitButton")[0].click(); } } if(self.quiz.timeLimit>0){ self.elapsed++; self.element.children("#sqTimer").children("#sqTimeLeft").html(self.secToTime(self.quiz.timeLimit-self.elapsed)); if(self.elapsed>=self.quiz.timeLimit){ $("#sqSubmitButton")[0].click(); } } }, 1000, self); } }, /** * sQuiz.stopTimer * @desc Stops the countdown */ stopTimer: function(){ clearInterval(this.countdown); } } }(jQuery));