-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mng 11 html quiz template #19
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ccc1e07
MNG-11 Add quiz template to index.html and create js file to render t…
daria305 a3a25b8
Update quiz template, add template for quiz answer
daria305 e557111
MNG-11 Create renderQuizPage and functions for question/mode-title up…
daria305 760c78a
MNG-11 Update for quizPage, add question/answers items functions
daria305 65e6656
MNG-11 Fiish rendering quiz questions
daria305 f1a1788
MNG-11 All finished before user selects the answer
daria305 ac162e2
Fix styles, to avoid cascading main page layout to the quizPage
daria305 aa9f04c
Fix styles to avoid cascading main page styles with quizApp id - afte…
daria305 3b22a25
MNG-11 Functions for selecting answers and checking the correctness
daria305 26eaa98
MNG-11 Questions are now changing, collect styles in appSettings
daria305 7a196e4
Update src/app/App.js change to arrow
daria305 367d8b9
Small fix for mode variable
daria305 f1694f0
Merge branch 'dev' into MNG-11-HTML-quiz-template
daria305 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ dist | |
.cache | ||
node_modules | ||
coverage | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// css styles dictionary changed during app runtime | ||
export const START_PAGE_STYLES = { | ||
startPageClass: "start-page" | ||
} | ||
|
||
export const QUIZ_PAGE_STYLES = { | ||
quizPageClass: "quiz-page", | ||
quizAnswerTextClass: "answer-text", | ||
quizAnswerImageClass: "answer-image", | ||
quizQuestionTextClass: "question-text", | ||
quizQuestionImageClass: "question-image", | ||
wrongAnswerClass: "wrong-answer", | ||
correctAnswerClass: "correct-answer", | ||
uncheckedClass: "unchecked" | ||
} | ||
|
||
export const TIMEOUT_AFTER_ANSWER_SELECTION = 1; //miliseconds | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import { | ||
QuestionService | ||
} from "../service/QuestionService.js" | ||
|
||
import { | ||
QUIZ_PAGE_STYLES, | ||
START_PAGE_STYLES, | ||
TIMEOUT_AFTER_ANSWER_SELECTION | ||
} from "./appSettings.js" | ||
|
||
// will be filledi with mode object during page rendering | ||
let CURRENT_MODE = null; | ||
let GENERATOR = null; | ||
|
||
// use to render the page for the first time, after the game start | ||
export function renderQuizPage(mode) { | ||
CURRENT_MODE = mode; | ||
|
||
const appScreen = document.querySelector('#pokequiz-app'); | ||
appScreen.classList.add(QUIZ_PAGE_STYLES.quizPageClass) | ||
appScreen.classList.remove(START_PAGE_STYLES.startPageClass) | ||
const quizTemplate = document.getElementById('quiz-template'); | ||
appScreen.innerHTML = quizTemplate.innerHTML; | ||
// TODO later - generate question using questionService - below are temporary dummy variables | ||
const generatedQuestion = { | ||
question: "quizQuestion", | ||
questionNum: 1, | ||
} | ||
setupPageTitle(CURRENT_MODE); | ||
//GENERATOR = new QuestionService.Generator() | ||
//TODO setupTimer() -- here or directly in App | ||
renderNextQuestion(CURRENT_MODE); | ||
} | ||
|
||
|
||
// use to update quizPage and change only the question, new answers and question counter | ||
// not changing the timer and bar | ||
// gent question generator and use generates next question if there is any left to answer | ||
// otherwise finishes the game and redirect user to the summary page | ||
export function renderNextQuestion(mode) { | ||
//genQuestion nie powinno być przekazywane do funkcji tylko powinno być tu wywoływana | ||
const genQuestion = getNextQuestion(mode); // TODO later pass generator and use generator.genQuestion(), and replace dummy function with real one, once it's implemented. Gonna be async | ||
if (genQuestion) { // some questions still left to answer | ||
const quizBody = document.querySelector("#quiz-body"); | ||
// Update question | ||
const quizQuestionElem = quizBody.querySelector(".quiz-question"); | ||
updateQuestion(quizQuestionElem, genQuestion.question, mode); | ||
// Update answers list | ||
const quizUl = quizBody.querySelector(".quiz-answers-list"); | ||
updateAnswersList(quizUl, genQuestion.question, mode); | ||
// Update question counter | ||
const questionCounter = document.querySelector("#question-counter"); | ||
updateQuestionCounter(questionCounter, genQuestion.questionNum); | ||
// listen for an answer selection | ||
const answersOptions = [...quizBody.querySelector(".quiz-answers-list").children] | ||
for (let option of answersOptions) { | ||
option.addEventListener("mouseup", function selectEventFunc() { | ||
selectAnswer(genQuestion.question, option.querySelector("div")); | ||
}) | ||
} | ||
} else { // no more questions left | ||
console.log("You WON!, but sorry, we still don't have any summary page"); // TODO create summary page redirection | ||
} | ||
} | ||
|
||
//TODO dummy function to be removed after generator is added | ||
const getNextQuestion = (mode) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. be aware of that this function is going to be async |
||
let q; | ||
if (mode.name == "WHO_IS_THAT_POKEMON") { | ||
q = { | ||
question: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png', | ||
answers: ['bulbasaur', 'ivysaur', 'venusaur', 'charmander', 'dummy1', 'dummy2'], | ||
correctAnswer: { | ||
name: 'bulbasaur', | ||
index: 1 | ||
} | ||
} | ||
} else if (mode.name == "WHAT_DOES_THIS_POKEMON_LOOK_LIKE") { | ||
q = { | ||
question: 'bulbasaur', | ||
answers: ['https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png', | ||
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/4.png', | ||
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/3.png', | ||
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/2.png' | ||
], | ||
correctAnswer: { | ||
name: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png', | ||
index: 1 | ||
} | ||
} | ||
} | ||
return { | ||
question: q, | ||
questionNum: 1, | ||
} | ||
} | ||
|
||
// Changes the title corresponding to the chosen game mode | ||
const setupPageTitle = (mode) => { | ||
const modeHeader = document.querySelector(".mode-title h2") | ||
modeHeader.innerText = mode.title // Setup mode title | ||
} | ||
|
||
// Updates the question div with styling and content depending on a type of a question | ||
const updateQuestion = (questionElement, questionSet, mode) => { | ||
if (mode.questionType === "image") { | ||
questionElement.classList.add(QUIZ_PAGE_STYLES.quizQuestionImageClass); | ||
const imgElem = createImgElement(questionSet.question); // add img from url | ||
questionElement.appendChild(imgElem); | ||
|
||
} else if (mode.questionType === "text") { | ||
questionElement.classList.add(QUIZ_PAGE_STYLES.quizQuestionTextClass); | ||
questionElement.innerText = questionSet.question; // add question as an inner text | ||
} | ||
} | ||
|
||
// Creates img element with a selected image url | ||
const createImgElement = (url) => { | ||
const img = document.createElement("img"); | ||
img.setAttribute("src", url); | ||
return img; | ||
} | ||
|
||
// Updates styles for question list based on mode type | ||
// creates question items sor provided question set | ||
const updateAnswersList = (answersElement, questionSet, mode) => { | ||
for (let answer of questionSet.answers) { | ||
const answerElement = createAnswerElement(answer, mode); | ||
answersElement.appendChild(answerElement); | ||
} | ||
} | ||
|
||
// returns children elements from the template | ||
// for template.content replacement, which is not fully supported yet | ||
const getTemplateContent = (template) => { | ||
const dummyDiv = document.createElement("div"); // | ||
dummyDiv.innerHTML = template.innerHTML; | ||
return dummyDiv.children | ||
} | ||
|
||
const createAnswerElement = (answer, mode) => { | ||
const liTemplate = document.querySelector("#quiz-li"); | ||
const li = getTemplateContent(liTemplate)[0]; | ||
const liFirstElem = li.children[0] | ||
|
||
if (mode.answerType === "image") { | ||
// first child of li receives an image | ||
liFirstElem.classList.add(QUIZ_PAGE_STYLES.quizAnswerImageClass) | ||
const imgElem = createImgElement(answer) // get img url | ||
liFirstElem.appendChild(imgElem) | ||
|
||
} else if (mode.answerType === "text") { | ||
// first child of li receives text | ||
liFirstElem.classList.add(QUIZ_PAGE_STYLES.quizAnswerTextClass) | ||
liFirstElem.innerText = answer // add question as an inner text | ||
} | ||
return li | ||
} | ||
|
||
// Updates the question number ona quiz page | ||
const updateQuestionCounter = (counterElem, questionNum) => { | ||
counterElem.innerText = String(questionNum).padStart(2, '0'); //TODO maybe - total num of question in a game mode | ||
} | ||
|
||
// fires up on mouse up event on answers list li, additionally accepts questionSet | ||
// check which answer was selected | ||
// eventHandler is element to which eventListener was attached to | ||
function selectAnswer(questionSet, eventHandler) { | ||
const answer = getAnswerFromElement(eventHandler); | ||
if (answer) { | ||
questionSet.correctAnswer.name === answer ? correctAnswerSelected(eventHandler) : wrongAnswerSelected(eventHandler); | ||
} else { | ||
throw new Error('Answer was not found') | ||
} | ||
} | ||
|
||
|
||
// Read selected answer value from clicked list item | ||
const getAnswerFromElement = (target) => { | ||
const targetClasses = [...target.classList]; | ||
let answer; | ||
if (targetClasses.includes(QUIZ_PAGE_STYLES.uncheckedClass)) { | ||
if (targetClasses.includes(QUIZ_PAGE_STYLES.quizAnswerTextClass)) { | ||
answer = target.innerText | ||
} else if (targetClasses.includes(QUIZ_PAGE_STYLES.quizAnswerImageClass)) { | ||
answer = target.children[0].getAttribute("src") | ||
} | ||
return answer | ||
} | ||
} | ||
|
||
const correctAnswerSelected = (selectedElem) => { | ||
console.log("yes") | ||
//TODO add correct-answer class and remove unchecked | ||
selectedElem.classList.remove(QUIZ_PAGE_STYLES.uncheckedClass) | ||
selectedElem.classList.add(QUIZ_PAGE_STYLES.correctAnswerClass) | ||
//TODO store results | ||
setTimeout(()=> { | ||
resetQuizAfterQuestion(); | ||
renderNextQuestion(CURRENT_MODE); | ||
}, TIMEOUT_AFTER_ANSWER_SELECTION) | ||
} | ||
|
||
const wrongAnswerSelected = (selectedElem) => { | ||
console.log("no") | ||
// add wrong-answer class and remove unchecked | ||
selectedElem.classList.remove(QUIZ_PAGE_STYLES.uncheckedClass) | ||
selectedElem.classList.add(QUIZ_PAGE_STYLES.wrongAnswerClass) | ||
//TODO store results | ||
setTimeout(()=> { | ||
resetQuizAfterQuestion(); | ||
renderNextQuestion(CURRENT_MODE); | ||
}, TIMEOUT_AFTER_ANSWER_SELECTION) | ||
} | ||
|
||
// removes question list items | ||
const resetQuizAfterQuestion = () => { | ||
const quizBody = document.getElementById('quiz-body'); | ||
const quizTemplate = document.getElementById('quiz-template'); | ||
quizBody.innerHTML = getTemplateContent(quizTemplate)[1].innerHTML // get the quiz body inner HTML from the template | ||
} | ||
// TODO check if any css class should be reset too | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mouseup? czemu nie click?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a, dobra, bo może ktoś by się w ostatniej chwili cofnął i jednak chciał ściągnąć myszkę z odpowiedzi. Make sense 😌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, that was the idea behind