diff --git a/index.html b/index.html index 18cb74a..e1d9810 100644 --- a/index.html +++ b/index.html @@ -7,25 +7,76 @@ + +
+

Coding Quiz

+

Please select the topics you are interested in: +

+ +

+
+ + + +

+ + + + + + + + + + + + + + + -

+ + -

- - + + + \ No newline at end of file diff --git a/main.css b/main.css index 0ccc64d..28cdb9e 100644 --- a/main.css +++ b/main.css @@ -1,13 +1,91 @@ +body { + + background-color: peachpuff; +} + +body, html { + font-family: sans-serif; +} + +/*YES I KNOW...BAD FOR ACCESBILITY BUT I. DONT. CARE. */ +textarea, select, input, button { outline: none; } + +.quizSelect { + padding: 5vw; + background-color: rgb(238, 215, 113); + margin: 20px 15px 30px 15px; + border-radius: 8px; + -webkit-box-shadow: 0px 4px 38px 1px rgba(0,0,0,0.22); + -moz-box-shadow: 0px 4px 38px 1px rgba(0,0,0,0.22); + box-shadow: 0px 4px 38px 1px rgba(0,0,0,0.22); +} + +.title { + letter-spacing: -1px; +} + +.title span { + font-weight: 100; +} + +#topics{ + margin: 2px 0; + color: grey; +} button { -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.4s; width: 60px; - height: 32px; - -} - -button:hover { + height: 42px; + font-size: .8rem; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 1px; + border-radius: 90px; + min-width: 130px; + padding-left: 20px; + padding-right: 20px; + } + + button:hover { background-color: #4CAF50; color: white; + } + + .correct { + color: #4CAF50 + } + + .incorrect { + color: red + } + + .response { + font-weight: bold; + } + + #score { + color: green; + } + + .answerChoice { + cursor: pointer; + } + + .topicList { + padding-left: 0px; + } + + .topicList input { + margin: 8px; + } + + input[type=checkbox] { + /* Double-sized Checkboxes */ + -ms-transform: scale(1.5); /* IE */ + -moz-transform: scale(1.5); /* FF */ + -webkit-transform: scale(1.5); /* Safari and Chrome */ + -o-transform: scale(1.5); /* Opera */ + padding: 15px; } \ No newline at end of file diff --git a/main.js b/main.js index 841782f..1d16849 100644 --- a/main.js +++ b/main.js @@ -1,28 +1,37 @@ //=============GLOBAL VARIABLES DECLARATION & ASSIGNMENT============ //creating an array that stores the questions for the topic 'functions' let quizBank= []; -//console.log(quizBank); +//counts the number of questions we ask, starting at zero for an array +let counter = 0; +//tracks index of the quizBank array +let index=0; +// create varibales that stores an array boolean values (true or false) when user clicks on answer choice +let correctAnswerChosen = 0; +let incorrectAnswerChosen = 0; + +let testBank = []; //assigning my HTLML element to a variable that holds the spot for the question -let questionsAppear = document.getElementById('populateQuestions') +let questionsAppear = document.getElementsByClassName('populateQuestions'); //assigning my HTML elements with attribute class to a variable that will hold the list of answer choice. -let answersAppear = document.getElementsByClassName('answerChoice') -console.log(answersAppear) +let answersAppear = document.getElementsByClassName('answerChoice'); //creating a variable that will hold the HTML element which displays response to user after they click -let responseAppear = document.getElementById('response') +let responseAppear = document.getElementsByClassName('response'); -//creating a variable that will hold the index that will track which questions we ar on -let index=0; +let quizElement = document.getElementById('quiz'); -// creating a varibale that stores an array boolean values (true) when user clicks on correct choice -let correctAnswerChosen = []; -console.log(correctAnswerChosen); +let elTopic1 = document.getElementById('functions') +let elTopic2 = document.getElementById('loops') +let elTopic3 = document.getElementById('objects') +let elTopic4 = document.getElementById('DOM') +let elTopic5 = document.getElementById('localStorage') +let elSubmitTopic = document.getElementById('dataSubmit'); -// creating a varibale that stores an array boolean values (false) when user clicks on incorrect choice -let incorrectAnswerChosen = []; -console.log(incorrectAnswerChosen); +//create a next button +let buttonHolder = document.getElementById('buttonHolder'); +let questionButton= document.createElement('button'); //===========OBJECT CONSTRUCTOR & INSTANCES============ @@ -31,7 +40,6 @@ let Question = function(topic, question, answerOptions, userResponse, questionRe { this.topic = topic, this.question = question, - // this.userAnswers = userAnswers -- //answerOptions will be an array this.answerOptions = answerOptions, this.correctAnswer = this.answerOptions[0], @@ -41,96 +49,262 @@ let Question = function(topic, question, answerOptions, userResponse, questionRe this.questionResult = questionResult; } -q01= new Question('Functions', 'JS does not execute a code block in a function unless the function is________?', ['invoke','define','construct','declare'], null, null); -q02= new Question('Functions', ' An invoked function is the________ thing the JS interpreter executes when a page loads.', [' first','final','second','third'], null, null); +if(localStorage.questObject) { + quizBank = JSON.parse(localStorage.getItem("questObject")) +} + +else { + + +q01 = new Question('functions', 'To execute the code block in a function, we do what?', ['Invoke the function','Define the function','Construct the function','Declare the function'], null, null) ; + +q02 = new Question('functions', 'An invoked function is the ________ thing the JavaScript interpreter executes when a page loads.', [' first','final','second','third'], null, null) ; + +q03 = new Question('functions', 'Functions take _______ to return a value?', ['parameters', 'objects', 'objectives', 'variables'], null, null) ; + +q04 = new Question('functions', 'Functions are known as _______ of the object?', ['methods', 'parameters', 'values', 'variables'], null, null) ; + +q05 = new Question('functions', 'In a function expression, what is omitted?', ['The name', 'The interpreter', 'The value', 'The method'], null, null) ; + +q11 = new Question('loops', 'Which of the following is not a loop type?', ['do for', 'do while', 'for', 'while'], null, null) ; + +q12 = new Question('loops', 'Loops check a ______?', ['condition', 'variable', 'function', 'method'], null, null) ; + +q13 = new Question('loops', 'If "5" === 5, it returns a ____ value?', ['false', 'true', 'null', 'NaN'], null, null) ; +q14 = new Question('loops', 'If the length of an array is 6, which of the following' + 'for loop' + 'is correct?', ['for (let i=0; i<6; i++)', 'for(let i=1; i>6; i++)', 'for(let i=0; i>5); i++', 'for(let i=1; i>6; i+-)'], null, null) ; +q15 = new Question('loops', 'What is the differenct between a ' + 'for loop' + ' and a ' + 'while loop' + '?', ['a ' + 'for loop' + ' runs a code a specific number of times and a ' + 'while loop' + ' is used when you do not know the code should run' , 'no difference', 'while loop' + ' is less common', 'for loop' + ' is widely used'], null, null) ; + +q21 = new Question('objects', 'In an object, variables become known as _______?', ['properties', 'scripts', 'keys', 'values'], null, null) ; + +q22 = new Question('objects', 'In an object, functions become known as _______?', ['methods', 'scripts', 'keys', 'values'], null, null) ; + +q23 = new Question('objects', 'An object constructor provides what main advantage?', ['Multiple instantiations', 'A single instantiation', 'Defined keys', 'Defined values'], null, null) ; + +q24 = new Question('objects', 'What will ' + 'math.round()' + ' change 4.39 to?', ['4', '4.5', '5', '4.8'], null, null) ; + +q25 = new Question('objects', 'How do you delete the property ' + 'pool' + ' from this object: let house = {windows:12, rooms:2, pool:1};', ['delete house.pool', 'delete pool.1', 'delete pool', 'delete pool.house'], null, null) ; + + +q31 = new Question('DOM', 'The DOM specifies the way in which a page is modeled using a _______?', ['DOM tree', 'DOM chart', 'DOM score', 'DOM loop'], null, null) ; + +q32 = new Question('DOM', 'The DOM is ________?', ['neither part of HTML, nor part of JavaScript', 'part of HTML, and part of JavaScript', 'part of HTML, but not part of JavaScript', 'not part of HTML, but part of JavaScript'], null, null) ; + +q33 = new Question('DOM', 'To access the DOM, you start by looking for ______?', ['elements', 'documents', 'attributes', 'text'], null, null) ; + +q34 = new Question('DOM', 'Methods that find elements in the DOM are called what?', ['DOM queries', 'Node queries', 'Element queries', 'Attribute queries'], null, null) ; + +q35 = new Question('DOM', 'A collection of nodes is known as a _______?', ['nodeList', 'nodeArray', 'nodeQuery', 'nodeScript'], null, null) ; + +q41 = new Question('localStorage', 'The value in a storage object is always a _______.', ['string','boolean', 'number', 'variable'], null, null) ; +q42 = new Question('localStorage', 'When saving an item into local storage, what comes after' + ' localStorage.setItem' +'?', ["('weight', '15')","'weight', '15'", "('weight', 15)", "(weight, '15')"], null, null) ; +q43 = new Question('localStorage', 'If ' + 'age' + ' is a key, how can we retrieve its value on console?', ['getItem(age)','getItem.age', 'getItem[age]', 'itemGet()'], null, null) ; +q44 = new Question('localStorage', 'How do you remove stored items from your browser?', ['localStorage.clear()','clear.localStorage', 'clear()', 'local.storage.clear()'], null, null) ; +q45 = new Question('localStorage', "How do you remove this key/value pair: 'color','blue'?", ["removeItem('color')",'remove.color', "removeItem('color',12)", 'removeItem.color.blue'], null, null) ; //pushing the questions of the function questions objects into an array that holds all the questions for the function topic -quizBank.push(q01,q02); -console.log(quizBank); +testBank.push(q01, q02, q03, q04, q05, q11, q12, q13, q14, q15, q21, q22, q23, q24, q25, q31, q32, q33, q34, q35, q41, q42, q43,q44,q45); +} //=========Index for tracking what questions we are on=============== //The "index" variable, declared above, will keep track of what question we are on, and we will pass this variable whereever we need to pass an index to the questions array function indexFunc() { - for(let i=0; i < quizBank.length; i++){ - index = Math.floor(Math.random() * quizBank.length); - } + index = Math.floor(Math.random() * quizBank.length); return index; } +function randomAnswer() { + aIndex = Math.floor(Math.random() * quizBank[index].answerOptions.length); + return aIndex; +} + //=====POPULATING DOM DYNAMICALLY===== //creating a function that populates question on the html page let questionPopulate= function(){ - // Zach mentioned it is better not to run a for loop here. Only run a for loop if we wanted all the questions to populate at once on the page. Since we want the user to answer one question at at time before the next one shows then it is better to access the "questions" propoerty of the questions object using the index of that object in the array. - index = indexFunc(); - questionsAppear.innerText = quizBank[index].question; -} + index = indexFunc(); -questionPopulate(); + let newQuestion = document.createElement('p'); + quizElement.appendChild(newQuestion); + newQuestion.setAttribute('class', 'populateQuestions'); + + //prevents repeated questions + while (quizBank[index].displayed) { + index = indexFunc(); + } + questionsAppear[counter].innerHTML = (counter + 1) + ". " + quizBank[index].question; + quizBank[index].displayed = true; + //questionsAppear = document.getElementsByClassName('populateQuestions'); +} //Placeholder for creating a function to randomize the answer options each time they appear (not part of the MVP) //creating a function that will populate the "answer options" property let answerChoices = function(){ - //since "answerAppear" was assigned a class name, then we can use it as an array. class attribute acts an array. - for (let i=0; i < answersAppear.length; i++){ - answersAppear[i].innerText= quizBank[index].answerOptions[i]; + //create an ordered list + let newAnswerChoices = document.createElement('ol'); + quizElement.appendChild(newAnswerChoices); + newAnswerChoices.setAttribute('class', 'answerChoice'); + newAnswerChoices.setAttribute('type', 'a'); + + let answerArray = []; + + //append list items + for (let i=0; i < quizBank[index].answerOptions.length; i++){ + let newAnswer = document.createElement('li'); + newAnswerChoices.appendChild(newAnswer); + newAnswer.setAttribute('class', 'answerChoice'); + + let j = randomAnswer(); + + for (let k = 0; k < answerArray.length; k++) { + while (j == answerArray[k]) { + j = randomAnswer(); + } + } + answerArray.push(j); + newAnswer.innerText = quizBank[index].answerOptions[j]; } + + //for (let i=0; i < answersAppear.length; i++){ + // answersAppear[i].innerText= quizBank[index].answerOptions[i]; + //} +} + + +// then attach an event handler + +let topicChoice1 = function(e) { + for (z = 0; z < testBank.length; z++) { + if (document.getElementById('functions').id === testBank[z].topic) { + quizBank.push(testBank[z]) + } + } +} + +let topicChoice2 = function(e) { + for (z = 0; z < testBank.length; z++) { + if (document.getElementById('loops').id === testBank[z].topic) { + quizBank.push(testBank[z]) + } + } +} + +let topicChoice3 = function(e) { + for (z = 0; z < testBank.length; z++) { + if (document.getElementById('objects').id === testBank[z].topic) { + quizBank.push(testBank[z]) + } + } +} + +let topicChoice4 = function(e) { + for (z = 0; z < testBank.length; z++) { + if (document.getElementById('DOM').id === testBank[z].topic) { + quizBank.push(testBank[z]) + } + } +} + +let topicChoice5 = function(e) { + for (z = 0; z < testBank.length; z++) { + if (document.getElementById('localStorage').id === testBank[z].topic) { + quizBank.push(testBank[z]) + } + } +} + +let topicSubmit = function(e) { + questionPopulate(); + answerChoices(); + answerEventFunc(); } -answerChoices(); //==========FUNCTIONS FOR EVENT HANDLERS ================ //Function that will give the response "correct" when the correct choice is clicked + score property (boolean) let responseCheck = function(){ - console.log("user response = " + quizBank[index].userResponse); - console.log("correct answer = " + quizBank[index].correctAnswer); - + let response = document.createElement('p'); + response.setAttribute('class', 'response'); + quizElement.appendChild(response); + responseAppear = document.getElementsByClassName('response'); + if (quizBank[index].userResponse === quizBank[index].correctAnswer){ - responseAppear.innerText = "Correct"; + response.setAttribute('style', 'color: green'); + responseAppear[counter].innerText = "Correct"; quizBank[index].result = true; + correctAnswerChosen++; } + else { - responseAppear.innerText = "Incorrect"; + response.setAttribute('style', 'color: red'); + responseAppear[counter].innerText = "Incorrect"; quizBank[index].result = false; + incorrectAnswerChosen++; } //if there are no more questions to be asked, do not display the "next" button - if (counter < quizBank.length){ - let buttonHolder = document.getElementById('buttonHolder'); - let questionButton= document.createElement('button'); + if (counter < (quizBank.length - 1)) { buttonHolder.appendChild(questionButton); - questionButton.innerText = 'Next Question'; + questionButton.innerText = 'Next Question'; } + //else remove the next button + else { + buttonHolder.removeChild(questionButton); + let elScore = document.getElementById('score'); + elScore.innerHTML = "Score: " + correctAnswerChosen + " / " + (correctAnswerChosen + incorrectAnswerChosen); + } } -//function for not allowing the user to choose an answer more than once. The placement of this may be off, just because at this point of reading the script, you have not gotten to the event yet. -let oneChoice =function(){ - answersAppear[0].removeEventListener('click',clicked) - answersAppear[1].removeEventListener('click',clicked) - answersAppear[2].removeEventListener('click',clicked) - answersAppear[3].removeEventListener('click',clicked) -} - -//========EVENT HANDLERS======= - -//Event handler for correct response - let clicked = function(e) { quizBank[index].userResponse = e.target.innerHTML; responseCheck(); - oneChoice(); + removeEventFunc(); +} + +let nextClicked = function (e) { + counter++; + + questionPopulate(); + answerChoices(); + answerEventFunc(); } //==============FIRING EVENTS + EXECUTION=============== // creating an code to run when the event click is fired in my HTML -answersAppear[0].addEventListener('click',clicked); -answersAppear[1].addEventListener('click',clicked); -answersAppear[2].addEventListener('click',clicked); -answersAppear[3].addEventListener('click',clicked); +let answerEventFunc = function() { + for(let i= (counter * 4); i < answersAppear.length; i++){ + answersAppear[i].addEventListener('click', clicked); + } +} -// //creating a code to run the next question in the array when the click "Next question" button is clicked +let removeEventFunc = function() { + for(let i= (counter * 4); i < answersAppear.length; i++){ + answersAppear[i].removeEventListener('click', clicked); + } +} +questionButton.addEventListener('click', nextClicked) + + + +// attach event listeners to topics +elTopic1.addEventListener('click', topicChoice1); +elTopic2.addEventListener('click', topicChoice2); +elTopic3.addEventListener('click', topicChoice3); +elTopic4.addEventListener('click', topicChoice4); +elTopic5.addEventListener('click', topicChoice5); +elSubmitTopic.addEventListener('click', topicSubmit); + +if (quizBank.length != 0){ + questionPopulate(); + answerChoices(); +answerEventFunc(); + +} + +localStorage.setItem("questObject", JSON.stringify(quizBank)) + +console.log(quizBank);