German Vocab

HTML / CSS / JavaScript / jQuery

Background

To aid my study of the German language, I decided to create an interactive site that would allow me to quiz myself on vocabulary. The initial instantiation of this site was designed using a combination of PHP and JavaScript.

I stored the vocab words in multidimensional PHP arrays. These arrays were all grouped together in a separate PHP file. I then wrote PHP code within each quiz page that called in the desired array and shuffled it. Shuffling each array was an important part of my initial design plan; I knew that I wanted to be able to easily and randomly sort the contents of each vocab list upon refreshing the page. Finally, the code displayed the shuffled English words alongside text input fields in a form. Upon submission of the form, the user's input would be checked using JavaScript to see if it matched the answers stored in the original PHP array.

This instantiation of the vocab site worked fine, but eventually I decided to re-write all the PHP code in JavaScript. This made sense to me since there was no particular reason to be using PHP, as nothing about the code was relying on the server. It was also useful to standardize all code across the project in one language.

I opted to use plain JavaScript (versus jQuery) for the most part throughout this project. The exception in this site comes in the multiple choice based review quiz. This quiz does in fact implement some usage of jQuery:

var section = $("section");
var numberCorrect = 0;
var i = 0;

$("#quiz1").submit(function(e) {
	
	var valueCheck = $(section[i]).find("input[type=radio]:checked").val();
	$(section[i]).hide();

	if (valueCheck == allQuestions[i].choices[allQuestions[i].correctAnswer]) {
		numberCorrect++;
		i++;
	}
	else {
		i++;
	;}
	
	$(section[i]).show();
	
	if (i == section.length) {
		$(".top-message").html("You got " + numberCorrect + " out of " +  section.length + " correct.");
		$("#next").hide();
	}
	
	e.preventDefault();
	
});

PHP to JavaScript

The main source of work in this project was re-writing the code that calls in each array, shuffles it, and displays the English words in a list with associated input text fields for users to type in the German equivalents. In the original PHP, my code was:

shuffle($nouns1);

echo "<form id='vocab_form'><ol>";
foreach($nouns1 AS $key => $value) {
	foreach($value AS $english_word => $german_word) {
		echo "<li>" . $english_word . " <span class='answer' style='display: none; font-weight: bold;'>" . $german_word . "</span></li>";
		echo "<input type='text' name='answer_key' id='" . $german_word . "'>";
		echo "<input type='checkbox' name='choose_word' class='check_box' style='display: none;'>";
	}
}
echo "</ol><input type='submit' value='Check Answers' id='check_answers'>";
echo "<input type='button' value='Quiz Selected Again' id='quiz_again' style='display: none;'>";
echo "<input type='button' value='Refresh Quiz' id='refresh_quiz' style='display: none'></form>";

nouns1 being a multidimensional PHP array that looked like the following:

$nouns1 = array(
0 => array("father" => "der Vater"),
1 => array("male teacher" => "der Lehrer"),
2 => array("cellar" => "der Keller"),
3 => array("uncle" => "der Onkel"),
4 => array("spoon" => "der Löffel"),
5 => array("saddle" => "der Sattel"),
6 => array("store, shop" => "der Laden"),
7 => array("car" => "der Wagen"),
8 => array("stomach" => "der Magen"),
9 => array("professor" => "der Professor"),
10 => array("tourist" => "der Tourist"),
// ETC...
);

The eventual result re-written in JavaScript is:

function shuffle(o){
	for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
}

nouns1 = shuffle(nouns1);

for (var i in nouns1) {
	var obj = nouns1[i];
	
	for(var j in obj) {
		var innerObj = obj[j];
		for(var englishWord in innerObj) {
			var germanWord = innerObj[englishWord];
			document.write("<li>" + englishWord + "<span class='answer' style='display: none; font-weight: bold;'>" +
			germanWord + "</span></li><input type='text' name='answer_key' id='" + germanWord +
			"' autocomplete='off'><input type='checkbox' class='check-box' style='display: none;'>" );
		}
	}
}

Referring to a JavaScript array with embedded objects:

var nouns1 = [
{"key1": {
	"father": "der Vater"
}},
{"key2": {
	"male teacher": "der Lehrer"
}},
{"key3": {
	"cellar": "der Keller"
}},
{"key4": {
	"uncle": "der Onkel"
}},
{"key5": {
	"spoon": "der Löffel"
}},
// ETC...
];

Besides the obvious discrepancies in syntax between the two languages, the major issues/differences I ran into were the following:

(1) PHP already has a shuffle function. For JavaScript, I searched for an in-built shuffle in the language and found none. I ended up using a solution suggested by others on StackExchange.

(2) PHP allows the indexes of arrays to be non-numerical. Therefore, the English/German word pairs work as an array; in JavaScript these pairs are objects. The distinction is seemingly minimal, but it initially caused me some confusion when I began re-writing the code.

(3) Additionally, PHP has a foreach loop that can go through each key/value pair of an array. This was important to my original code as it kept the English/German word pairs associated with each other, while shuffling the outer array around it.

In JavaScript, I had to approach this issue differently, having no "key AS value" option within a for loop. Instead, I had to create a variable representing my English/German word objects.

In my code, this variable is named obj. For example, using i to loop through the indexes of the outer array results (on the 43rd time through, after shuffling) in:

i = "44";
nouns[i] = {"key18" = {woman: "die Frau"}} = var obj

I then loop through each index of obj using the variable j. In this example, this corresponds to:

j = "key18";

I then create the variable innerObj now representing the object containing solely the English/German word pair:

obj[j] = {woman: "die Frau"} = innerObj

The variable englishWord refers to the "key" in each innerObj. This results in the final assigning of variables:

englishWord = "woman"
innerObj[englishWord] = "die Frau" = germanWord

The move from PHP to JavaScript was a project I had long hoped to undertake with this site. Now that this has been accomplished, I hope to more easily implement further updates and functionality into the project.

Visit Site