var questions = questions || null; //Array.prototype.shuffle = function(local){ // var a = this; // var newArray = typeof local === "boolean" && local ? this : []; // for (var i = 0, newIdx, curr, next; i < a.length; i++){ // newIdx = Math.floor(Math.random()*i); // curr = a[i]; // next = a[newIdx]; // newArray[i] = next; // newArray[newIdx] = curr; // } // // return newArray; //}; function shuffleArray(d) { for (var c = d.length - 1; c > 0; c--) { var b = Math.floor(Math.random() * (c + 1)); var a = d[c]; d[c] = d[b]; d[b] = a; } return d }; function initPage(evt) { if (questions != null ) { initQuestions(); } initPopups(); } function initQuestions() { for (var key in questions) { var container = document.getElementById(key); var question = questions[key]; if (!container || !question ) continue; initQuestion(question); var form = getNextVariants(question); container.querySelector(".content").innerHTML = form; } } function initQuestion(question) { if (question.variants) question.variants = shuffleArray(question.variants); question.position = -1; } function getNextVariants(question) { question.correct = []; question.correctAnswers = []; var out = []; for (var i = 0; i < question.count; i++) { var index = -1; var variant = ""; if (question.variants) { index = (++question.position % question.variants.length); variant = question.variants[index]; } if (question.type == "v" ) { var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*[,\|]\s*/); var text = ""; variant = variant.replace(elem, text); } if (variant.indexOf("|") > 0) { var vals2 = variant.split("|"); question.feedback = vals2[1]; variant = vals2[0]; } out.push("
") out.push(variant); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "vf" ) { // roletka s feedbackem var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*[,\|]\s*/); var text = ""; variant = variant.replace(elem, text); } out.push("

") out.push(variant); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "vc" ) { // vyber z roletky s danym seznamem spolecnym pro vsechny varianty var text = "" + variant[0] +" – "; out.push("

