I'm trying to access and delete the child in a div generated when I press the "submit" button, the individual divs inside will be generated because there are some functions running with the click, but when I press refresh to delete them nothing happened.
For more clarification here's the src: https://github.com/espnal/wdd230-final-project/blob/main/javascript/js.js
(This is my first post here if you have any suggestions I'm open)
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0]
let dayweather = "Sunday"
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0]["icon"]}#2x.png`;
let individualDiv = document.createElement("Div")
individualDiv.className = "individual"
let description = document.createElement("p")
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4")
day.innerHTML = dayweather
let temperature = document.createElement("p")
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`
let hum = document.createElement("p")
hum.innerHTML = `${firstItem.main.humidity}%`
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city)
SecondItemF(list, city)
ThirdItemF(list, city)
})
});
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.classList.remove("individual");
})
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>
You need to use a linter like this one: https://jshint.com Your code needs a ton of semi-colons and you're missing a bracket and parenthesis }) that .fetch() or submit handler needs. I edited your question just so it doesn't irritate anyone trying to answer the question. You'll see the comment at the bottom of this example showing where I added it, but I guessed because there's no way to test it since there's no key for the API (but not expecting one, so worries there).
Besides that problem, the solution for the problem addressed in the question is the following:
Remove:
contentDiv.classList.remove("individual");
And add:
contentDiv.replaceChildren();
Removing a class doesn't remove the actual elements (well normally unless there's some very convoluted logic going on). .replaceChildren(); without a parameter will remove everything within contentDiv, but if you nee to just remove .individual do the following:
document.querySelector('.individual').remove();
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0];
let dayweather = "Sunday";
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0].icon}#2x.png`;
let individualDiv = document.createElement("Div");
individualDiv.className = "individual";
let description = document.createElement("p");
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4");
day.innerHTML = dayweather;
let temperature = document.createElement("p");
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`;
let hum = document.createElement("p");
hum.innerHTML = `${firstItem.main.humidity}%`;
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`;
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city);
SecondItemF(list, city);
ThirdItemF(list, city);
});
});// <= This is missing
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.replaceChildren();
});
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>
I will attempt to be as concise as possible, but am out of my depth (i should be in the baby pool :)
I'm trying to make a simple website for my son that presents a random sentence with a blank where an adverb should be. The user then has to guess which of the three randomised words presented below is an adverb. I have then tried to implement a scoring system which is where my problem lies.
I had it working OK, when the buttons were static, but since randomising and adding event listeners to the answer buttons it is adding two to the score instead of one. The problem code is towards the bottom (//add event listeners to buttons)
One further problem is that when someone answers the first question incorrectly my code says they have 'undefined correct answers'. I can't get that to say '0 correct answers'
<head>
<title>Adverb Kings</title>
</head>
<body>
<h1>Adverb Kings</h1>
<div id="sentence"></div>
<div>
<button type="button" onclick="right()"></button>
<button type="button" onclick="wrong()"></button>
<button type="button" onclick="wrong()"></button>
<div id="result"></div>
<div id="correct"></div>
<div id="attempted"></div>
</div>
<script>
//define right functions
function right() {
correctAlert();
correctAnswer();
answersAttempted();
}
//define wrong functions
function wrong() {
incorrectAlert();
answersAttempted();
}
//alert correct
function correctAlert() {
var element = document.getElementById("result");
element.classList.add("correct");
element.innerHTML = "Correct";
}
//alert incorrect
function incorrectAlert() {
var element = document.getElementById("result");
element.classList.add("incorrect");
element.innerHTML = "Incorrect, try again.";
}
//tracking correct answers
function correctAnswer() {
if (sessionStorage.correct) {sessionStorage.correct = Number(sessionStorage.correct)+1;
} else {
sessionStorage.correct = 1;
}
}
//tracking attempted questions count
function answersAttempted() {
if (typeof(Storage) !== "undefined") {
if (sessionStorage.attempts) {
sessionStorage.attempts = Number(sessionStorage.attempts)+1;
} else {
sessionStorage.attempts = 1;
}
document.getElementById("attempted").innerHTML = "You have attempted " + sessionStorage.attempts + " question(s) in this session and got " + sessionStorage.correct + " correct" ;
} else {
document.getElementById("attempted").innerHTML = "Sorry, your browser does not support web storage...";
}
}
//create sentence array
var sentence;
sentence = ['The people _______ went crazy about the new game options', 'The man _______ slipped his hands around his desk handle', 'He _______ typed a new password for his school account'];
//randomise sentence array
var el = document.getElementById('sentence');
el.textContent = sentence[Math.floor(Math.random() * sentence.length)];
//set order of words in order to randomise
var orders = [0, 1, 2];
shuffle(orders);
//add event listeners to buttons
var buttons = document.getElementsByTagName("button");
buttons[orders[0]].addEventListener('click', right);
buttons[orders[1]].addEventListener('click', wrong);
buttons[orders[2]].addEventListener('click', wrong);
//create and randomise adverb array
var adverbs = ['slowly', 'quickly', 'insanely'];
buttons[orders[0]].textContent = adverbs[Math.floor(Math.random() * adverbs.length)];
//create and randomise other words
var other1 = ['burger', 'insane', 'ugly'];
buttons[orders[1]].textContent = other1[Math.floor(Math.random() * other1.length)];
var other2 = ['sausage', 'fist', 'gun'];
buttons[orders[2]].textContent = other2[Math.floor(Math.random() * other2.length)];
//shuffle position of adverb
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
</script>
</body>
</html>```
You are adding the event listeners both in the HTML and JS.
Remove the onclick="..." part of the buttons in the HTML and all should be good.
To stop the number being undefined, set sessionStorage.correct to 0 before you call any functions:
<script>
sessionStorage.correct = 0;
...
You have added event listener twice on in HTML and one in js code due to which it is hitting twice.
regarding the undefined value, when hitting incorrect first-time session storage is not initialized due to which it is showing undefined. please check below js code where I have commented the js event listener and initialize the sessionstorage.correct and now it is working fine.
code
//define right functions
function right() {
correctAlert();
correctAnswer();
answersAttempted();
}
//define wrong functions
function wrong() {
incorrectAlert();
answersAttempted();
}
//alert correct
function correctAlert() {
var element = document.getElementById("result");
element.classList.add("correct");
element.innerHTML = "Correct";
}
//alert incorrect
function incorrectAlert() {
var element = document.getElementById("result");
element.classList.add("incorrect");
element.innerHTML = "Incorrect, try again.";
}
//tracking correct answers
function correctAnswer() {
if (sessionStorage.correct) {sessionStorage.correct = Number(sessionStorage.correct)+1;
} else {
sessionStorage.correct = 1;
}
}
//tracking attempted questions count
function answersAttempted() {
if (typeof(Storage) !== "undefined") {
if (sessionStorage.attempts) {
sessionStorage.attempts = Number(sessionStorage.attempts)+1;
} else {
sessionStorage.attempts = 1;
}
// initializing sessionStorage.correct
if(!sessionStorage.correct) {
sessionStorage.correct=0;
}
document.getElementById("attempted").innerHTML = "You have attempted " + sessionStorage.attempts + " question(s) in this session and got " + sessionStorage.correct + " correct" ;
} else {
document.getElementById("attempted").innerHTML = "Sorry, your browser does not support web storage...";
}
}
//create sentence array
var sentence;
sentence = ['The people _______ went crazy about the new game options', 'The man _______ slipped his hands around his desk handle', 'He _______ typed a new password for his school account'];
//randomise sentence array
var el = document.getElementById('sentence');
el.textContent = sentence[Math.floor(Math.random() * sentence.length)];
//set order of words in order to randomise
var orders = [0, 1, 2];
shuffle(orders);
//add event listeners to buttons
var buttons = document.getElementsByTagName("button");
// buttons[orders[0]].addEventListener('click', right);
// buttons[orders[1]].addEventListener('click', wrong);
// buttons[orders[2]].addEventListener('click', wrong);
//create and randomise adverb array
var adverbs = ['slowly', 'quickly', 'insanely'];
buttons[orders[0]].textContent = adverbs[Math.floor(Math.random() * adverbs.length)];
//create and randomise other words
var other1 = ['burger', 'insane', 'ugly'];
buttons[orders[1]].textContent = other1[Math.floor(Math.random() * other1.length)];
var other2 = ['sausage', 'fist', 'gun'];
buttons[orders[2]].textContent = other2[Math.floor(Math.random() * other2.length)];
//shuffle position of adverb
function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}
Hi so i got a very basic JavaScript HTML quiz working, however what i want to end up with is an assessment type quiz that has lets say 15 questions based on 3 categories (e.g. Alcoholism, depression, drug abuse) e.g.
How often to you drink alcohol?
- All the time
- Occasionally
- Never
the player answers all 15 questions and at the end depending on how they answered the questions they get assigned a category e.g. your category is Drug Abuse etc.
I'm thinking that maybe each category has its own counter and a value is applied to each of the possible answers e.g. All the time gives a score of 3, occasionally scores a 2 etc. As the player answers the questions, the values get stored in the corresponding category and at the end the scores for each category are added up and the category with the highest score gets assigned to the player?
Any help with this would be appreciated :)
HTML:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2 id="test_status"></h2>
<div id="test"></div>
</body>
</html>
CSS:
<style>
div#test {
border:#000 1px solid;
padding: 10px 40px 40px 40px;
}
</style>
JS:
<script>
var pos = 0, test, test_status, question, choice, choices, chA, chB, chC, correct = 0;
var questions = [
["How often do you drink?", "All the time", "Often", "Never", "B"],
["Do you ever feel sad for no reason?", "All the time", "Often", "Never", "C"],
["Have you ever tried drugs", "All the time", "Often", "Never", "C"],
["Do you feel uneasy around people", "All the time", "Often", "Never", "C"]
];
function _(x) {
return document.getElementById(x);
}
function renderQuestion () {
test = _("test");
if(pos >= questions.length) {
test.innerHTML = "<h2>Your Category is </h2>";
_("test_status").innerHTML = "Test Completed";
pos = 0;
correct = 0;
return false;
}
_("test_status").innerHTML = "Question "+(pos+1)+" of"+questions.length;
question = questions[pos] [0];
chA = questions[pos] [1];
chB = questions[pos] [2];
chC = questions[pos] [3];
test.innerHTML = "<h3>"+question+"</h3>";
test.innerHTML += "<input type='radio' name='choices' value='A'> "+chA+"<br>";
test.innerHTML += "<input type='radio' name='choices' value='B'> "+chB+"<br>";
test.innerHTML += "<input type='radio' name='choices' value='C'> "+chC+"<br><br>";
test.innerHTML +="<button onclick='checkAnswer()'>submit Answer</button>";
}
function checkAnswer() {
choices = document.getElementsByName("choices");
for (var i=0; i<choices.length; i++) {
if(choices[i].checked) {
choice = choices[i].value;
}
}
if(choice == questions[pos] [4]) {
correct++;
}
pos++;
renderQuestion();
}
window.addEventListener("load", renderQuestion, false);
</script>
The executable Javascript snippet its generated by TypeScript(a public GIT repository is available on this bucket), The quiz its organized by arguments and categories; below you can see the UML diagram.
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Categories;
(function (Categories) {
var QuestionCategory = (function () {
function QuestionCategory(value) {
this.Value = value;
}
return QuestionCategory;
})();
Categories.QuestionCategory = QuestionCategory;
var AQuestionCategory = (function (_super) {
__extends(AQuestionCategory, _super);
function AQuestionCategory() {
_super.call(this, 1);
}
return AQuestionCategory;
})(QuestionCategory);
Categories.AQuestionCategory = AQuestionCategory;
var BQuestionCategory = (function (_super) {
__extends(BQuestionCategory, _super);
function BQuestionCategory() {
_super.call(this, 2);
}
return BQuestionCategory;
})(QuestionCategory);
Categories.BQuestionCategory = BQuestionCategory;
var CQuestionCategory = (function (_super) {
__extends(CQuestionCategory, _super);
function CQuestionCategory() {
_super.call(this, 3);
}
return CQuestionCategory;
})(QuestionCategory);
Categories.CQuestionCategory = CQuestionCategory;
})(Categories || (Categories = {}));
var Questions;
(function (Questions) {
var Answer = (function () {
function Answer(text, value) {
this.Text = text;
this.Value = value;
}
return Answer;
})();
Questions.Answer = Answer;
var Question = (function () {
function Question(text, id, category, answers) {
this.Text = text;
this.ID = id;
this.Category = category;
this.Answers = answers;
}
Question.prototype.Render = function () {
var _this = this;
var dContainer = document.createElement("div");
var dQuestion = document.createElement("h3");
dQuestion.innerHTML = this.Text;
dContainer.appendChild(dQuestion);
var dCategory = document.createElement("div");
dCategory.innerHTML = 'Category: ' + this.Category.Value;
dContainer.appendChild(dCategory);
dContainer.appendChild(document.createElement("br"));
var counter = 0;
this.Answers.forEach(function (a) {
var __id = _this.ID + counter;
var dRadio = document.createElement("input");
dRadio.setAttribute('type', 'radio');
dRadio.setAttribute('id', __id);
dRadio.setAttribute('data-category', _this.Category.Value + '');
dRadio.setAttribute('value', a.Value + '');
dRadio.setAttribute('name', _this.ID);
var dLabel = document.createElement("label");
dLabel.innerHTML = a.Text;
dLabel.setAttribute('For', __id);
dContainer.appendChild(dRadio);
dContainer.appendChild(dLabel);
counter++;
});
dContainer.appendChild(document.createElement("hr"));
return dContainer;
};
return Question;
})();
Questions.Question = Question;
var QuestionCollection = (function () {
function QuestionCollection(questions) {
this.Questions = questions;
}
QuestionCollection.prototype.Render = function () {
var div = document.createElement("div");
this.Questions.forEach(function (q) {
div.appendChild(q.Render());
});
return div;
};
return QuestionCollection;
})();
Questions.QuestionCollection = QuestionCollection;
var QuestionArgument = (function () {
function QuestionArgument(name, collection) {
this.Collection = collection;
this.Name = name;
}
QuestionArgument.prototype.Render = function () {
var div = document.createElement("div");
var h1Arg = document.createElement("h1");
h1Arg.innerHTML = this.Name;
div.appendChild(h1Arg);
div.appendChild(document.createElement("hr"));
div.appendChild(this.Collection.Render());
return div;
};
return QuestionArgument;
})();
Questions.QuestionArgument = QuestionArgument;
var QuizManager = (function () {
function QuizManager(hook, arguments) {
this.Arguments = arguments;
this.Hook = hook;
}
QuizManager.prototype.Render = function () {
var _this = this;
this.Arguments.forEach(function (arg) {
_this.Hook.appendChild(arg.Render());
});
var btn = document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Done');
btn.onclick = function (e) {
_this.Compute();
};
this.Hook.appendChild(btn);
};
QuizManager.prototype.Compute = function () {
var _this = this;
var cats = [], dxCat = [], dxCatTotValue = [];
this.Arguments.forEach(function (arg) {
arg.Collection.Questions.forEach(function (q) {
if (cats.length > 0) {
if (cats.indexOf(q.Category) === -1)
cats.push(q.Category);
}
else
cats.push(q.Category);
});
});
cats.forEach(function (c) {
var p = document.querySelectorAll('input[data-category =\'' + c.Value + '\']:checked');
var tv = 0;
for (var i = 0; i < p.length; i++) {
if (parseInt(p[i]['value']) != NaN)
tv += parseInt(p[i]['value']);
}
dxCatTotValue.push({ "Cat": c.Value, "TVal": tv });
});
this.Hook.appendChild(document.createElement("hr"));
var summariH2 = document.createElement("h2");
summariH2.innerHTML = 'Summary';
dxCatTotValue.sort(this.Compare);
dxCatTotValue.forEach(function (catValue) {
var entryDiv = document.createElement("div");
entryDiv.innerHTML = 'Category ' + catValue['Cat'] + ': ' + catValue['TVal'];
_this.Hook.appendChild(entryDiv);
});
this.Hook.appendChild(document.createElement("hr"));
};
QuizManager.prototype.Compare = function (a, b) {
if (a['TVal'] > b['TVal'])
return -1;
if (a['TVal'] < b['TVal'])
return 1;
return 0;
};
return QuizManager;
})();
Questions.QuizManager = QuizManager;
})(Questions || (Questions = {}));
window.onload = function () {
var CCat = new Categories.CQuestionCategory();
var BCat = new Categories.BQuestionCategory();
var ACat = new Categories.AQuestionCategory();
var q1 = new Questions.Question('Do you eat Apples?', 'q1', CCat, [new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var q2 = new Questions.Question('Do you like Pears?', 'q2', BCat, [new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var fruitsquestions = new Questions.QuestionCollection([q1, q2]);
var fruitsArguments = new Questions.QuestionArgument('Fruits', fruitsquestions);
var q3 = new Questions.Question('Do you eat Onions?', 'q3', ACat, [new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var q4 = new Questions.Question('Do you like Cucumbers?', 'q4', CCat, [new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var vegetablesQuestions = new Questions.QuestionCollection([q3, q4]);
var vegetablesArguments = new Questions.QuestionArgument('Vegetables', vegetablesQuestions);
var quiz = new Questions.QuizManager(document.getElementById("content"), [fruitsArguments, vegetablesArguments]);
quiz.Render();
};
<div id="content"></div>
The TypeScript source:
module Categories {
export class QuestionCategory {
Value: number;
Text: string;
constructor(value: number) { this.Value = value; }
}
export class AQuestionCategory extends QuestionCategory {
constructor() { super(1); }
}
export class BQuestionCategory extends QuestionCategory {
constructor() { super(2); }
}
export class CQuestionCategory extends QuestionCategory {
constructor() { super(3); }
}
}
module Questions {
import QC = Categories;
export class Answer {
Text: string;
Value: number;
constructor(text: string, value: number) {
this.Text = text;
this.Value = value;
}
}
export class Question {
Category: QC.QuestionCategory;
Answers: Answer[];
Text: string;
ID: string;
constructor(text: string, id: string, category: QC.QuestionCategory, answers: Answer[]) {
this.Text = text;
this.ID = id;
this.Category = category;
this.Answers = answers;
}
Render(): HTMLElement {
var dContainer = document.createElement("div");
var dQuestion = document.createElement("h3")
dQuestion.innerHTML = this.Text;
dContainer.appendChild(dQuestion);
var dCategory = document.createElement("div")
dCategory.innerHTML = 'Category: ' + this.Category.Value;
dContainer.appendChild(dCategory);
dContainer.appendChild(document.createElement("br"));
var counter = 0;
this.Answers.forEach(a => {
var __id = this.ID + counter;
var dRadio = document.createElement("input");
dRadio.setAttribute('type', 'radio');
dRadio.setAttribute('id', __id);
dRadio.setAttribute('data-category', this.Category.Value + '');
dRadio.setAttribute('value', a.Value + '');
dRadio.setAttribute('name', this.ID);
var dLabel = document.createElement("label");
dLabel.innerHTML = a.Text
dLabel.setAttribute('For', __id)
dContainer.appendChild(dRadio);
dContainer.appendChild(dLabel);
counter++;
});
dContainer.appendChild(document.createElement("hr"));
return dContainer;
}
}
export class QuestionCollection {
Questions: Question[];
constructor(questions: Question[]) { this.Questions = questions; }
Render(): HTMLElement {
var div = document.createElement("div");
this.Questions.forEach(q => {
div.appendChild(q.Render());
});
return div;
}
}
export class QuestionArgument {
Name: string;
Collection: QuestionCollection;
constructor(name: string, collection: QuestionCollection) {
this.Collection = collection;
this.Name = name;
}
Render(): HTMLElement {
var div = document.createElement("div");
var h1Arg = document.createElement("h1");
h1Arg.innerHTML = this.Name;
div.appendChild(h1Arg);
div.appendChild(document.createElement("hr"));
div.appendChild(this.Collection.Render());
return div;
}
}
export class QuizManager {
Hook: HTMLElement;
Arguments: QuestionArgument[];
constructor(hook: HTMLElement, arguments: QuestionArgument[]) {
this.Arguments = arguments;
this.Hook = hook;
}
Render() {
this.Arguments.forEach(arg => {
this.Hook.appendChild(arg.Render());
});
var btn = <HTMLButtonElement> document.createElement('input');
btn.setAttribute('type', 'button');
btn.setAttribute('value', 'Done');
btn.onclick = (e) => { this.Compute(); }
this.Hook.appendChild(btn);
}
Compute() {
var cats = [], dxCat = [], dxCatTotValue = [];
this.Arguments.forEach(arg => {
arg.Collection.Questions.forEach(q => {
if (cats.length > 0) {
if (cats.indexOf(q.Category) === -1)
cats.push(q.Category);
}
else
cats.push(q.Category);
});
});
cats.forEach(c => {
var p = document.querySelectorAll('input[data-category =\'' + c.Value + '\']:checked');
var tv = 0;
for (var i = 0; i < p.length; i++)
{
if (parseInt(p[i]['value']) != NaN)
tv += parseInt(p[i]['value']);
}
dxCatTotValue.push({ "Cat": c.Value, "TVal": tv });
})
//this.Hook.appendChild(btn);
this.Hook.appendChild(document.createElement("hr"));
var summariH2 = document.createElement("h2");
summariH2.innerHTML = 'Summary';
dxCatTotValue.sort(this.Compare);
dxCatTotValue.forEach(catValue => {
var entryDiv = document.createElement("div");
entryDiv.innerHTML = 'Category ' + catValue['Cat'] + ': ' + catValue['TVal'];
this.Hook.appendChild(entryDiv);
});
this.Hook.appendChild(document.createElement("hr"));
}
Compare(a, b) {
if (a['TVal'] > b['TVal'])
return -1;
if (a['TVal'] < b['TVal'])
return 1;
return 0;
}
}
}
window.onload = () => {
var CCat = new Categories.CQuestionCategory();
var BCat = new Categories.BQuestionCategory();
var ACat = new Categories.AQuestionCategory();
var q1 = new Questions.Question('Do you eat Apples?', 'q1',
CCat,
[new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var q2 = new Questions.Question('Do you like Pears?', 'q2',
BCat,
[new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var fruitsquestions = new Questions.QuestionCollection([q1, q2]);
var fruitsArguments = new Questions.QuestionArgument('Fruits', fruitsquestions);
var q3 = new Questions.Question('Do you eat Onions?', 'q3',
ACat,
[new Questions.Answer('Yes', 1), new Questions.Answer('No', 2)]);
var q4 = new Questions.Question('Do you like Cucumbers?', 'q4',
CCat,
[new Questions.Answer('All the time', 1), new Questions.Answer('Occasionally', 2), , new Questions.Answer('Never', 3)]);
var vegetablesQuestions = new Questions.QuestionCollection([q3, q4]);
var vegetablesArguments = new Questions.QuestionArgument('Vegetables', vegetablesQuestions);
var quiz = new Questions.QuizManager(document.getElementById("content"), [fruitsArguments, vegetablesArguments]);
quiz.Render();
};
this quiz maker produces a very simple set of HTML and it's obvious where the total calculation is in order to change it.
You can simply add the numbers of questions relating to each answer, then compare to say which is largest and display the result. It gives you a choice of having radio buttons in a list for each question, or several on one line.
All the questions will display on a single page, rather than having to press Next each time which can be annoying for people doing the quiz. No CSS is needed and hardly any javascript.
Example code for a self-scoring quiz with 1 question of each type (drop-down box, short answer, multiple answers etc). The generator tool in the link above will create something similar, it's pure HTML and javascript with no external scripts to load, no jquery or dependencies.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional/EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../../dkj.css" type="text/css">
<title>Quiz: Sample "Think Again" Quiz</title>
<script type="text/javascript">
<!--
var stuff = new Array (51) // maximum number of questions
var answered = new Array (51) // processing inhibitor for guessers
for(var i = 0; i<=50; i++){stuff[i]=0; answered[i]=0} //initialize arrays// --> </script>
</head>
<body bgcolor ="#ffff88" text="#000000" link="#000088" vlink="purple" alink="#880000" >
<a name="top"></a>
<p align='right'><font size=-1>
Quiz created: 1999/1/31
</font></p>
<center>
<h2><font color="#ff3333">Sample "Think Again" Quiz</font></h2></center>
<noscript>
<p><font color="#880000">
I'm sorry. This page requires that your browser be capable of running JavaScript in order to use the self-correcting feature of the quiz.
In most browsers you can activate JavaScript using a dialog box somewhere under one of the menu bar options. If you are really using a (rare) non-JavaScript-capable browser, you will have to do without the self-grading features of this page.</font></p>
</noscript>
<p>
<b>Instructions: </b>
Answer the multiple choice questions, guessing if necessary,
then click on the "Process Questions" button to see your
score. The program will not reveal which questions you got wrong, only how
many points you have. Go back and change your answers until you get them all
right. (The message box will rejoice at that point and the page will change color in delight.)</p>
<p>
<b>Points to note: </b>
(1) Questions with only one possible answer are one point each.
(2) Questions with <i>one or more</i> possible answers (represented by check boxes)
give a point for each correct answer, but also subtract a point for each wrong answer!
(3) The program will not attempt to score your efforts at all if
you have not tried at least half of the questions.
(4) This practice quiz is for your own use only.
No record of your progress is kept or reported to anyone. </p>
<hr>
<form name="formzSampQuiz">
1. Fog is notorious in
<blockquote>
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">New York
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">Chicago
<input type=radio name=quest1 onClick="stuff[1]=1; answered[1]=1">London
<input type=radio name=quest1 onClick="stuff[1]=0; answered[1]=1">Los Angeles
<input type=radio name=quest1 checked onClick="stuff[1]=0; answered[1]=0">No Answer </blockquote>
2. Chicago is in
<blockquote>
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Montana
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Manitoba
<input type=radio name=quest2 onClick="stuff[2]=0; answered[2]=1">Missouri
<input type=radio name=quest2 onClick="stuff[2]=1; answered[2]=1">Illinois
<input type=radio name=quest2 checked onClick="stuff[2]=0; answered[2]=0">No Answer </blockquote>
3. The famous French Queen Marie Antoinette was married to
<blockquote>
<select name=quest3 size=1 onChange="figureout3()"><option selected>No Answer <option>St. Louis
<option>Louis XVI
<option>Louis DXLVIII
<option>Louis Rukeyser
<option>Louey, brother of Dewey and and Huey
<option>John L. Louis
</select>
<script type="text/javascript"><!-- //Pre-processor for question 3";
function figureout3() {
if (document.formzSampQuiz.quest3.options.selectedIndex == 0)
{stuff[3] = 0; answered[3]=0} // no answer
else if (document.formzSampQuiz.quest3.options.selectedIndex == 2)
{stuff[3] = 1; answered[3]=1} // right answer
else {stuff[3] = 0; answered[3]=1} // wrong answer
} // end function figureout3()
//--></script>
</blockquote>
4. Compared with Elizabeth II, Elizabeth I was
<blockquote>
<input type=radio name=quest4 onClick="stuff[4]=1; answered[4]=1">earlier
<input type=radio name=quest4 onClick="stuff[4]=0; answered[4]=1">later
<input type=radio name=quest4 checked onClick="stuff[4]=0; answered[4]=0">No Answer </blockquote>
5. Which of the Following are saints?
<blockquote>
<script type="text/javascript">
<!-- //Script to pre-process question 5
function figureout5() {
stuff[5]=0; answered[5]=0
if(document.formzSampQuiz.q5p2.checked==true){stuff[5]--; answered[5]=1}
if(document.formzSampQuiz.q5p3.checked==true){stuff[5]++; answered[5]=1}
if(document.formzSampQuiz.q5p4.checked==true){stuff[5]++; answered[5]=1}
if(document.formzSampQuiz.q5p5.checked==true){stuff[5]--; answered[5]=1}
if(document.formzSampQuiz.q5p6.checked==true){stuff[5]--; answered[5]=1}
} //end function figure5
// --></script>
<input type=checkbox name="q5p2" onClick="figureout5()">
Jack-the-Ripper
<input type=checkbox name="q5p3" onClick="figureout5()">
St. Augustine
<input type=checkbox name="q5p4" onClick="figureout5()">
St. Ursula
<input type=checkbox name="q5p5" onClick="figureout5()">
Adolf Hitler
<input type=checkbox name="q5p6" onClick="figureout5()">
Napoleon
</blockquote>
6. Which of the following is <i>not</i> one of the Seven Deadly Sins?
<blockquote>
<select name=quest6 size=1 onChange="figureout6()"><option selected>No Answer <option>pride
<option>lust
<option>envy
<option>stupidity
<option>anger
<option>covetousness
<option>gluttony
<option>sloth
</select>
<script type="text/javascript"><!-- //Pre-processor for question 6";
function figureout6() {
if (document.formzSampQuiz.quest6.options.selectedIndex == 0)
{stuff[6] = 0; answered[6]=0} // no answer
else if (document.formzSampQuiz.quest6.options.selectedIndex == 4)
{stuff[6] = 1; answered[6]=1} // right answer
else {stuff[6] = 0; answered[6]=1} // wrong answer
} // end function figureout6()
//--></script>
</blockquote>
<script type="text/javascript"><!--// Processor for questions 1-6>
function processqzSampQuiz() {
document.bgColor='#ffff88'
var goodguyszSampQuiz=0 // used to calculate score
var inhibitzSampQuiz=0 // used to prevent processing of partially completed forms
for (var i=1; i<=6; i++){
goodguyszSampQuiz=goodguyszSampQuiz + stuff[i]; inhibitzSampQuiz = inhibitzSampQuiz + answered[i];
} // end for
// Prevent display of score if too few questions completed
if (inhibitzSampQuiz < 3){
document.formzSampQuiz.grade.value="You must try at least 3!"
document.formzSampQuiz.score.value= "Secret!";
} // end if
else {
document.formzSampQuiz.score.value=goodguyszSampQuiz;
if (goodguyszSampQuiz==7){
document.formzSampQuiz.grade.value="Hooray!"
document.bgColor="#ff9999"
}else {document.formzSampQuiz.grade.value="Keep Trying!"}
} // end else
} // end function processqzSampQuiz()
function killall(){ //keep final scores from hanging around after reset clears form
goodguys=0; inhibitaa=0;
for (i=0; i<=50; i++){stuff[i]=0; answered[i]=0}
} // end functionl killall()
// --> </script>
<input type=button name=processor value="Process Questions" onClick=processqzSampQuiz()> <input type=reset value="Reset" onClick="killall(); document.bgColor='#ffff88'">
<input type=text name="grade" value="Nothing!" size=25 onFocus="blur()">
Points out of 7:
<input type=text name="score" value="Zip!" size=10 onFocus="blur()">
<br></form>
<p align='right'><font size=-1>
Return to top.</font></p>
<hr>
<!-- You can edit this acknowledgement out if you like. -->
<p align='right'><font size=-1>
This consummately cool, pedagogically compelling, self-correcting, <br>
multiple-choice quiz was produced automatically from <br>
a text file of questions using D.K. Jordan's<br>
<a href="http://anthro.ucsd.edu/~dkjordan/resources/quizzes/quizzes.html">
Think Again Quiz Maker</a> <br>
of October 31, 1998.<br>
</font></p>
</body></html>
UPDATE 6-25-2014
Any insight would be appreciated!
UPDATE 6-21-2014
I tried to make the radio variables, global so the 'if block' in the 'answerFwd' function could be compared to the correctAnswer Array, but that didn't work!
UPDATE 6-16-2014
ADDED JS FIDDLE
I am building a quiz and creating an array of radio buttons dynamically, and would like to match the selected button with the correct answer I have established in the question array.
html
<div id="responses">
<input type="radio" name="choices" class="radioButtons" value="0" id="choice0">
<div id="c0" class="choiceText">The Observers</div>
<input type="radio" name="choices" class="radioButtons" value="1" id="choice1">
<div id="c1" class="choiceText">The Watchers </div>
<input type="radio" name="choices" class="radioButtons" value="2" id="choice2">
<div id="c2" class="choiceText">The Sentinels</div>
<input type="radio" name="choices" class="radioButtons" value="3" id="choice3">
<div id="c3" class="choiceText">The Oa</div>
</div>
questions:
var allQuestions = [{
"question": "Who was Luke's wingman in the battle at Hoth?",
"choices": ["Dak", "Biggs", "Wedge", "fx-7"],
"correctAnswer": 0 }, {
"question": "What is the name of Darth Vader's flag ship?",
"choices": ["The Avenger", "Devastator ", "Conquest", "The Executor"],
"correctAnswer": 3 },{},{} //other questions];
var item = allQuestions[0];
var currentQuestion = 0;
var playersScore = 0;
//function which creates the buttons
function createRadioButtonFromArray(array) {
var len = array.length;
var responses = document.getElementById("responses");
responses.innerHTML = '';
for (var i = 0; i < len; i++) {
radio = document.createElement("input"); //Updated 6-21-2014 removed 'var'
radio.type = "radio";
radio.name = "choices";
radio.className = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
ar radioText = document.createElement("div");
radioText.id = "c" + i;
radioText.className = "choiceText";
radioText.innerHTML = array[i];
responses.appendChild(radio);
responses.appendChild(radioText);
}
}
function answerFwd() {
var answerOutput = " ";
var itemAnswers = allQuestions;
var playerTally = 0; //Updated 6-9-2014
var playerFeedback = " "; //Updated 6-9-2014
var playerMessage = document.getElementById("playerMessage"); //Updated 6-9-2014
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
createRadioButtonFromArray(itemAnswers[currentQuestion].choices);
* Updated 6-9-2014 I am stumped; This doesn't work but I was encouraged I got a score tally on the page! Am I comparing the elements correctly? Updated 6-21-2014 This reversed the gain, where I had the tally render on the screen*
if (itemAnswers.correctAnswer === responses.id) { //Updated 6-21-2014
playerTally += 1;
playerFeedback += "<h5>" + playerTally + "</h5> <br/>";
playerMessage.innerHTML = playerFeedback;
}
}
At first I tried to debug this but had trouble finding where the error was coming from.
One thing I noticed was currentAnswer variable was only being set once. (when it was declared)
Another thing that would make this cleaner is storing each response to each question as a property of the questions object.
For example: {"question": "What is the registry of the Starship Reliant?","choices": ["NX-01", "NCC-1864", "NCC-1701", "NCC-2000"],"correctAnswer": 1,"selectedAnswer": 0}
This is a good example of why you may want to use object oriented programming. You can keep the global namespace clean, while also having tighter control over your variables.
I put together this Quiz Code using some object oriented principles:
JavaScript
var Quiz = function(questions) {
this.questions = questions;
this.$template = {
"header": document.querySelector(".question"),
"options": document.querySelector(".question-choices")
};
this.init();
}
Quiz.prototype = {
"init": function() {
this.question = 0;
this.generateQuestion();
this.bindEvents();
},
//gets called when this.question == this.questions.length, calculates a score percentage and alerts it
"score": function() {
var correctCount = 0;
this.questions.forEach(function(question){
if ( (question.selectedAnswer || -1) === question.correctAnswer ) correctCount += 1
})
alert("Score: " + ((correctCount / this.questions.length) * 100) + "%")
},
//Gets called during initialization, and also after a nav button is pressed, loads the question and shows the choices
"generateQuestion": function() {
var question = this.questions[this.question];
this.$template.header.innerHTML = question.question;
this.$template.options.innerHTML = "";
question.choices.forEach(this.createRadio.bind(this));
},
//Binds the previous, and next event handlers, to navigate through the questions
"bindEvents": function() {
var _this = this,
$nextBtn = document.querySelector(".question-navigation--next"),
$prevBtn = document.querySelector(".question-navigation--prev");
$nextBtn.addEventListener("click", function(e) {
//Go to the next question
_this.question++;
if ( _this.question == _this.questions.length ) {
_this.score();
} else {
_this.generateQuestion();
}
});
$prevBtn.addEventListener("click", function(e) {
_this.question--;
if ( _this.question <= 0 ) _this.question = 0
_this.generateQuestion();
});
},
//Create each individual radio button, is callback in a forEach loop
"createRadio": function(choice, index) {
var question = this.questions[this.question];
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "options";
radio.id = "option-"+index;
if ( question.selectedAnswer === index ) {
radio.checked = true;
}
radio.addEventListener("click", function(e) {
question.selectedAnswer = index;
})
var radioText = document.createElement("label");
radioText.setAttribute("for", "option-"+index)
radioText.innerHTML = choice;
radioText.insertBefore(radio, radioText.firstChild);
this.$template.options.appendChild(radioText);
}
}
var q = new Quiz(allQuestions)
Dont mind my code, it is probably very terrible in the eyes of professionals aha but anyway
i am coding a game where the user has to answer a question with 3 options, the question, the 3 answers are all set in arrays [1] to [10]. My problem is that when the question is asked, the question wont update on the website.
<head>
<script type="text/javascript">
var Question = new Array(10);
var Answer1 = new Array(10);
var Answer2 = new Array(10);
var Answer3 = new Array(10);
var i = 1;
(example of one question)
Question[1] = "What time is it?";
Answer1[1] = "1.I dont know";
Answer2[1] = "2.Party Time";
Answer3[1] = "3.None of your business";
</script>
(my function that writes the questions/answers)
<script type="text/javascript">
function displayQuestions() {
document.write(Question[i].toString());
document.write("\n <br>" + Answer1[i].toString());
document.write("\n <br>" + Answer2[i].toString());
document.write("\n <br>" + Answer3[i].toString());
}
</script>
</head>
<body>
<div>My Question Game!</div>
<div id="Question"><script type="text/javascript">displayQuestions();</script></div>
<button onclick="answerGet()">Answer</button>
<script type="text/javascript">
function answerGet()
{
var answer = 0;
answer = parseInt(prompt("Please enter your answer (1 - 3) "));
if (answer < 4 && answer > 0) {
} else if (isNaN(answer)) {
parseInt(prompt("It is not a number. Please enter a number from 1 to 3", ""));
} else {
parseInt(prompt("Your number (" + answer + ") is above 3. Please enter a number from 1 to 3"));
if ((answer() === CorrectAnswer[i])) {
score = score + 50;
}
i = i + 1;
alert(i);
Question = Question[i];
Answer1 = Answer1[i];
Answer2 = Answer2[i];
Answer3 = Answer3[i];
CorrectAnswer = Correctanswer[i];
}
To make your program a bit more slick, you should use jquery.
Sans that to fix your immediate problem, try calling your displayQuestions function after the correct answer is given, like the following:
Answer1 = Answer1[i];
Answer2 = Answer2[i];
Answer3 = Answer3[i];
CorrectAnswer = Correctanswer[i];
displayQuestions();
Your code isn't that bad. Here is how you can update the questions:
In your answerGet() function, add the following to the if ((answer() === CorrectAnswer[i])) block
var question = document.getElementById('question');
question.innerHTML = displayQuestions();
This will get the text from displayQuestions() and put it inside the question div. But there is still a problem, the displayQuestions() function actually prints to the screen. We want it to return text instead, like this:
function displayQuestions() {
var text = Question[i].toString();
text += "\n <br>" + Answer1[i].toString())
text += "\n <br>" + Answer2[i].toString();
text += "\n <br>" + Answer3[i].toString();
return text;
}
Now one final problem: the code that prints the first question is now wrong because the displayQuestions() function doesn't print anything, just returns the text. Lets fix that:
<div id="Question"><script type="text/javascript">document.write(displayQuestions());</script><div>
That should do it. Let me know if you have any trouble implementing that.