Files
gf-core/demos/TransQuiz/translation_quiz.js

765 lines
24 KiB
JavaScript

// translation_quiz.js, assumes that quiz_support.js has also been loaded
/*-------------------------------------- Configuration Variables --------------------------------------*/
var pass_percentage = 0.75;
var min_no_questions = 10;
var exam_quesNo = 10; // sets the number of questions appearing in an exam
var max_answer_times = 1; // the max limit for the user to increase his/her score
/*-------------------------------------- other Variables --------------------------------------*/
var grammar;
var question_lang;
var answer_lang;
//saves the random tree generated by the server in generate_question function to be used by the check_answer
var rand_tree;
var counter;
var score;
var confirmed_check = new Boolean(true);
var prev_pressed = new Boolean();
var prev_question;
var prev_explanation;
var prev_answer;
var prev_hint;
var current_question;
var current_answer;
var current_explanation= "";
var current_hint;
//for history
var quiz_history = [];
var history_shown= new Boolean();
var index =0;
//for check answer
var answer_was_right= new Boolean();
var raw_user_answer;
var user_answer;
var user_answer_splited;
var server_answer;
var all_answers = [];
var parsed_trees = 0;
var words_hidden = new Boolean();
var answer_times ;
var hint_times ;
var hint_pressed = new Boolean();
var restart_active = new Boolean();
var is_ended = new Boolean();
var info_hidden = new Boolean();
//modes variables
var have_minibar = new Boolean();
var have_prevQuestion = new Boolean();
var have_checkAns = new Boolean();
var max_hint_times;
var selected_mode;
/*-------------------------------------- Functions --------------------------------------*/
function default_values()
{
//resets the question, answer and the explanation and hint display areas
document.question.question_text.value= "Quiz questions will be displayed here.";
document.answer.answer_text.value = " ";
document.explanation.explanation_text.value= "Explanations are displayed here.";
document.getElementById("hint_txt").innerHTML = "";
//resets some flags
prev_pressed = false;
is_ended = false; //refering to the End button or end o quiz by score or end of exam
restart_active = false; //refering to the Restart button
hint_pressed = false;
answer_was_right= false;
history_shown= false;
//resets the counter and score displays and some variables
answer_times = 1;
counter = 0;
score = 0;
hint_times =0;
document.getElementById('counter_display').value = counter;
document.getElementById('score_display').value = score;
//resets the variables for keeping the history
quiz_history = [];
index =0;
var history=element("history_part");
history.innerHTML ="";
//resets the variables for keeping the parsing and linearization altenatives
parsed_trees = 0;
all_answers = [];
//shows the normal user answer area
show_element("user_answer");
}
function start_quiz()
{
//sets the grammar and From and To languages
grammar= minibar.grammar_menu.value;
question_lang= minibar.from_menu.value;
answer_lang= minibar.to_menu.value;
//removes the start button
minibar.quizbar.removeChild(minibar.quizbar.lastChild);
set_mode();
//shows the minibar area and buttons
var buttons_bar=element("buttons_bar");
if (have_minibar)
{
//show the minibar word magnets
show_element("minibar_contin");
//show the delete and clear buttons
show_element("minibar_buttons");
//hides the normal user answer area
hide_element("user_answer");
//changes the "Check Answer" button to a none_submit one
buttons_bar.removeChild(buttons_bar.lastChild);
appendChildren(buttons_bar,
[ button("Check Answer","check_answer_quiz()","C", "check_answer")]);
}
else
{
//enable the user answer area
document.getElementById('user_answer').disabled = false;
//hide the minibar word magnets
hide_element("minibar_contin");
//hide the delete and clear buttons
hide_element("minibar_buttons");
//changes the "Check Answer" button to a submit one
buttons_bar.removeChild(buttons_bar.lastChild);
appendChildren(buttons_bar,
[ submit_button("Check Answer", "check_answer")]);
}
//conditionally enbles the "Hint", "Check Answer", "Next Question" and "Previous Question" buttons, and the minibar
if (have_checkAns)
document.getElementById('check_answer').disabled = false;
else
document.getElementById('check_answer').disabled = true;
if (have_prevQuestion)
document.getElementById('previous_question').disabled = false;
if ( max_hint_times > 0 )
document.getElementById('hint').disabled = false;
document.getElementById('next_question').disabled = false;
//generates the first quiz question
generate_question();
//resets the restart_active
restart_active= true ;
//hides the information
if ( info_hidden == false )
toggle_info();
}
function restart_quiz()
{
//javascript:location.reload(true);
if (restart_active == true)
{
var end_confirmed= new Boolean(true);
if (!is_ended )
end_confirmed = confirm(" Are you sure you want to quit this quiz!");
if (end_confirmed)
{
end_quiz(false);
reset_mode();
//add the start button
appendChildren(minibar.quizbar,[ button("Start Quiz","start_quiz()","S")]);
//removes the History button
var history_bar=element("history_bar");
history_bar.removeChild(history_bar.lastChild);
default_values();
}
}
}
function generate_question()
{
//for the exam mode
if (selected_mode == "Exam Mode")
{
if (check_notEmpty())
{
if (counter > 0)
{
document.getElementById('score_display').value = "?";
//save the current user answer for history
current_answer = document.answer.answer_text.value;
quiz_history[index][1] = current_answer;
make_all_answers();
}
else
exam_continue();
}
}
else
{
if (prev_pressed == true )
{
//changes the question, answer and the explanation back to the current one
document.question.question_text.value= current_question;
document.answer.answer_text.value = current_answer;
document.explanation.explanation_text.value= current_explanation;
document.getElementById("hint_txt").innerHTML = current_hint;
prev_pressed = false; // to go back to normal
//enables the "Previous Question","Hint" and "Check Answer" buttons
document.getElementById('previous_question').disabled = false;
document.getElementById('check_answer').disabled = false;
document.getElementById('hint').disabled = false;
}
else
{
// if the user clicks the "Next Question" without cheking his/her previous answer,
// asks for user's confirmation before moving to the next question
if ( answer_times == 0 )
{
confirmed_check = confirm("Are you sure you don't want to check your answer's correctness!");
if ( hint_times == 0 )
{
//saves the current answer and the explanation which is null(the answer was not checked or hinted)
current_answer = document.answer.answer_text.value;
current_explanation = "You did not check your answer's correctness!";
current_hint = "";
}
//save the current user answer for history
quiz_history[index][1] = document.answer.answer_text.value;
//save the current explanation for history
quiz_history[index][2] = "You did not check your answer's correctness!";
}
if (confirmed_check == true )
{
//save the current question for the "previous question" button and history
prev_question = current_question;
//save the current answer for the "previous question" button
prev_answer = current_answer;
//save the current explanation and hint for the "previous question" button
prev_explanation = current_explanation;
prev_hint= current_hint;
//clears the question, answer and the explanation and hint display areas
clearing();
if (have_minibar)
{
minibar.clear_all();
//unhides the words area and removes the "Show Magnets" button
show_word_magnets();
}
if (answer_was_right) //here it still contains info about the previous question
document.explanation.explanation_text.value= current_explanation;
//resets the times user has answered to the current question
answer_times = 0;
//resets the times user has pressed hint for the current question
hint_times = 0;
document.getElementById('counter_display').value = counter;
//increments the counter
counter= ++ counter;
//sends a question retrival request to the server
server.get_random(generate_question2);
}
}
}
//sets the focus on the answer area
document.answer.answer_text.focus();
}
function generate_question2(random_trees)
{
//we now have a random abstract syntax tree that we need to linearize
server.pgf_call("linearizeAll",{tree:random_trees[0].tree,
to:question_lang}, generate_question3);
rand_tree= random_trees[0].tree;
}
function generate_question3(random_texts)
{
var no_of_lins = random_texts[0].texts.length;
//generates a random number, to determine which linearization should be used as the question
var which= Math.floor(Math.random()* no_of_lins );
if (which >= no_of_lins)
which = which - 1;
//display the new quiz quetion sent by server
document.question.question_text.value= counter +". " + random_texts[0].texts[which];
//save the current question for the "previous question" button and history
current_question = document.question.question_text.value;
index = quiz_history.length;
quiz_history[index] = [];
quiz_history[index][0]= current_question;
}
function check_answer_quiz()
{
if (check_notEmpty())
{
//resets the user confirmation for moving to next question without checking the answer
confirmed_check = true;
//clears the explanation and Hint display area
document.explanation.explanation_text.value = "";
document.getElementById("hint_txt").innerHTML = "";
//save the current user answer for the "peivious question" button and history
current_answer = document.answer.answer_text.value;
quiz_history[index][1] = current_answer;
//increments the times the user has answered to the current question
answer_times ++;
//resets the hint_pressed flag
hint_pressed = false;
if ((answer_times + hint_times) <= 1)
make_all_answers();
else
continue_checking();
}
}
function make_all_answers()
{
//resets the variables for keeping the parsing and linearization altenatives
parsed_trees = 0;
all_answers = [];
//we now need to linearize the random abstract syntax tree in order to
//find all possible correct answers then we check user's answer against these answers.
server.pgf_call("linearize",{tree:rand_tree, to:question_lang}, parse_answer);
}
function parse_answer(right_answer)
{
server.parse(question_lang,right_answer[0].text, parse_answer2);
}
var trees_to_go;
function parse_answer2(parsed_answer)
{
trees_to_go = parsed_trees = parsed_answer[0].trees.length;
var j =0;
for (j= 0; j < parsed_trees ; j++)
{
server.linearizeAll(parsed_answer[0].trees[j], answer_lang, collect_answers);
}
}
function collect_answers(lin_answer)
{
var next= 0;
var i=0;
for (i= 0; i < lin_answer[0].texts.length ; i++)
{
next = all_answers.length;
all_answers[next]= lin_answer[0].texts[i];
}
trees_to_go--;
if(trees_to_go == 0)
continue_checking();
}
function continue_checking()
{
if (selected_mode == "Exam Mode")
{
check_answer_exam2();
exam_continue();
}
else
if (hint_pressed)
show_hint2();
else
check_answer2();
}
function check_answer2()
{
if (have_minibar)
hide_word_magnets();
raw_user_answer= document.answer.answer_text.value;
user_answer = remove_unwanted_characters(raw_user_answer);
answer_was_right= false;
var k = 0 ;
for (k= 0; k < all_answers.length; k++)
{
server_answer = remove_unwanted_characters(all_answers[k]);
if ( user_answer == server_answer )
{
if (answer_times <= max_answer_times)
{
//increments the score
score ++;
document.getElementById('score_display').value = score;
}
document.explanation.explanation_text.value = "Yes, that was the correct answer.";
answer_was_right= true;
break;
}
}
if (k >= all_answers.length)
{
document.explanation.explanation_text.value= "No, the correct answer(s) is(are): \n "
+ all_answers;
document.getElementById('counter_display').value = counter;
}
//save the current explanation for the "previous question" button and history
current_explanation = document.explanation.explanation_text.value;
quiz_history[index][2] = current_explanation;
if ((counter >= min_no_questions) && ((score/counter) >= pass_percentage))
{
if (answer_was_right)
document.explanation.explanation_text.value += "\nAlso, ";
else
document.explanation.explanation_text.value += "\nHowever, ";
document.explanation.explanation_text.value += "Congratulations!!! You passed the quiz. Click \"Restart Quiz\" for a new one.";
document.getElementById('counter_display').value = counter;
end_quiz(false);
}
else
if (answer_was_right)
{
//goes to the next question automaticly after getting the correct answer
generate_question();
}
//save the current hint for the "previous question" button
current_hint = document.getElementById("hint_txt").innerHTML ;
}
function check_answer_exam2()
{
raw_user_answer= document.answer.answer_text.value;
user_answer = remove_unwanted_characters(raw_user_answer);
var k = 0 ;
for (k= 0; k < all_answers.length; k++)
{
server_answer = remove_unwanted_characters(all_answers[k]);
if ( user_answer == server_answer )
{
//increments the score
score ++;
//save the current explanation for history
current_explanation = "Yes, that was the correct answer.";
quiz_history[index][2] = current_explanation;
break;
}
}
if (k >= all_answers.length)
{
//save the current explanation for history
current_explanation = "No, the correct answer(s) is(are): \n " + all_answers;
quiz_history[index][2] = current_explanation;
}
}
function exam_continue()
{
if (counter >= exam_quesNo)
exam_result();
else
{
//clears the question and answer and the explanation and hint display areas
clearing();
document.getElementById('counter_display').value = counter + "/" + exam_quesNo;
//increments the counter
counter= ++ counter;
//sends a question retrival request to the server
server.get_random(generate_question2);
}
}
function exam_result()
{
document.getElementById('score_display').value = score;
document.getElementById('counter_display').value = counter + "/" + exam_quesNo;
document.explanation.explanation_text.value= "That's the end of exam.";
end_quiz(false);
}
function show_hint()
{
if (hint_times < max_hint_times)
{
if (check_notEmpty())
{
//clears the explanation and Hint area
document.explanation.explanation_text.value = "";
document.getElementById("hint_txt").innerHTML = "";
//increments the times the user has pressed hint button
hint_times= ++ hint_times;
//resets the user confirmation for moving to next question without checking the answer
confirmed_check = true;
//save the current user answer for the "peivious question" button
current_answer = document.answer.answer_text.value;
//sets the hint_pressed flag
hint_pressed = true;
raw_user_answer= document.answer.answer_text.value;
user_answer = remove_unwanted_characters(raw_user_answer);
user_answer_splited = split_to_words(user_answer);
if ((answer_times + hint_times) <= 1)
make_all_answers();
else
continue_checking();
}
}
else
{
//Error message (max_hint_times is passed)
document.explanation.explanation_text.value = "Sorry, you have already used up your allowed number of hints for this question.";
}
}
function show_hint2()
{
var best_answer = new Array();
best_answer= find_closest(all_answers);
var compared = new Array();
compared = string_matching(best_answer, user_answer_splited);
//preparing the Hint spans
var hint = element("hint_txt");
hint.innerHTML = "<b>Hint: </b>";
var max_length = Math.max(best_answer.length, user_answer_splited.length);
for (k= 0; k < max_length; k++)
{
var id = "word" + k.toString();
var word_span= span_id(id);
hint.appendChild(word_span);
}
var k=0;
var visited = new Array();
for (k= 0; k < best_answer.length; k++)
{
visited[k] = 0;
}
var i= 0; //i is used for the user_answer
var myid = "";
while ( i < compared.length)
{
myid = "word" + i.toString();
if (compared[i] == 0)
{
var j =0; //j is used for the server_answer
while (j < best_answer.length)
{
if (visited[j] == 0 && user_answer_splited[i] == best_answer[j] && (j >= compared.length || compared[j] == 0 ))
{
//yellow for the right word in wrong place
document.getElementById(myid).style.color="#FFFF00";
visited[j] = 1;
break;
}
j++;
}
if ( j >= best_answer.length)
{
//red for the totaly wrong word
document.getElementById(myid).style.color="#FF0000";
}
}
else
{ //green for the right word in right place
document.getElementById(myid).style.color="#339933";
}
document.getElementById(myid).innerHTML = user_answer_splited[i] + " ";
i++;
}
while ( i < best_answer.length)
{
myid = "word" + i.toString();
document.getElementById(myid).style.color="#FF0000";
document.getElementById(myid).innerHTML = "____ ";
i++;
}
//save the current explanation and hint for the "previous question" button
current_explanation = document.explanation.explanation_text.value;
current_hint = document.getElementById("hint_txt").innerHTML ;
}
function previous_question_quiz()
{
if ( counter > 1)
{
if ( answer_times == 0 && hint_times == 0 )
{
//sets the current answer and the explanation and hint
current_answer = document.answer.answer_text.value;
current_explanation = "";
current_hint = "";
}
//disables the "Previous Question","Hint" and "Check Answer" buttons
document.getElementById('previous_question').disabled = true;
document.getElementById('check_answer').disabled = true;
document.getElementById('hint').disabled = true;
//changes the question, answer and the explanation
document.question.question_text.value= prev_question;
document.answer.answer_text.value = prev_answer;
document.explanation.explanation_text.value= prev_explanation;
document.getElementById("hint_txt").innerHTML = prev_hint;
prev_pressed = true; // to remember the current question, answer and explanation
}
}
function end_quiz(confirm_needed)
{
if (restart_active == true && is_ended == false)
{
var end= new Boolean(true);
if (confirm_needed)
end = confirm(" Are you sure you want to quit this quiz!");
if (end)
{
if (have_minibar)
{
//removes the "Show Magnets" button if exists
show_word_magnets();
//remove the minibar word magnets if there was any
remove_minibar();
//shows the normal user answer area
show_element("user_answer");
}
disable_all();
is_ended = true;
//adds a Show Quiz History button
var history_bar=element("history_bar");
appendChildren(history_bar,
[ button("Show Quiz History","show_history()","H", "quiz_history")]);
}
}
}
function show_history()
{
var current_grammar = minibar.grammar.name; // minibar.grammar.name gives the grammar name without .pgf
var to_lang= langpart(minibar.to_menu.value,current_grammar);
var from_lang= langpart(minibar.from_menu.value,current_grammar);
var history=element("history_part");
if (history_shown == false)
{
var i=0;
for (i= 0; i < quiz_history.length ; i++)
{
var question = text("Question" + " "+quiz_history[i][0] + "\n");
history.appendChild(empty("br"));
history.appendChild(question);
history.appendChild(empty("br"));
var answer = text("Your Answer" + ": "+ quiz_history[i][1] + "\n");
history.appendChild(answer);
history.appendChild(empty("br"));
var explan = text("Explanation" + ": "+ quiz_history[i][2] + "\n");
history.appendChild(explan);
history.appendChild(empty("br"));
history.appendChild(empty("br"));
}
history_shown = true;
}
var history_content = history.innerHTML;
var history_window = window.open('', 'historyPopup', "dependent = 1, scrollbars=1, location=1, statusbar=1, width=540, height=650, left = 10, top = 20");
history_window.document.writeln('<html><head><title>Quiz History</title></head><body>');
history_window.document.writeln('<h3> Your Quiz History </h3>');
history_window.document.write('<b> Quiz Mode: </b>');
history_window.document.write(selected_mode+ ", ");
history_window.document.write('<b> Grammar: </b> ');
history_window.document.write(" "+ current_grammar +", ");
history_window.document.write('<b> From: </b>');
history_window.document.write(" "+ from_lang + ", ");
history_window.document.write('<b> To: </b>');
history_window.document.writeln(" "+ to_lang);
history_window.document.writeln('<div style="font-size:18px;">');
history_window.document.writeln(history_content);
history_window.document.writeln('</div>');
history_window.document.writeln('<div style="color: #2E8B57; font-size:16px; font-weight: bold;"><a href="javascript: window.print()">Print History</a></div>');
history_window.document.writeln('<div style="padding-left: 320px; color: #2E8B57; font-size:16px; font-weight: bold;"><a href="javascript: window.close()">Close page</a></div>');
history_window.document.writeln('</body></html>');
history_window.document.close();
}