durfdoen-2.0/layouts/quiz.erb

218 lines
5.8 KiB
Text
Raw Normal View History

2020-09-06 20:41:54 +02:00
<div>
2020-08-28 22:36:50 +02:00
<% @items.find_all("/quiz/*").each_with_index do |quest, i| %>
<div id="question_<%=i+1%>" class="question hidden">
<%= render '/partials/question.*', question: quest, number: i.to_s %>
2020-03-19 22:24:54 +01:00
</div>
2020-08-28 22:36:50 +02:00
<% end %>
</div>
2020-09-14 21:33:13 +02:00
<div class="hidden">
<h3> Deze verenigingen kan je eens uitchecken ;) </h3>
<div id="resultWrapper">
</div>
2020-08-28 22:36:50 +02:00
</div>
<div class="buttons">
2020-09-14 20:58:52 +02:00
<div>
<button id="previousButton" onclick="goPrevious()">
Vorige
</button>
</div>
<div>
<button id="nextButton" onclick="goNext()">
Volgende
</button>
</div>
2020-03-19 22:24:54 +01:00
</div>
2020-03-11 00:04:27 +01:00
<script>
2020-09-14 21:33:13 +02:00
Array.prototype.stableSort = function(cmp) {
cmp = !!cmp ? cmp : (a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
};
let stabilizedThis = this.map((el, index) => [el, index]);
let stableCmp = (a, b) => {
let order = cmp(a[0], b[0]);
if (order != 0) return order;
return a[1] - b[1];
}
stabilizedThis.sort(stableCmp);
for (let i=0; i<this.length; i++) {
this[i] = stabilizedThis[i][0];
}
return this;
}
2020-09-14 22:27:46 +02:00
Array.prototype.sortByKey = function(key) {
return this.sort(function(a, b) {
var x = key(a); var y = key(b);
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}
const _results = <%= to_partials(all_groups()) %>;
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
// This keeps the state of the current question/result
// So navigating between questions works without reload
const state = {
'question': {
'index': 0,
'id': "",
'element': undefined
},
'answers': {},
'allQuestions': document.getElementsByClassName("question"),
};
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
var depth = 0;
const previousButton = document.getElementById("previousButton");
const nextButton = document.getElementById("nextButton");
const resultWrapper = document.getElementById("resultWrapper");
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
function reset() {
const params = getParams();
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
state.question.index = 'vraag' in params ? parseInt(params['vraag']) : 1;
state.question.id = "question_"+state.question.index;
state.question.element = document.getElementById(state.question.id);
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
state.answers = {};
2020-09-10 00:28:10 +02:00
2020-09-14 22:54:14 +02:00
// Hide all subquestions
for(let form of [...document.querySelectorAll(`[id^="${state.question.index - 1}#"]`)]) {
form.style.display = "none";
// The vraag2 -> politiek -> Vlaamse en nationale politiek div wasn't set to none, because of the more complicated id.
form.querySelectorAll(".question_wrapper").forEach(e => e.style.display = "none");
}
// Set checked to false for everything in this question
for(let form of [...document.querySelectorAll(`[id^="${state.question.index - 1}"][id$="form"]`)]) {
[...form.elements].filter(e => e.nodeName == "INPUT").forEach(e => e.checked = false);
}
2020-08-28 23:48:27 +02:00
save_state();
showCorrectElements();
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
function getParams() {
const url = window.location.search;
if(!url) return {};
const paramsBuilder = {};
for(let currentVar of url.substring(1).split("&")) {
var pair = currentVar.split('=');
paramsBuilder[pair[0]] = decodeURIComponent(pair[1]);
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
return paramsBuilder;
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
function createRelativeUrl(newQuestionIndex) {
return window.location.pathname + "?vraag="+newQuestionIndex;
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
function showCorrectElements() {
// This part resets to the original state;
for(let question of state.allQuestions) {
question.classList.add("hidden");
}
2020-09-14 21:33:13 +02:00
resultWrapper.parentNode.classList.add("hidden");
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
if(state.question.index == 1) {
2020-09-14 20:58:52 +02:00
previousButton.style.display = "none";
2020-08-28 23:48:27 +02:00
} else {
2020-09-14 20:58:52 +02:00
previousButton.style.display = "";
2020-08-28 23:48:27 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
if(!state.question.element) {
2020-09-14 20:58:52 +02:00
nextButton.style.display = "none";
2020-09-14 21:33:13 +02:00
resultWrapper.parentNode.classList.remove("hidden");
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
const result = {};
2020-08-28 23:48:27 +02:00
for(let question of state.allQuestions) {
2020-08-28 22:36:50 +02:00
const div = window.sessionStorage[question.id];
2020-09-14 20:58:52 +02:00
if(!div) {
console.log("You didn't answer question "+question.id)
continue;
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
const resultObj = JSON.parse(div);
for (let key in resultObj) {
if (!(key in result)) result[key] = 0;
result[key] += resultObj[key];
2020-03-19 22:24:54 +01:00
}
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
show_result(result);
} else {
2020-09-14 20:58:52 +02:00
nextButton.style.display = "";
2020-08-28 23:48:27 +02:00
state.question.element.classList.remove("hidden");
}
2020-08-28 23:48:27 +02:00
};
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function save_answers(vers) {
2020-08-28 23:48:27 +02:00
for (let ver of vers) {
if (state.answers[ver]) {
state.answers[ver] += 1;
} else {
state.answers[ver] = 1;
2020-08-28 22:36:50 +02:00
}
2020-08-28 23:48:27 +02:00
}
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function del_answers(vers) {
for (let ver of vers) {
2020-08-28 23:48:27 +02:00
state.answers[ver] -= 1;
2020-08-28 22:36:50 +02:00
}
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function show_result(result) {
2020-09-14 21:33:13 +02:00
while (resultWrapper.lastElementChild) {
resultWrapper.removeChild(resultWrapper.lastElementChild);
}
2020-09-14 21:33:13 +02:00
2020-09-14 22:31:31 +02:00
for (let [ver, val] of Object.entries(result).sortByKey(([k1, v1]) => k1).stableSort(([k1, v1], [k2, v2]) => v2 - v1)) {
2020-09-14 20:58:52 +02:00
if(!(ver in _results)) {
console.error("No html found for '"+ver+"'");
continue;
}
2020-09-14 21:33:13 +02:00
2020-09-14 22:27:46 +02:00
if(!val) continue;
2020-09-14 20:58:52 +02:00
const create_wrapper= document.createElement('div');
create_wrapper.innerHTML = _results[ver];
2020-09-14 21:33:13 +02:00
create_wrapper.style.order = val;
resultWrapper.appendChild(create_wrapper);
}
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function save_state() {
2020-08-28 23:48:27 +02:00
window.sessionStorage.setItem(state.question.id, JSON.stringify(state.answers));
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function goNext() {
2020-08-28 23:48:27 +02:00
window.history.pushState("object or string", "", createRelativeUrl(state.question.index + 1));
depth += 1;
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
reset();
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 22:36:50 +02:00
function goPrevious() {
2020-08-28 23:48:27 +02:00
if(depth > 1) {
depth -= 1;
window.history.replaceState("", "", createRelativeUrl(state.question.index - 1));
2020-09-14 20:58:52 +02:00
} else {
window.location.search = "vraag="+ (state.question.index - 1);
2020-08-28 23:48:27 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
reset();
2020-08-28 22:36:50 +02:00
}
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
window.addEventListener("popstate", e => {
e.preventDefault();
goPrevious();
});
2020-09-10 00:28:10 +02:00
2020-08-28 23:48:27 +02:00
reset();
2020-03-11 00:04:27 +01:00
</script>
2020-02-27 21:45:34 +01:00
<%= yield %>