diff options
| author | Camil Staps | 2016-05-09 21:27:00 +0200 | 
|---|---|---|
| committer | Camil Staps | 2016-05-09 21:27:00 +0200 | 
| commit | 9c84cb67d2b1537de440c1d1e623d86b5d171642 (patch) | |
| tree | 636109ecf23d190eb480287e24fa7df8295b1add /public | |
| parent | More help text (diff) | |
Buttons for answer input
Diffstat (limited to 'public')
| -rw-r--r-- | public/css/hebrewparsetrainer.css | 18 | ||||
| -rw-r--r-- | public/js/hebrewparsetrainer.js | 596 | 
2 files changed, 344 insertions, 270 deletions
| diff --git a/public/css/hebrewparsetrainer.css b/public/css/hebrewparsetrainer.css index 1776cf3..54f0c2d 100644 --- a/public/css/hebrewparsetrainer.css +++ b/public/css/hebrewparsetrainer.css @@ -16,23 +16,27 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  @font-face { -    font-family: 'Ezra SIL'; -    src: url('fonts/EzraSIL.ttf'); +	font-family: 'Ezra SIL'; +	src: url('fonts/EzraSIL.ttf');  }  #trainer-404 { -    display: none; -    padding: 15px; +	display: none; +	padding: 15px; +} + +#trainer-input-fancy { +	margin-bottom: 20px;  }  #trainer-input-help { -    display: none; +	display: none;  }  .hebrew { -    font-family: 'Ezra SIL', David; +	font-family: 'Ezra SIL', David;  }  .hebrew-large { -    font-size: 40px; +	font-size: 40px;  } diff --git a/public/js/hebrewparsetrainer.js b/public/js/hebrewparsetrainer.js index b453458..ea4e571 100644 --- a/public/js/hebrewparsetrainer.js +++ b/public/js/hebrewparsetrainer.js @@ -16,267 +16,337 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  $(document).ready(function(){ -    // http://stackoverflow.com/a/4399433/1544337 -    jQuery.fn.shake = function(intShakes, intDistance, intDuration) { -        this.each(function() { -            $(this).css("position","relative");  -            for (var x=1; x<=intShakes; x++) { -                $(this).animate({left:(intDistance*-1)}, (intDuration/intShakes)/4) -                        .animate({left:intDistance}, (intDuration/intShakes)/2) -                        .animate({left:0}, (intDuration/intShakes)/4); -            } -        }); -        return this; -    }; - -    var audio_positive = new Audio('public/audio/positive.wav'); -    var audio_negative = new Audio('public/audio/negative.wav'); - -    var correct_answers; -    var input_count = 0; -    var checked = false; - -    function addInput() { -        input_count++; -        var html = "<div class='row trainer-input'>\ -                        <div class='col-md-8'>\ -                            <div class='form-group'>\ -                                <label for='trainer-input-"+input_count+"'>Parse:</label>\ -                                <input type='text' class='form-control' id='trainer-input-"+input_count+"' placeholder='Q pf 3ms' spellcheck='false'/>\ -                            </div>\ -                        </div>\ -                        <div class='col-md-4'>\ -                            <div class='form-group'>\ -                                <label for='trainer-parsed-"+input_count+"'>Interpreted as:</label>\ -                                <input type='text' class='form-control' id='trainer-parsed-"+input_count+"' readonly='readonly'/>\ -                            </div>\ -                        </div>\ -                    </div>"; -        $('#trainer-input-container').append(html); - -        $('#trainer-input-'+input_count).keyup(function(e){ -            if (e.keyCode == 13) { -                if (!checked) { -                    checked = checkInput(); -                } else { -                    reloadVerb(); -                    $(this) -                        .val('') -                        .css({backgroundColor:'transparent'}) -                        .parent().removeClass('has-error has-success'); -                    checked = false; -                } -            } else { -                $(this) -                    .css({backgroundColor:'transparent'}) -                    .parent().removeClass('has-error has-success'); -                checked = false; -                processInput(); -            } -        }).focus(); -    } - -    function removeInputs() { -        $('.trainer-input').remove(); -        input_count = 0; -    } - -    function reloadVerb() { -        $('#trainer-404').hide(); -        $('#trainer-verb').css({color: 'gray'}); -        $('#trainer-answer').text(''); -        removeInputs(); - -        var stems = $('input[name="stem"]:checked').map(function(){return this.value;}); -        var tenses = $('input[name="tense"]:checked').map(function(){return this.value;}); -        var roots = $('input[name="root"]:checked').map(function(){return this.value;}); - -        $.ajax('verb/random/', { -            data: { -                stem: $.makeArray(stems).join(), -                tense: $.makeArray(tenses).join(), -                root: $.makeArray(roots).join() -            }, -            dataType: 'json', -            error: function(jqxhr, status, error) { -                $('#trainer-404').fadeIn(); -            }, -            success: function(data, status, jqxhr) { -                $('#trainer-verb').text(data.verb.verb).css({color: 'black'}); - -                correct_answers = []; -                for (var i in data.answers) { -                    var answer = { -                        stem: data.answers[i].stem, -                        tense: data.answers[i].tense, -                        person: data.answers[i].person, -                        gender: data.answers[i].gender, -                        number: data.answers[i].number -                    }; -                    correct_answers.push(answer); -                } - -                addInput(); -            } -        }); -    } - -    var stems = []; -    var tenses = []; -    var tenses_abbr = []; - -    function findStem(stem) { -        var stems_ = stems.filter(function(s){return s.toLowerCase().indexOf(stem.toLowerCase()) == 0;}); -        if (stems_.length == 1) -            return stems_[0]; -    } - -    function findTense(tense) { -        if (tenses.indexOf(tense) != -1) -            return tense; -        if (tenses_abbr.indexOf(tense) != -1) -            return tenses[tenses_abbr.indexOf(tense)]; -    } - -    function parseAnswer(parsing) { -        var persons = ['1', '2', '3', null]; -        var genders = ['m', 'f', 'c', null]; -        var numbers = ['s', 'p', null]; - -        var re = /^\s*(\w+)\s+(\w+)(?:\s+(?:([123])\s*)?([mf])\s*([sp])\s*)?$/; -        var match = parsing.match(re); -        if (match == null) -            return false; - -        var stem = findStem(match[1]); -        var tense = findTense(match[2]); -        var person = match[3] ? match[3] : null; -        var gender = match[4] ? match[4] : null; -        var number = match[5] ? match[5] : null; - -        if (typeof stem === 'undefined' || typeof tense === 'undefined' || $.inArray(person, persons) == -1 || -                $.inArray(gender, genders) == -1 || $.inArray(number, numbers) == -1) -            return false; - -        if (tense.indexOf('infinitive') == 0 && (person != null || gender != null || number != null)) -            return false; -        if (tense.indexOf('infinitive') != 0) { -            if (gender == null || number == null) -                return false; -            if (tense.indexOf('participle') == 0 && person != null) -                return false; -            if (tense.indexOf('participle') != 0 && person == null) -                return false; -        } - -        return { -            stem: stem, -            tense: tense, -            person: person, -            gender: gender, -            number: number -        }; -    } -     -    function parsingToString(parsing, extended) { -        var genders = { -            'm': 'masculine', -            'f': 'feminine' -        }; -        var numbers = { -            's': 'singular', -            'p': 'plural' -        }; -        if (extended === true) { -            return parsing.stem + ' ' + parsing.tense +  -                    (parsing.person ? (' ' + parsing.person) : '') + -                    (parsing.gender ? (' ' + genders[parsing.gender]) : '') +  -                    (parsing.number ? (' ' + numbers[parsing.number]) : ''); -        } else { -            return parsing.stem + ' ' + parsing.tense +  -                    (parsing.person ? (' ' + parsing.person) : '') +  -                    (parsing.gender ? (' ' + parsing.gender) : '') +  -                    (parsing.number ? (' ' + parsing.number) : ''); -        } -    } - -    function processInput() { -        var input = $('#trainer-input-' + input_count); -        var answer = parseAnswer(input.val()); -        if (answer === false) { -            input.parent().addClass('has-error'); -            $('#trainer-parsed-' + input_count).val('Parsing error'); -        } else { -            input.parent().removeClass('has-error'); -            $('#trainer-parsed-' + input_count).val(parsingToString(answer, true)); -        } -        return answer; -    } - -    function checkInput() { -        var answer = processInput(); -        if (!answer && $('#trainer-input-'+input_count).val() != '') { -            $('#trainer-input-'+input_count).shake(2, 12, 300); -            return false; -        } - -        for (var i in correct_answers) { -            var correct_answer = correct_answers[i]; -            if (JSON.stringify(answer) == JSON.stringify(correct_answer)) { -                $('#trainer-input-'+input_count) -                    .css({backgroundColor: '#dff0d8'}) -                    .parent().addClass('has-success'); -                if ($('#settings-audio').prop('checked')) audio_positive.play(); - -                correct_answers.splice(i,1); -                if (correct_answers.length > 0) { -                    addInput(); -                    return false; -                } else { -                    return true; -                } -            } -        } - -        $('#trainer-input-'+input_count) -            .css({backgroundColor: '#f2dede'}) -            .parent().addClass('has-error'); -        if ($('#settings-audio').prop('checked')) audio_negative.play(); -        $('#trainer-answer').text(' - ' + correct_answers.map(parsingToString).join(', ')); - -        return true; -    } - -    function init() { -        $.ajax('stem/', { -            dataType: 'json', -            success: function(data, status, jqxhr) { -                stems = data.map(function(d){return d.name;}); -            } -        }); - -        $.ajax('tense/', { -            dataType: 'json', -            success: function(data, status, jqxhr) { -                tenses = data.map(function(d){return d.name;}); -                tenses_abbr = data.map(function(d){return d.abbreviation;}); -            } -        }); - -        reloadVerb(); -    } - -    $('#hebrewparsetrainer-settings input.reload-verb').change(function(){ -        reloadVerb(); -    }); - -    var help_shown = false; -    $('#show-hide-help').click(function(){ -        help_shown = !help_shown; -        $('#trainer-input-help').slideToggle(); -        $(this).text((help_shown ? 'Hide' : 'Show') + ' help'); -        $('#trainer-input-'+input_count).focus(); -    }); - -    init(); +	// http://stackoverflow.com/a/4399433/1544337 +	jQuery.fn.shake = function(intShakes, intDistance, intDuration) { +		this.each(function() { +			$(this).css("position","relative"); +			for (var x=1; x<=intShakes; x++) { +				$(this).animate({left:(intDistance*-1)}, (intDuration/intShakes)/4) +						.animate({left:intDistance}, (intDuration/intShakes)/2) +						.animate({left:0}, (intDuration/intShakes)/4); +			} +		}); +		return this; +	}; + +	var audio_positive = new Audio('public/audio/positive.wav'); +	var audio_negative = new Audio('public/audio/negative.wav'); + +	var correct_answers; +	var input_count = 0; +	var checked = false; + +		function stepFancyInput(step) { +			$('#trainer-input-fancy').html(''); +			var buts = {}; +			switch (step) { +				case 0: +					buts = { 'Q ':   'Qal' +					       , 'Hip ': 'Hiphil' +					       , 'Ho ':  'Hophal' +					       , 'Ni ':  'Niphal' +					       , 'Pi ':  'Piel' +					       , 'Pu ':  'Pual' +					       , 'Hit ': 'Hitpael' +					}; break; +				case 1: +					buts = { 'pf ':	'Pf.' +					       , 'ipf ':   'Ipf.' +					       , 'coh ':   'Coh.' +					       , 'imp ':   'Imp.' +					       , 'ius ':   'Ius.' +					       , 'infcs':  'Inf. cs.' +					       , 'infabs': 'Inf. abs.' +					       , 'pta ':   'Part. act.' +					       , 'ptp ':   'Part. pass.' +					}; break; +				case 2: +					buts = { '1': '1', '2': '2', '3': '3', '': 'N/A' }; break; +				case 3: +					buts = { 'm': 'Masculine', 'f': 'Feminine', '': 'N/A' }; break; +				case 4: +					buts = { 's': 'Singular', 'p': 'Plural', '': 'N/A' }; break; +			} + +			for (k in buts) { +				var but = $('<button></button>'); +				but.addClass('btn btn-default').attr('role', 'button'); +				but.text(buts[k]).val(k); +				but.click(function(){ +					var ip = $('#trainer-input-'+input_count); +					ip.val(ip.val() + $(this).val()).focus(); +					if (step < 4) { +						stepFancyInput(step + 1); +					} else { +						var done = checkInput(true); +						if ($('#trainer-input-'+input_count).parent().hasClass('has-error')) { +							if (done) { +								var next = $('<button></button>'); +								next.addClass('btn btn-warning').attr('role', 'button'); +								next.text('Next'); +								next.click(reloadVerb); +								$('#trainer-input-fancy').html(next); +							} else { +								var skip = $('<button></button>'); +								skip.addClass('btn btn-warning').attr('role', 'button'); +								skip.text('Skip'); +								skip.click(reloadVerb); +								$('#trainer-input-fancy').append(skip); +							} +						} +					} +				}); + +				$('#trainer-input-fancy').append(but).append(' '); +			} +		} + +	function addInput() { +		input_count++; +		var html = "<div class='row trainer-input'>\ +						<div class='col-md-8'>\ +							<div class='form-group'>\ +								<label for='trainer-input-"+input_count+"'>Parse:</label>\ +								<input type='text' class='form-control' id='trainer-input-"+input_count+"' placeholder='Q pf 3ms' spellcheck='false'/>\ +							</div>\ +						</div>\ +						<div class='col-md-4'>\ +							<div class='form-group'>\ +								<label for='trainer-parsed-"+input_count+"'>Interpreted as:</label>\ +								<input type='text' class='form-control' id='trainer-parsed-"+input_count+"' readonly='readonly'/>\ +							</div>\ +						</div>\ +					</div>"; +		$('#trainer-input-container').append(html); + +		$('#trainer-input-'+input_count).keyup(function(e){ +			if (e.keyCode == 13) { +				if (!checked) { +					checked = checkInput(false); +				} else { +					reloadVerb(); +					$(this) +						.val('') +						.css({backgroundColor:'transparent'}) +						.parent().removeClass('has-error has-success'); +					checked = false; +				} +			} else { +				$(this) +					.css({backgroundColor:'transparent'}) +					.parent().removeClass('has-error has-success'); +				checked = false; +				processInput(); +			} +		}).focus(); + +		stepFancyInput(0); +	} + +	function removeInputs() { +		$('.trainer-input').remove(); +		input_count = 0; +	} + +	function reloadVerb() { +		$('#trainer-404').hide(); +		$('#trainer-verb').css({color: 'gray'}); +		$('#trainer-answer').text(''); +		removeInputs(); + +		var stems = $('input[name="stem"]:checked').map(function(){return this.value;}); +		var tenses = $('input[name="tense"]:checked').map(function(){return this.value;}); +		var roots = $('input[name="root"]:checked').map(function(){return this.value;}); + +		$.ajax('verb/random/', { +			data: { +				stem: $.makeArray(stems).join(), +				tense: $.makeArray(tenses).join(), +				root: $.makeArray(roots).join() +			}, +			dataType: 'json', +			error: function(jqxhr, status, error) { +				$('#trainer-404').fadeIn(); +			}, +			success: function(data, status, jqxhr) { +				$('#trainer-verb').text(data.verb.verb).css({color: 'black'}); + +				correct_answers = []; +				for (var i in data.answers) { +					var answer = { +						stem: data.answers[i].stem, +						tense: data.answers[i].tense, +						person: data.answers[i].person, +						gender: data.answers[i].gender, +						number: data.answers[i].number +					}; +					correct_answers.push(answer); +				} + +				addInput(); +			} +		}); +	} + +	var stems = []; +	var tenses = []; +	var tenses_abbr = []; + +	function findStem(stem) { +		var stems_ = stems.filter(function(s){return s.toLowerCase().indexOf(stem.toLowerCase()) == 0;}); +		if (stems_.length == 1) +			return stems_[0]; +	} + +	function findTense(tense) { +		if (tenses.indexOf(tense) != -1) +			return tense; +		if (tenses_abbr.indexOf(tense) != -1) +			return tenses[tenses_abbr.indexOf(tense)]; +	} + +	function parseAnswer(parsing) { +		var persons = ['1', '2', '3', null]; +		var genders = ['m', 'f', 'c', null]; +		var numbers = ['s', 'p', null]; + +		var re = /^\s*(\w+)\s+(\w+)(?:\s+(?:([123])\s*)?([mf])\s*([sp])\s*)?$/; +		var match = parsing.match(re); +		if (match == null) +			return false; + +		var stem = findStem(match[1]); +		var tense = findTense(match[2]); +		var person = match[3] ? match[3] : null; +		var gender = match[4] ? match[4] : null; +		var number = match[5] ? match[5] : null; + +		if (typeof stem === 'undefined' || typeof tense === 'undefined' || $.inArray(person, persons) == -1 || +				$.inArray(gender, genders) == -1 || $.inArray(number, numbers) == -1) +			return false; + +		if (tense.indexOf('infinitive') == 0 && (person != null || gender != null || number != null)) +			return false; +		if (tense.indexOf('infinitive') != 0) { +			if (gender == null || number == null) +				return false; +			if (tense.indexOf('participle') == 0 && person != null) +				return false; +			if (tense.indexOf('participle') != 0 && person == null) +				return false; +		} + +		return { +			stem: stem, +			tense: tense, +			person: person, +			gender: gender, +			number: number +		}; +	} + +	function parsingToString(parsing, extended) { +		var genders = { +			'm': 'masculine', +			'f': 'feminine' +		}; +		var numbers = { +			's': 'singular', +			'p': 'plural' +		}; +		if (extended === true) { +			return parsing.stem + ' ' + parsing.tense + +					(parsing.person ? (' ' + parsing.person) : '') + +					(parsing.gender ? (' ' + genders[parsing.gender]) : '') + +					(parsing.number ? (' ' + numbers[parsing.number]) : ''); +		} else { +			return parsing.stem + ' ' + parsing.tense + +					(parsing.person ? (' ' + parsing.person) : '') + +					(parsing.gender ? (' ' + parsing.gender) : '') + +					(parsing.number ? (' ' + parsing.number) : ''); +		} +	} + +	function processInput() { +		var input = $('#trainer-input-' + input_count); +		var answer = parseAnswer(input.val()); +		if (answer === false) { +			input.parent().addClass('has-error'); +			$('#trainer-parsed-' + input_count).val('Parsing error'); +		} else { +			input.parent().removeClass('has-error'); +			$('#trainer-parsed-' + input_count).val(parsingToString(answer, true)); +		} +		return answer; +	} + +	function checkInput(reload) { +		var answer = processInput(); +		if (!answer && $('#trainer-input-'+input_count).val() != '') { +			$('#trainer-input-'+input_count).shake(2, 12, 300); +			return false; +		} + +		for (var i in correct_answers) { +			var correct_answer = correct_answers[i]; +			if (JSON.stringify(answer) == JSON.stringify(correct_answer)) { +				$('#trainer-input-'+input_count) +					.css({backgroundColor: '#dff0d8'}) +					.parent().addClass('has-success'); +				if ($('#settings-audio').prop('checked')) audio_positive.play(); + +				correct_answers.splice(i,1); +				if (correct_answers.length > 0) { +					addInput(); +					return false; +				} else { +					if (reload === true) { +						window.setTimeout(reloadVerb, 600); +					} +					return true; +				} +			} +		} + +		$('#trainer-input-'+input_count) +			.css({backgroundColor: '#f2dede'}) +			.parent().addClass('has-error'); +		if ($('#settings-audio').prop('checked')) audio_negative.play(); +		$('#trainer-answer').text(' - ' + correct_answers.map(parsingToString).join(', ')); + +		return true; +	} + +	function init() { +		$.ajax('stem/', { +			dataType: 'json', +			success: function(data, status, jqxhr) { +				stems = data.map(function(d){return d.name;}); +			} +		}); + +		$.ajax('tense/', { +			dataType: 'json', +			success: function(data, status, jqxhr) { +				tenses = data.map(function(d){return d.name;}); +				tenses_abbr = data.map(function(d){return d.abbreviation;}); +			} +		}); + +		reloadVerb(); +	} + +	$('#hebrewparsetrainer-settings input.reload-verb').change(function(){ +		reloadVerb(); +	}); + +	var help_shown = false; +	$('#show-hide-help').click(function(){ +		help_shown = !help_shown; +		$('#trainer-input-help').slideToggle(); +		$(this).text((help_shown ? 'Hide' : 'Show') + ' help'); +		$('#trainer-input-'+input_count).focus(); +	}); + +	init();  }); | 
