app/exercises/ex3.js
/** Custom exercise formatching 3 words. Inherited from Exercise.js
* @initialize it using: new Ex3();
* @customize it by using prototypal inheritance
**/
import $ from 'jquery';
import Exercise from "./exercise";
import Settings from "../settings";
function Ex3(data,index,size){
this.init(data,index,size);
/** @Override */
this.cacheCustomDom = function(data,index,size){
this.$to = this.$elem.find("#ex-to");
this.$context = this.$elem.find("#ex-content");
this.$showSolution = this.$elem.find("#show_solution");
this.$btn1 = this.$elem.find("#btn1");
this.$btn2 = this.$elem.find("#btn2");
this.$btn3 = this.$elem.find("#btn3");
this.$btn4 = this.$elem.find("#btn4");
this.$btn5 = this.$elem.find("#btn5");
this.$btn6 = this.$elem.find("#btn6");
this.$nextExercise = this.$elem.find('#next-exercise');
this.$feedbackBtn = this.$elem.find('#feedback');
};
/** @Override */
this.bindUIActions = function(){
//Bind UI action of Hint/Show solution to the function
this.$showSolution.on("click", this.handleHint.bind(this));
//Bind UI action of button 1 click to the function
this.$btn1.on("click", this.selectChoice.bind(this,1));
//Bind UI action of button 2 click to the function
this.$btn2.on("click", this.selectChoice.bind(this,2));
//Bind UI action of button 3 click to the function
this.$btn3.on("click", this.selectChoice.bind(this,3));
//Bind UI action of button 4 click to the function
this.$btn4.on("click", this.selectChoice.bind(this,4));
//Bind UI action of button 5 click to the function
this.$btn5.on("click", this.selectChoice.bind(this,5));
//Bind UI action of button 6 click to the function
this.$btn6.on("click", this.selectChoice.bind(this,6));
//Next exercise clicked
this.$nextExercise.on("click",this.onRenderNextEx.bind(this));
//Next exercise clicked
this.$feedbackBtn.on("click",this.giveFeedbackBox.bind(this));
};
/** @Override */
this.wrongAnswerAnimation = function(){
this.shake.shakeFocusedElement();
}
this.selectChoice = function(btnID){
// if no button was previously selected, select it now
if(this.chosenButton == -1){
this.chosenButton = btnID;
}else{
// otherwise check the selection
this.check(btnID);
}
};
// Disables correctly selected buttons
this.successDisableBtn = function(btnID){
var elem = $("#btn"+btnID);
elem.prop('disabled', true);
elem.addClass("btn-success");
};
//Checks if a button is disabled
this.isDisabled = function(btnID){
var elem = $("#btn"+btnID);
return elem.is(':disabled');
};
// Checks answers
this.check = function(btnID){
if(this.checkCondition(btnID)){
// Disable buttons
this.successDisableBtn(btnID);
this.successDisableBtn(this.chosenButton);
this.correctAnswers ++;
this.endExercise();
}else{
this.wrongAnswerAnimation();
}
this.chosenButton = -1;
};
this.endExercise = function(){
// check if all the answers were given
if(this.successCondition(0)){
// Proceed to next exercise
this.checkAnswer(0);
// Prepare the document
this.prepareDocument();
// Reset buttons, answers, hints
this.resetBtns();
this.correctAnswers = 0;
this.hints = 0;
}
};
// Checks the selected buttons
this.checkCondition = function(btnID){
if((this.answers.indexOf(btnID) == -1)|| (this.choices.indexOf(this.chosenButton) == -1)){
return (this.choices.indexOf(btnID) == this.answers.indexOf(this.chosenButton));
}else{
return (this.answers.indexOf(btnID) == this.choices.indexOf(this.chosenButton));
}
};
/** @Override */
this.successCondition = function(a){
return (this.correctAnswers >= 3);
};
// Resets all the disabled buttons
this.resetBtns = function(){
for(var idx = 1; idx<=6; idx++){
var elem = $('#btn'+idx);
elem.prop('disabled', false);
elem.removeClass("btn-success");
}
};
/** @Override */
this.next = function (){
this.populateButtons();
};
// Populates the buttons
this.populateButtons = function(){
//Random options
var idxs = this.randomNumsInRange(2,this.data.length-1);
var _this = this;
// random numbers between 1 and 3
this.choices = this.arrayWithRandomNumsUpTo(3);
// random numbers between 4 and 6
this.answers = this.arrayWithRandomNumsUpTo(3);
for (var i=0; i<this.answers.length; i++){
this.answers[i] = this.answers[i] + 3;
}
//Populate buttons
function match2Buttons(choice, answer, valueFrom, valueTo) {
_this["$btn"+choice].text(valueFrom);
_this["$btn"+answer].text(valueTo);
}
match2Buttons(this.choices[0],this.answers[0],this.data[this.index].from,this.data[this.index].to);
match2Buttons(this.choices[1],this.answers[1],this.data[idxs[0]].from,this.data[idxs[0]].to);
match2Buttons(this.choices[2],this.answers[2],this.data[idxs[1]].from,this.data[idxs[1]].to);
};
// Gives a hint by disabling a correct match
this.giveHint = function (){
// Only one hint is possible
if(this.hints < 1){
// Disable buttons
if(this.disableHintButtons(0)) return;
if(this.disableHintButtons(1)) return;
if(this.disableHintButtons(2)) return;
}
};
// Disables the buttons given in the hint
this.disableHintButtons = function(idx){
if(!this.isDisabled(this.answers[idx])){
this.successDisableBtn(this.choices[idx]);
this.successDisableBtn(this.answers[idx]);
this.correctAnswers++;
this.hints++;
this.endExercise();
return true;
}
return false;
};
/** Generates an array of random numbers of given size
* @param size: defines how many random numbers we want
* the resulted random numbers will in the range of [1,size]
*/
this.arrayWithRandomNumsUpTo = function(size){
var arr = [];
while(arr.length < size){
var randomnumber = Math.ceil(Math.random()*size);
if((arr.indexOf(randomnumber) > -1)) continue;
arr[arr.length] = randomnumber;
}
return arr;
};
/** Generates an array of random numbers of given size
* @param size: defines how many random numbers we want
* @param range: defines the upper limit of the numbers: [1,range]
*/
this.randomNumsInRange = function(size,range){
var arr = [];
while(arr.length < size){
var randomnumber = Math.ceil(Math.random()*range);
if((arr.indexOf(randomnumber) > -1) || randomnumber==this.index) continue;
arr[arr.length] = randomnumber;
}
return arr;
};
};
Ex3.prototype = Object.create(Exercise.prototype, {
constructor: Ex3,
/************************** SETTINGS ********************************/
description: {value: "Match each word with its translation"},
customTemplateURL: {value: 'static/template/exercise/ex3.html'},
choices: { writable: true, value:[1,2,3]}, // arr of indexes of possible choices
answers: { writable: true, value:[1,2,3]}, // arr of indexes of possible answers
chosenButton: { writable: true, value:-1}, // ID of currently selected button; -1 means no button is selected
correctAnswers: { writable: true, value:0}, // number of correct answers
hints: {writable:true, value:0}, // max number of possible hints is 1
minRequirement: { writable: true, value:4}, // minimum number required for the ex
resultSubmitSource: {value: Settings.ZEEGUU_EX_SOURCE_MATCH},
/*******************************************************************/
});
export default Ex3;