-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
173 lines (145 loc) · 7.34 KB
/
Copy pathscript.js
File metadata and controls
173 lines (145 loc) · 7.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* get necessary already existing elements from DOM */
const quizOuter = document.querySelector('.quiz-outer');
const btnSubmit = document.querySelector('.submit');
const btnReset = document.querySelector('.reset');
const resultBox = document.querySelector('.results');
const headerBox = document.querySelector('.header');
function quizBuilder() {
questionsList.forEach( (question, index) => {
/* create elements to structure a card with quiz question, image, possible answers */
const quizInner = document.createElement('div');
const questionBox = document.createElement('div');
const imageBox = document.createElement('img');
const answersBoxList = document.createElement('ol');
quizOuter.appendChild(quizInner);
quizInner.appendChild(questionBox);
quizInner.appendChild(imageBox);
quizInner.appendChild(answersBoxList);
/* add class with styles to each quiz question card */
quizInner.setAttribute('class', 'quiz-inner');
/* destructure values to get question, image, answers from each question object in array */
const { questionText, questionImage, answersToQuestion, questionNumber } = question;
/* insert question and image to new elements */
questionBox.innerHTML= `<h4>Question ${questionNumber} of ${questionsList.length}</h4><p>${questionText}</p>`;
imageBox.src = questionImage;
/* get possible answers looping the question objects, and insert them to DOM */
for (letter in answersToQuestion) {
const answersBoxListItem = document.createElement('li');
answersBoxList.appendChild(answersBoxListItem);
const answer = answersToQuestion[letter];
answersBoxListItem.innerHTML = `<input type='radio' name='${questionNumber}' value='${letter}'
id='${questionNumber}${letter}'>
<label for='${questionNumber}${letter}'>${answer}</label>`
}
});
}
function markAnswered() {
/* get necessary dynamically created input elements from DOM */
const userInputsCollection = document.querySelectorAll('input[type="radio"]');
const userAnswersArray = Array.from(userInputsCollection);
/* add event listener to check which question is answered and change style */
userAnswersArray.forEach(element => {
element.addEventListener('click', () => {
element.parentElement.parentElement.parentElement.classList.add('answered');
});
});
}
function getUserResult() {
/* get necessary dynamically created input elements from DOM */
const userInputsCollection = document.querySelectorAll('input[type="radio"]');
const userAnswersArray = Array.from(userInputsCollection);
/* create object for each user to keep his/her answers */
const person = {};
/* add checked answers (based on checked input) with question numbers (based on input name equal to question number) to user object as properties */
userAnswersArray
.filter(element => {
return element.checked === true;
})
.forEach(element => person[element.name] = element.value);
/* create variables with arrays to store user good, bad and missing answers */
const goodAnswersArray = [];
const badAnswersArray = [];
const missingAnswersArray = [];
/* verify if user answered given question and add to good or bad answers array */
questionsList.forEach(element => {
if (person.hasOwnProperty(element.questionNumber)) {
if (person[element.questionNumber] == element.correct) {
goodAnswersArray.push(element.questionNumber);
} else {
badAnswersArray.push(element.questionNumber);
}
} else {
missingAnswersArray.push(element.questionNumber);
badAnswersArray.push(element.questionNumber);
}
});
/* change style to show good and bad answers without reference to user results */
const corrNumbersLetters = questionsList.map(element => {
return element.questionNumber + element.correct;
});
for (let i=0; i<userInputsCollection.length; i++) {
if (corrNumbersLetters.includes(userInputsCollection[i].id) === true) {
userInputsCollection[i].nextElementSibling.classList.add('good-answer');
} else {
userInputsCollection[i].nextElementSibling.classList.add('bad-answer');
}
}
/* change style to block possibility of changing answers at this stage */
for (let i=0; i<userInputsCollection.length; i++) {
userInputsCollection[i].setAttribute("disabled", "true");
}
/* show result box after check answers button is clicked */
resultBox.style.display='block';
/* show reset button after check answers button is clicked */
btnReset.style.display='block';
/* create personalized messages depending on level of score */
const messageStandard1 = `<h2>Your result is ${goodAnswersArray.length} / ${badAnswersArray.length + goodAnswersArray.length}.</h2>`;
const messageStandard2 = `<p>You responded to ${goodAnswersArray.length + badAnswersArray.length - missingAnswersArray.length} question(s) out of ${badAnswersArray.length + goodAnswersArray.length}. No answer was regarded as bad answer in your result.</p>`;
const messageStandard3 = `<p>See above to compare your answers with correct ones. If you want to try once more, please click reset button.</p>`;
const messageHigh = `${messageStandard1}
<p>Wow, this is impressive.</p>
${messageStandard2}${messageStandard3}`;
const messageMedium = `${messageStandard1}
<p>Not bad, but could be better.</p>
${messageStandard2}${messageStandard3}`;
const messageLow = `${messageStandard1}
<p>Disappointed? Well, many celebrities did not go above that score too.</p>
${messageStandard2}${messageStandard3}`;
/* check the level od user score: high, medium or low and insert proper message to DOM */
const ratio = goodAnswersArray.length / (badAnswersArray.length + goodAnswersArray.length);
if (ratio >= 0.7) {
resultBox.innerHTML = messageHigh;
} else if (ratio < 0.7 && ratio >= 0.5) {
resultBox.innerHTML = messageMedium;
} else {
resultBox.innerHTML = messageLow;
}
/* move user to let him/her see results */
resultBox.scrollIntoView();
}
function resetAnswers() {
/* get necessary dynamically created input elements from DOM */
const userInputsCollection = document.querySelectorAll('input[type="radio"]');
/* change style to unblock possibility of changing answers if reset was made */
for (let i=0; i<userInputsCollection.length; i++) {
userInputsCollection[i].removeAttribute("disabled");
}
/* hide reset button afer reset button is clicked */
btnReset.style.display='none';
/* remove style corresponding to user answers */
for (let i=0; i<userInputsCollection.length; i++) {
userInputsCollection[i].checked=false;
userInputsCollection[i].nextElementSibling.classList.remove('good-answer');
userInputsCollection[i].nextElementSibling.classList.remove('bad-answer');
userInputsCollection[i].parentElement.parentElement.parentElement.classList.remove('answered');
}
/* remove results from top page */
resultBox.style.display='none';
/* move user to top to start again */
headerBox.scrollIntoView();
}
/* execute functions and listen for further events */
quizBuilder();
markAnswered();
btnSubmit.addEventListener('click', getUserResult);
btnReset.addEventListener('click', resetAnswers);