Allow the user to see the correct solution if he is stuck

Closes #4
This commit is contained in:
Lukas Fürderer 2020-09-03 14:46:59 +02:00
parent 8a578e44ed
commit fc7f630001
3 changed files with 73 additions and 9 deletions

View File

@ -21,7 +21,11 @@
</div> </div>
<template v-for="(elem, row) in solution"> <template v-for="(elem, row) in solution">
<div class="row"> <div class="row">
<div v-for="(idx, column) in elem.idx" class="card" v-bind:class="{incorrect: column == store.section && incorrects[row]}"> <div
v-for="(idx, column) in elem.idx"
class="card"
v-bind:class="{incorrect: column == store.section && incorrects[row], revealed: column == store.section && elem.got_revealed}"
>
<span>{{ solution_text(elem, column) }}</span> <span>{{ solution_text(elem, column) }}</span>
<svg width=20 height=20 v-if="column == store.section && !solution_correct" v-on:click="remove_solution(row)"> <svg width=20 height=20 v-if="column == store.section && !solution_correct" v-on:click="remove_solution(row)">
<path d="M2 2L18 18M18 2L2 18" stroke="#f00" stroke-width="2px" /> <path d="M2 2L18 18M18 2L2 18" stroke="#f00" stroke-width="2px" />
@ -40,8 +44,9 @@
</div> </div>
<div class="description"> <div class="description">
<div class="helptext" v-if="!all_inserted || correction_visible">{{ helptext }}</div> <div class="helptext" v-if="!all_inserted || correction_visible">{{ helptext }}</div>
<button v-if="revealing_text != null" v-on:click="reveal_solution">{{ revealing_text }}</button> <button v-if="revealing_text != null" v-on:click="show_correction">{{ revealing_text }}</button>
<button v-if="next_column_text != null" v-on:click="open_next_column">{{ next_column_text }}</button> <button v-if="next_column_text != null" v-on:click="open_next_column">{{ next_column_text }}</button>
<button v-if="correction_visible && !solution_correct && !solution_revealed" v-on:click="reveal_solution">Lösung aufdecken</button>
</div> </div>
<div class="close_button" v-on:click="is_open = false"> <div class="close_button" v-on:click="is_open = false">
<svg width="30" height="30"> <svg width="30" height="30">

View File

@ -91,6 +91,9 @@ body {
#quiz .card.incorrect { #quiz .card.incorrect {
background-color: #faa; background-color: #faa;
} }
#quiz .card.revealed {
background-color: #7e6;
}
#quiz .solution { #quiz .solution {
overflow-y: auto; overflow-y: auto;

70
quiz.js
View File

