A Simple Flashcard System in JavaScript

The JavaScript program below, when run, prompts for a lesson file, and, when one is provided, quizzes the user with the questions from it. When the user answers all questions correctly three times in a row, the lesson is counted as complete.

The lesson file should be a text file. Each line in the file represents a question and its correct response, delimited by a semicolon.

To see the code in action, copy it into an .html file and open that file in a web browser that runs JavaScript. Or, for an online version, visit https://thiscouldbebetter.neocities.org/flashcards.html.

flashcards


<html>
<body>

	<!-- user interface -->
	<div>
		<input id="inputFileLesson" type="file" onchange="inputFileLesson_Changed(this);"
	</div>

	<div>
		<textarea id="textareaPresentation" readonly="readonly"></textarea>
	</div>

	<div>
		<input id="inputResponse"></input>
	</div>

	<p id="pStatusMessage">Upload a valid file to begin.</p>
	
<script type="text/javascript">

// ui event handlers

function inputFileLesson_Changed(inputFileLesson)
{
	var file = inputFileLesson.files[0];

	var fileReader = new FileReader();
	fileReader.onload = inputFileLesson_Changed_FileLoaded;
	fileReader.readAsText(file);
}

function inputFileLesson_Changed_FileLoaded(event)
{
	var fileContents = event.target.result;

	var questionsAsStrings = fileContents.split("\n");

	var questions = [];

	for (var i = 0; i < questionsAsStrings.length; i++)
	{
		var questionAsString = questionsAsStrings[i];

		var presentationAndResponse = questionAsString.split(";");

		if (presentationAndResponse.length == 2)
		{
			var presentation = presentationAndResponse[0];
			var response = presentationAndResponse[1].trim();

			var question = new Question(presentation, response);

			questions.push(question);
		}
	}

	var lessonDefn = new LessonDefn
	(
		questions, 
		3 // timesCorrectPerQuestion
	);

	Globals.Instance.initialize(lessonDefn);
}

// classes

function DisplayHelper()
{
	// do nothing
}
{
	DisplayHelper.prototype.displayLessonRun = function(lessonRun)
	{
		var textareaPresentation = document.getElementById
		(
			"textareaPresentation"
		);

		var questionCurrent = lessonRun.questionCurrent();

		textareaPresentation.value = questionCurrent.presentation;

		var inputResponse = document.getElementById("inputResponse");
		inputResponse.value = "";
		inputResponse.focus();

		var pStatusMessage = document.getElementById("pStatusMessage");
		pStatusMessage.innerHTML = lessonRun.statusMessage;
	}
}

function Globals()
{
	// do nothing
}
{
	// instance

	Globals.Instance = new Globals();

	// methods

	Globals.prototype.initialize = function(lessonDefn)
	{
		this.lessonDefn = lessonDefn;

		this.lessonRun = new LessonRun(this.lessonDefn);

		this.displayHelper = new DisplayHelper();
		this.inputHelper = new InputHelper();

		this.lessonRun.initialize();

		this.inputHelper.initialize();

		this.displayHelper.displayLessonRun(this.lessonRun);
	}
}


function InputHelper()
{
	// do nothing
}
{
	InputHelper.prototype.initialize = function()
	{
		document.body.onkeydown = this.handleEventKeydown.bind(this);
	}

	// event handlers

	InputHelper.prototype.handleEventKeydown = function(event)
	{
		if (event.key == "Enter")
		{
			var inputResponse = document.getElementById("inputResponse");
			var responseActual = inputResponse.value.trim();
			
			var lessonRun = Globals.Instance.lessonRun;
			var responseExpected = lessonRun.questionCurrent().responseCorrect;
	
			var responseRecordCurrent = lessonRun.responseRecordCurrent();

			if (responseActual == responseExpected)
			{
				responseRecordCurrent.timesCorrect++;
				lessonRun.statusMessage = 
					"Correct!  This question has been answered correctly "
					+ responseRecordCurrent.timesCorrect
					+ " times in a row.";
			}
			else
			{
				responseRecordCurrent.timesCorrect = 0;
				lessonRun.statusMessage = 
					"Incorrect!  The correct answer was "
					+ responseExpected
					+ ".  You answered "
					+ responseActual
					+ ".";	
			}

			if (lessonRun.isComplete() == true)
			{
				lessonRun.statusMessage = "Lesson complete!";
				document.body.onkeydown = null;
			}
			else
			{
				lessonRun.questionAdvance();
			}

			Globals.Instance.displayHelper.displayLessonRun
			(
				lessonRun
			);
		}
		
	}
}

function LessonDefn(questions, timesCorrectPerQuestion)
{
	this.questions = questions;
	this.timesCorrectPerQuestion = 
		timesCorrectPerQuestion;
}

function LessonRun(defn)
{
	this.defn = defn;
	this.statusMessage = 
		"Each question must be correctly answered " 
		+ this.defn.timesCorrectPerQuestion
		+ " times in a row.";
}
{
	LessonRun.prototype.initialize = function()
	{
		this.questionIndexCurrent = 0;
		this.responseRecords = [];

		var questions = this.defn.questions;

		for (var i = 0; i < questions.length; i++)
		{
			var question = questions[i];
			var responseRecord = new ResponseRecord();
			this.responseRecords.push(responseRecord);
		}
	}

	LessonRun.prototype.isComplete = function()
	{
		var returnValue = true;

		var timesRequired = this.defn.timesCorrectPerQuestion;

		for (var i = 0; i < this.responseRecords.length; i++)
		{
			var responseRecord = this.responseRecords[i];
			if (responseRecord.timesCorrect < timesRequired)
			{
				returnValue = false;
				break;
			}
		}	

		return returnValue;
	}

	LessonRun.prototype.questionAdvance = function()
	{
		var isFirstTime = true;
		var timesRequired = this.defn.timesCorrectPerQuestion;

		while 
		(
			isFirstTime == true 
			|| this.responseRecordCurrent().timesCorrect >= timesRequired
		)
		{
			isFirstTime = false;

			this.questionIndexCurrent++;

			if (this.questionIndexCurrent >= this.defn.questions.length)
			{
				this.questionIndexCurrent = 0;
			}
		}
	}

	LessonRun.prototype.questionCurrent = function()
	{
		return this.defn.questions[this.questionIndexCurrent];
	}

	LessonRun.prototype.responseRecordCurrent = function()
	{
		return this.responseRecords[this.questionIndexCurrent];
	}

}

function Question(presentation, responseCorrect)
{
	this.presentation = presentation;
	this.responseCorrect = responseCorrect;
}

function ResponseRecord()
{
	this.timesCorrect = 0;
}

</script>

</body>
</html>

This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s