") out.push(text); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "select_word" ) { // vyber slova ve vete, vyber z roletky s danym seznamem spolecnym pro vsechny varianty var words = variant.split(/\s+/g); var sentence = [] for (var j = 0; j < words.length; j++) { var word = words[j]; var affix = ""; if (endsWith( word, ".,;?!")) { affix = word.charAt(word.length-1); word = word.substring(0, word.length-1); } if (word.startsWith("{")) { var parts = word.replace(/[\{\}]/g, "").split(/\|/) parts.push(j); // pidani indexu slova - na pozici 3 parts[1] = parts[1].split("/"); question.correct.push(parts); console.log(parts[0] + " - " + parts[2] + " - " + question.options[parts[2]]) question.correctAnswers.push(question.options[parts[2]]); word = parts[0]; } else { question.correct.push(""); question.correctAnswers.push(""); } if (word == "-" && word == "–") { sentence.push(word); } else { sentence.push("" + word + "" + affix); } } var text = "

" + sentence.join(" ") + "
"; out.push("
") out.push(text); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "th" ) { var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*\|\s*/); var textLength = "" + Math.ceil(vals[1].length*1) + "em"; var text = "(" + vals[0]+ ") "; var cors = vals[1].split(/\//); trimValues(cors); question.correct.push(cors); text += ""; variant = variant.replace(elem, text); } out.push("

") out.push(variant); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "thf" ) { var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*\|\s*/); var textLength = "" + Math.ceil(vals[1].length*0.65) + "em"; var text = "(" + vals[0]+ ") "; var cors = vals[1].split(/\//); trimValues(cors); question.correct.push(cors); question.feedback = vals[2]; text += ""; variant = variant.replace(elem, text) + "

"; } out.push("
") out.push(variant); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "tf" ) { var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*\/\s*/); var textLength = "" + Math.ceil(vals[0].length*0.65) + "em"; if (question.textLength) { textLength = question.textLength; } var text = " "; trimValues(vals); question.correct.push(vals); text += ""; variant = variant.replace(elem, text); } out.push("

") out.push(variant); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "tff" ) { // fill text + feedback (examples etc.) var parts = variant.split(/\s*\|\s*/); if (parts.length < 2) break; question.feedback = parts[1]; variant = parts[0]; var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*\/\s*/); var textLength = "" + Math.ceil(vals[0].length*0.65) + "em"; if (question.textLength) { textLength = question.textLength; } if (textLength == "0em") textLength = "8em"; var text = " "; trimValues(vals); question.correct.push(vals); text += ""; variant = variant.replace(elem, text); } out.push("

") out.push(variant); out.push("
"); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "fillin" ) { var rndIndex = Math.floor(variant.length*Math.random()); if (variant[rndIndex][0] == "-") { rndIndex += (Math.random() > 0.5) ? -1 : 1; } var text = question.template; for (var i = 0; i < variant.length; i++ ) { var item = variant[i].join("/") if (i != rndIndex) { item = ""; question.correctAnswers.push(variant[i]); } text = text.replace("{T" + (i+1) + "}", item); } out.push("

") out.push(text); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "translate" ) { var elems = variant.match(/\{([^}]+)\}/g); for (var j = 0; j < elems.length; j++) { var elem = elems[j] var vals = elem.substring(1, elem.length-1).trim().split(/\s*[\|]\s*/); trimValues(vals); var text = "

" + vals[0] +"

" + vals[1] + "
"; variant = variant.replace(elem, text); } out.push("
") out.push(variant); out.push("
"); out.push("

" + templates.nexter + "

"); } if (question.type == "division" ) { var divider = templates.divider; var sels = [""] for (var j = 0; j < question.options.length; j++) { var qopt = question.options[j]; var opt = templates.divOption.replace("{TEXT}", qopt).replace("{VALUE}", qopt); sels.push(opt); } divider = divider.replace("{OPTIONS}", sels.join("")); out.push("

"); var state = "letter"; var letterCount = 0; question.correctAnswers = []; question.plainText = "" var correctText = ""; var correctPos = 0; var word = variant.substring(0, variant.indexOf("|")).trim(); question.feedback = variant.substring(variant.indexOf("|")+1).trim(); for (var j = 0; j < word.length; j++) { var char = word.charAt(j); if (state == "letter" && char != "{") { letterCount++; var qid = "div_" + i + "_" + letterCount; out.push(divider.replace(/\{QID\}/g, qid)); out.push("" + char + ""); //state = "letter"; question.plainText += char; continue; } if (state == "letter" && char == "{") { state = "option"; correctPos = letterCount; correctText = ""; continue; } if (state == "option" && char != "}") { correctText += char; continue; } if (state == "option" && char == "}") { question.correctAnswers.push([correctPos, correctText]); console.log(question.correctAnswers) correctText = ""; state = "letter" continue; } } out.push("
"); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "sortf" ) { // tahaci trideni + feedback out.push("

"); out.push("
"); question.items = {} var groups = []; var dragitems = []; for (var j = 0; j < question.groups.length; j++) { var grp = question.groups[j]; var shuffled = shuffleArray(grp.variants); groups.push("
"); groups.push("

" + grp.label + "

"); groups.push("
"); groups.push("
"); for (var k = 0; k < question.varcount; k++) { // var item = shuffled[k]; var parts = item.split("|") var iid = question.id + "_" + j + "_" + k question.items[iid] = { group: j, feedback: parts[1]} dragitems.push("" + parts[0] + ""); } } out = out.concat(shuffleArray(dragitems)); out.push("
"); out = out.concat(groups); out.push("
"); out.push("

" + templates.checker + "

"); } if (question.type == "dragf" ) { // tahaci vkladani do textu out.push("

"); out.push("
"); shuffleArray(question.options); for (var j = 0; j < question.options.length; j++) { var iid = question.id + "_" + j; out.push("" + question.options[j] + ""); } out.push("
"); //konec dragbase shuffleArray(question.variants); for (var j = 0; j < question.variants.length; j++) { var variant2 = question.variants[j]; var elems = variant2.match(/\{([^}]+)\}/g); for (var k = 0; k < elems.length; k++) { var elem = elems[k] var val = elem.substring(1, elem.length-1).trim(); var text = ""; question.correctAnswers.push([val]); variant2 = variant2.replace(elem, text); out.push("

" + variant2 + "

") } } out.push("
"); out.push("

" + templates.checker + "

"); } } return out.join(""); } function endsWith(text, endChars) { for (var i = 0; i < endChars.length; i++) { if (text.endsWith(endChars.charAt(i)) ) { return true; } } return false; } function toggleWord(elem) { var index = elem.getAttribute("data-index"); if (elem.classList.contains("selected")) { var table = elem.parentNode.parentNode.querySelector("table[data-index=\"" + index + "\"]"); if (table) { table.parentNode.removeChild(table); } } else { var results = elem.parentNode.parentNode.querySelector(".results"); if (results) { var qid = elem.parentNode.parentNode.parentNode.parentNode.id; var options = questions[qid].options; var sel = "" var text = ""; text += "" text += "" text += "" results.innerHTML += text } } elem.classList.toggle("selected") } function toggleDivider(select) { var sels = select.parentNode.parentNode.querySelectorAll(":checked + label + select"); for (var i = 0; i < sels.length; i++) { sels[i].className = "level" + (i % 2 + 1) } } function trimValues(arr) { for (var k = 0; k < arr.length; k++) { arr[k] = arr[k].trim(); } } function toggleSolution(input) { var solution = input.parentNode; solution.classList.toggle("shown") } var templates = { "th": "
{CONTENT}
", "v": "
{CONTENT}
", "divider": "", "divOption": "", checker: "", nexter: "" } function checkQuestion(checker) { var form = checker.parentNode.parentNode.parentNode; var qid = form.id; if (qid == "") return; var question = questions[qid]; switch (question.type) { case "v": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; var sel = elem.querySelector("select"); var fb = elem.querySelector(".feedback"); sel.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); if (sel.value == "---") continue; var fbComment = question.feedback || ""; if (sel.value == question.correct[i]) { fb.innerHTML = " " + fbComment; elem.classList.add("correct"); } else { fb.innerHTML = "(*" + question.correctAnswers[i] + ") " + fbComment; elem.classList.add("wrong"); } } break; case "vc": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; var sel = elem.querySelector("select"); var fb = elem.querySelector(".feedback"); sel.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); if (sel.value == "---") continue; var fbComment = question.feedback || ""; if (sel.value == question.correct[i]) { fb.innerHTML = ""; elem.classList.add("correct"); } else { fb.innerHTML = "(*" + question.correctAnswers[i] + ") " + fbComment; elem.classList.add("wrong"); } } break; case "tf": case "th": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; var input = elem.querySelector("input"); var fb = elem.querySelector(".feedback"); input.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); if (input.value == "") continue; var isCorrect = false; for (var j = 0; j < question.correct[i].length; j++) { if (input.value == question.correct[i][j]) { isCorrect = true; } } if (isCorrect) { fb.innerHTML = "" elem.classList.add("correct"); } else { fb.innerHTML = "(*" + question.correct[i].join("/") + ")" elem.classList.add("wrong"); } } break; case "fillin": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; checkText(elem, question.correctAnswers[i]); } break; case "tff": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; var input = elem.querySelector("input"); var fb = elem.querySelector(".feedback"); input.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); var isCorrect = false; for (var j = 0; j < question.correct[i].length; j++) { if (input.value == question.correct[i][j]) { isCorrect = true; } } if (input.value == "" && !isCorrect) continue; if (isCorrect) { fb.innerHTML = "" elem.classList.add("correct"); } else { fb.innerHTML = "(*" + question.correct[i].join("/") + ")" elem.classList.add("wrong"); } } var examples = elems[0].parentNode.querySelector(".examples"); if (examples) examples.innerHTML = question.feedback; break; case "thf": var elems = form.querySelectorAll(".testelement"); for (var i = 0; i < elems.length; i++) { var elem = elems[i]; var input = elem.querySelector("input"); var fb = elem.querySelector(".feedback"); input.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); if (input.value == "") continue; var isCorrect = false; for (var j = 0; j < question.correct[i].length; j++) { if (input.value == question.correct[i][j]) { isCorrect = true; } } var feedback = ""; var feedback2 = "" + question.feedback + "" if (isCorrect) { feedback = "" + feedback elem.classList.add("correct"); } else { feedback = "(*" + question.correct[i].join("/") + ")" + feedback elem.classList.add("wrong"); } fb.innerHTML = feedback; var fb2 = elem.parentNode.querySelector(".fb2"); if (fb2) { fb2.innerHTML = feedback2; } } break; case "select_word": var words = form.querySelectorAll(".word"); for (var i = 0; i< words.length; i++) { var word = words[i]; var windex = word.getAttribute("data-index"); word.onclick = null; if (word.classList.contains("selected")) { var table = form.querySelector(".result[data-index=\"" + windex + "\"]") var correct = question.correct[i]; var correctOption = question.correctAnswers[i]; if (correct != "") { word.classList.add("correct"); correct.push(true); var tds = table.querySelectorAll("td"); checkText(tds[1], correct[1]); checkSelect(tds[2], correct[2], correctOption); } else { word.classList.add("wrong"); table.classList.add("wrong"); } } } for (var i = 0; i < question.correct.length; i++) { var cor = question.correct[i]; if (cor.length > 0 && cor.length < 5) { /* var text = "
Slovo:" + elem.innerHTML +"
1. p. j. č.:
Род и тип" + sel +"
"; text += "" text += "" text += "
Slovo:" + cor[0] +"
1. p. j. č.:" + cor[1] + "
Род и тип" + question.correctAnswers[i] +"
" */ var div = form.querySelector(".results"); var table = addChild(div, "table", "result missed"); var tbody = addChild(table, "tbody"); var tr = addChild(tbody, "tr"); var th = addChild(tr, "th"); th.innerHTML = "Slovo:"; var td = addChild(tr, "td"); td.innerHTML = cor[0]; tr = addChild(tbody, "tr"); th = addChild(tr, "th"); th.innerHTML = "1. p. j. č.:"; td = addChild(tr, "td"); td.innerHTML = cor[1]; tr = addChild(tbody, "tr"); th = addChild(tr, "th"); th.innerHTML = "Род и тип:"; td = addChild(tr, "td"); td.innerHTML = question.correctAnswers[i]; words[i].classList.add("missed"); } } break; case "division": var text = question.plainText; var out = ""; var row1 = "", row2 = ""; for (var i = 0; i < question.correctAnswers.length; i++) { var answer = question.correctAnswers[i]; row1 += "" var start = answer[0]; if (i < question.correctAnswers.length-1) { row2 += "" } else { row2 += "" } } out += row1 + "" + row2 + "
" + answer[1] + "" + text.substring(answer[0], question.correctAnswers[i+1][0]) + "" + text.substring(answer[0]) + "
"; out += "