@ -192,12 +192,21 @@ var app = new Vue({
helptext: function() { helptext: function() {
if (this.correction_visible) { if (this.correction_visible) {
if (this.solution_correct) { if (this.solution_correct) {
return [ if (this.solution_revealed) {
"Perfekt! Die Reihenfolge ist korrekt.", return [
"Super! Alle Bedeutungen sind korrekt eingeordnet.", "Schau dir die Reihenfolge genau an. Elemente die zuvor nicht korrekt einsortiert waren, sind nun grün markiert.",
"Sehr gut! Die biblischen Bezüge sind alle korrekt zugeordnet.", "Alle Bedeutungen sind jetzt am richtigen Platz. Die Bedeutungen die zuvor nicht korrekt zugeordnet waren, sind grün markiert.",
"Gut gemacht! Die Ministrantendienste sind alle passend zugeordnet.\nDu hast das Quiz nun erfolgreich abgeschlossen.", "Die biblichen Bezüge sind nun zugeordnet. Bezüge die zuvor nicht korrekt platziert waren, sind grün markiert.",
][this.store.section]; "Die Ministrantendienste sind nun am richtigen Platz. Was zuvor nicht korrekt zugeordnet war, ist grün markiert.\nDu hast es geschafft! Das Quiz ist nun zu Ende.",
][this.store.section];
} else {
return [
"Perfekt! Die Reihenfolge ist korrekt.",
"Super! Alle Bedeutungen sind korrekt eingeordnet.",
"Sehr gut! Die biblischen Bezüge sind alle korrekt zugeordnet.",
"Gut gemacht! Die Ministrantendienste sind alle passend zugeordnet.\nDu hast es geschafft! Das Quiz ist nun zu Ende.",
][this.store.section];
}
} else if (this.store.section == 0) { } else if (this.store.section == 0) {
return "Die Reihenfolge passt leider noch nicht ganz. Falsch eingeordnete Elemente sind rot markiert. Entferne diese mit einem Klick auf das rote X und füge sie neu ein, bis die Reihenfolge stimmt."; return "Die Reihenfolge passt leider noch nicht ganz. Falsch eingeordnete Elemente sind rot markiert. Entferne diese mit einem Klick auf das rote X und füge sie neu ein, bis die Reihenfolge stimmt.";
} else { } else {
@ -296,6 +305,9 @@ var app = new Vue({
} }
return reduced_list; return reduced_list;
}, },
solution_revealed: function() {
return this.solution.some(elem => elem.got_revealed);
},
}, },
methods: { methods: {
store_text: function(idx) { store_text: function(idx) {
@ -308,6 +320,7 @@ var app = new Vue({
if (this.solution.length == 0) { if (this.solution.length == 0) {
this.solution.push({ this.solution.push({
idx: [i], idx: [i],
got_revealed: false,
}); });
} else if (i == this.store.selected) { } else if (i == this.store.selected) {
this.store.selected = null; this.store.selected = null;
@ -321,6 +334,7 @@ var app = new Vue({
insert_front: function() { insert_front: function() {
this.solution.splice(0, 0, { this.solution.splice(0, 0, {
idx: [this.store.selected], idx: [this.store.selected],
got_revealed: false,
}); });
this.store.selected = null; this.store.selected = null;
}, },
@ -334,6 +348,7 @@ var app = new Vue({
insert_after: function(elem) { insert_after: function(elem) {
this.solution.splice(this.find_solution(elem)+1, 0, { this.solution.splice(this.find_solution(elem)+1, 0, {
idx: [this.store.selected], idx: [this.store.selected],
got_revealed: false,
}); });
this.store.selected = null; this.store.selected = null;
}, },
@ -344,7 +359,7 @@ var app = new Vue({
this.solution[row_idx].idx.pop(); this.solution[row_idx].idx.pop();
} }
}, },
reveal_solution: function() { show_correction: function() {
this.correction_visible = true; this.correction_visible = true;
}, },
open_next_column: function() { open_next_column: function() {
@ -352,10 +367,51 @@ var app = new Vue({
this.store.selected = null; this.store.selected = null;
this.store.items = shuffle_cards(this.store.section); this.store.items = shuffle_cards(this.store.section);
this.correction_visible = false; this.correction_visible = false;
this.solution.forEach(elem => {
elem.got_revealed = false;
});
}, },
add_card_to: function(row) { add_card_to: function(row) {
this.solution[row].idx.push(this.store.selected); this.solution[row].idx.push(this.store.selected);
this.store.selected = null; this.store.selected = null;
}, },
reveal_solution: function() {
if (this.store.section == 0) {
// remove wrong elements
let incorrect_rows = [];
this.incorrects.forEach((incorrect, i) => {
if (incorrect) {
incorrect_rows.push(i);
}
});
incorrect_rows.reverse().forEach(rowNum => {
this.solution.splice(rowNum, 1);
});
// insert missing elements and mark them as 'got_revealed'
for (let i=0; i<cards_content[0].length; i++) {
if (this.solution.length <= i || this.solution[i].idx[0] != i) {
this.solution.splice(i, 0, {
idx: [i],
got_revealed: true,
});
}
}
} else {
this.solution.forEach((elem, i) => {
let card_inserted = elem.idx.length > this.store.section;
let card_needed = cards_content[this.store.section][i] != null;
if (!card_inserted && card_needed) {
elem.idx.push(i);
elem.got_revealed = true;
} else if (card_inserted && !card_needed) {
elem.idx.splice(this.store.section, 1);
} else if (card_inserted && card_needed && elem.idx[this.store.section] != i) {
Vue.set(elem.idx, this.store.section, i);
elem.got_revealed = true;
}
});
}
},
}, },
}); });