" + question.feedback + "

"; var fb = form.querySelector(".feedback"); if (fb) fb.innerHTML = out; break; case "dragf": var drops = form.querySelectorAll(".droparea-fill"); for (var i = 0; i < drops.length; i++) { var drop = drops[i]; drop.ondragend = null; var item = drop.querySelector(".dragitem"); if (item) { item.ondrag = null; checkText(item, question.correctAnswers[i]); } } break; case "sortf": var drops = form.querySelectorAll(".droparea"); isEmpty = true; for (var i = 0; i < drops.length; i++) { if (drops[i].querySelectorAll(".dragitem").length > 0) { isEmpty = false; } } if (isEmpty) { break; } for (var i = 0; i < drops.length; i++) { var items = drops[i].querySelectorAll(".dragitem"); for (var j = 0; j < items.length; j++) { var item = items[j]; var iid = item.id; var fb = item.querySelector(".feedback"); var fb_content = ""; if (i == question.items[iid].group) { fb_content = "" item.classList.add("correct"); } else { fb_content = ""; item.classList.add("wrong"); } fb_content += " " + question.items[iid].feedback + "" fb.innerHTML = fb_content; } } } var toolbar = form.querySelector(".toolbar"); if (toolbar) { toolbar.innerHTML = templates.nexter; } } function checkText(elem, correct) { console.log(elem) var input = elem.querySelector("input"); var val = ""; if (input) { val = input.value.trim(); val = val.replace(/\s+/g, " ") } if (elem.classList.contains("dragitem")) { input = elem.firstChild; val = input.nodeValue.trim(); } if (val == "") return; var fb = elem.querySelector(".feedback"); //input.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); var isCorrect = false; for (var j = 0; j < correct.length; j++) { if (val == correct[j]) { isCorrect = true; } } var feedback = ""; if (isCorrect) { feedback = "" + feedback elem.classList.add("correct"); } else { feedback = " (*" + correct.join("/") + ")" elem.classList.add("wrong"); } fb.innerHTML = feedback; } function checkSelect(elem, correct, correctAnswer) { var sel = elem.querySelector("select"); var fb = elem.querySelector(".feedback"); //sel.disabled = true; fb.innerHTML = ""; elem.classList.remove("correct"); elem.classList.remove("wrong"); //if (sel.value == "---") return; var fbComment = ""; if (sel.value == correct) { fb.innerHTML = ""; elem.classList.add("correct"); } else { fb.innerHTML = " (*" + correctAnswer + ") " + fbComment; elem.classList.add("wrong"); } } function createNextForm(nexter) { var content = nexter.parentNode.parentNode; var form = content.parentNode; var question = questions[form.id]; content.innerHTML = getNextVariants(question); } function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("text", ev.currentTarget.id); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); ev.currentTarget.appendChild(document.getElementById(data)); } function togglePopup (evt) { var icon = evt.currentTarget; var popup = icon.parentNode; if (popup.classList.contains("shown")) { popup.setAttribute("title", "Close popup") } else { popup.setAttribute("title", "Show popup") } popup.classList.toggle("shown") } function closePopup(evt) { var popup = evt.currentTarget.parentNode.parentNode; popup.classList.remove("shown"); } function initPopups() { var pops = document.querySelectorAll(".popup"); for (var i = 0; i < pops.length; i++) { var pop = pops[i]; var content = pop.innerHTML; pop.innerHTML = ""; var icon = pop.appendChild(document.createElement("span")); icon.className = "popup-icon"; icon.addEventListener("click", togglePopup); var cont = pop.appendChild(document.createElement("span")); cont.className = "popup-content"; cont.innerHTML = content; var closer = cont.appendChild(document.createElement("span")); closer.className = "closer"; closer.innerHTML = "×"; closer.addEventListener("click", closePopup); } } function addChild(parent, childName, childClass) { var child = parent.appendChild(document.createElement(childName)); if (childClass != undefined) { child.className = childClass; } return child; } window.addEventListener("load", initPage);