I'm doing a little game that is about a questions-answers game, that has 3 options and only one is the right one. So, what I'm trying to do is, every time I open the page, I randomize the correct answer, so, the player can't just memorize the positions, he will be obligate to remember the true answer. I already know how to randomize the right button, doing it with a random number and stuff like that, but, with this problem, just randomize the right button isn't what I need, cuz I have to change the position of the answer too. So, this is my code.
const vintecinco = document.getElementById('312');
const vinteseis = document.getElementById('314');
const vintesete = document.getElementById('214');
vinteseis.addEventListener('click', acerto);
function acerto() {
var msg = document.createElement('p');
msg.textContent = 'Voce acertou!';
msg.style.cssText = 'color: green;'
document.body.appendChild(msg);
var prosseguir = document.createElement('a');
prosseguir.textContent = 'Próxima pergunta!'
prosseguir.href = 'q3.html';
document.body.appendChild(prosseguir);
vintecinco.disabled = true;
vinteseis.disabled = true;
vintesete.disabled = true;
}
vintecinco.addEventListener('click', erro);
vintesete.addEventListener('click', erro);
function erro() {
var msgerro = document.createElement('p');
msgerro.textContent = "Voce errou!";
msgerro.style.cssText = 'color: red;';
document.body.appendChild(msgerro);
var voltar = document.createElement('a');
voltar.textContent = 'Recomeçar!'
voltar.href = 'index.html';
document.body.appendChild(voltar);
vintecinco.disabled = true;
vinteseis.disabled = true;
vintesete.disabled = true;
}
<main>
<p>Qual o número de pi?</p>
<input type="submit" value="3,12..." id='312'>
<input type="submit" value="2,14..." id='214'>
<input type="submit" value="3,14..." id='314'>
</main>
What kind of thing I could do to get random positions without compromise my right answer?
Now I did some changes and I created a test file. I'm trying to do something like that, but now, I can't change the value of the 2 wrong answers, they're default. How could I change it?
var random = Math.floor(Math.random() * 3);
for(var i=1;i<=10;i++) {
console.log(i);
var button = document.getElementById('btn' + i);
if(random == i) {
button.addEventListener('click', prize);
button.value = '1';
}
else {
button.addEventListener('click', closewindow);
button.value = '2';
}
}
There are many ways to do what you want, depending on the rest of the application, one or the other may be better for you, an example:
var input = [];
function acerto() {
var msg = document.createElement('p');
msg.textContent = 'Voce acertou!';
msg.style.cssText = 'color: green;'
document.body.appendChild(msg);
var prosseguir = document.createElement('a');
prosseguir.textContent = 'Próxima pergunta!'
prosseguir.href = 'q3.html';
document.body.appendChild(prosseguir);
input.forEach((i)=>{
i.disabled = true;
});
input = [];
}
function erro() {
var msgerro = document.createElement('p');
msgerro.textContent = "Voce errou!";
msgerro.style.cssText = 'color: red;';
document.body.appendChild(msgerro);
var voltar = document.createElement('a');
voltar.textContent = 'Recomeçar!'
voltar.href = 'index.html';
document.body.appendChild(voltar);
input.forEach((i)=>{
i.disabled = true;
});
input = [];
}
// question, true, false, false...
var res = ["Qual o número de pi?", "3.14", "2.14", "3.12"];
var quest = document.getElementsByTagName("main")[0];
// Create Question
quest.innerHTML = "<p>" + res.splice(0, 1)[0] + "</p>";
// Create Random input
for(i in res){
let temp = document.createElement('input');
temp.type = "submit";
temp.value = res[i];
if(i == 0){
temp.addEventListener('click', acerto);
}else{
temp.addEventListener('click', erro);
}
let rand = Math.floor((input.length+1) * Math.random());
input.splice(rand, 0, temp);
}
// Show input
input.forEach((i)=>{
quest.appendChild(i);
});
<main>
</main>
Related
I have a problem with the function below. It's taking the data from JSON and it's creating a menu item. The problem is when there are more than 2 menu items, and I try to increase the quantity of the first item then the value of the second item is increasing.
function ShowTheMenu(theCategoryId) {
var parentEl = document.getElementById("itemlist");
ClearMenu();
for (let i = 0; i < data.length; i++) {
if (data[i].KategorijaBroj == theCategoryId) {
// MAIN PARENT
var itemBox = document.createElement("div");
itemBox.classList.add("itembox");
var itemImage = document.createElement("img");
itemImage.classList.add("itemimage");
itemImage.src = "/menuitemsimages/" + data[i].Image;
var itemContent = document.createElement("div");
itemContent.classList.add("itemcontent");
var itemTitle = document.createElement("h3");
itemTitle.classList.add("itemtitle");
itemTitle.innerHTML = data[i].Title;
var itemPrice = document.createElement("p");
itemPrice.classList.add("itemprice");
itemPrice.innerHTML = "$" + data[i].Price;
var itemQnt = document.createElement("p");
itemQnt.classList.add("quantity");
itemQnt.innerHTML = "Quantity";
var buttonsBox = document.createElement("div");
buttonsBox.classList.add("divcontrolbtns");
var itemQuantity = 0;
var quantityValue = document.createElement("div");
quantityValue.innerHTML = itemQuantity;
var increaseBtn = document.createElement("div");
increaseBtn.classList.add("controlbtns");
increaseBtn.innerHTML = "+";
increaseBtn.addEventListener("click", function () {
if(itemQuantity < 10) {
itemQuantity++;
}
quantityValue.innerHTML = itemQuantity;
})
var decreaseBtn = document.createElement("div");
decreaseBtn.classList.add("controlbtns");
decreaseBtn.innerHTML = "-";
decreaseBtn.addEventListener("click", function () {
if(itemQuantity > 0) {
itemQuantity--;
}
quantityValue.innerHTML = itemQuantity;
})
var itemAddToCart = document.createElement("button");
itemAddToCart.classList.add("btn-add-to-cart");
itemAddToCart.textContent = "Add to cart";
var itemDesc = document.createElement("p");
itemDesc.classList.add("itemdesc");
itemDesc.innerHTML = data[i].Description;
itemBox.appendChild(itemImage);
itemContent.appendChild(itemTitle);
itemContent.appendChild(itemDesc);
itemContent.appendChild(itemPrice);
itemContent.appendChild(itemAddToCart);
itemContent.appendChild(itemQnt);
buttonsBox.appendChild(increaseBtn);
buttonsBox.appendChild(quantityValue);
buttonsBox.appendChild(decreaseBtn);
itemContent.appendChild(buttonsBox);
itemBox.appendChild(itemContent);
parentEl.appendChild(itemBox);
}
}
}
IMAGE
What should I do in order for the chosen menu item value to be changed?
Try to do something like this bellow. I try to use same HTML structure that you use but to be honest, I suggest that you change a little bit ;)
<!DOCTYPE html>
<html>
<head>
<script>
// Qt
var quantity = new Array();
function ShowTheMenu(theCategoryId) {
// Clear menu
// ClearMenu();
// bt+
increaseBtn = (i) => {
// Item target
let item = document.getElementById('item_' + i);
// Qt target
let qtSpan = item.getElementsByClassName('qt');
// Qt
let qt = parseInt(qtSpan[0].innerHTML);
// Fix some errors
if (qt === undefined || !qt) qt = 0;
// Increase
if (qt < 10) qt++;
// Update
qtSpan[0].innerHTML = qt;
};
// bt-
decreaseBtn = (i) => {
// Item target
let item = document.getElementById('item_' + i);
// Qt target
let qtSpan = item.getElementsByClassName('qt');
// Qt
let qt = parseInt(qtSpan[0].innerHTML);
// Fix some errors
if (qt === undefined || !qt) qt = 0;
// Decrease
if (qt > 0) qt--;
// Update
qtSpan[0].innerHTML = qt;
};
//
var data = new Array();
data[0] = {
Image:
'https://s2.glbimg.com/WcYUQNaattnUf7d8U8MUBfk7loU=/620x430/e.glbimg.com/og/ed/f/original/2015/10/30/pizza.jpg',
KategorijaBroj: 1,
Title: 'Delicious Pizza',
Price: 10,
Description: 'Description test',
};
for (let i = 0; i < data.length; i++) {
if (data[i].KategorijaBroj == theCategoryId) {
// Img
let img = data[i].Image; // '/menuitemsimages/' + data[i].Image;
// Title
let title = data[i].Title;
// Price
let price = '$' + data[i].Price;
// Description
let desc = data[i].Description;
// Qtd
let qt = 2;
// Matriz
let newItem = `<div id="item_${i}" class="itembox">
<div class="itemcontent">
<img src="${img}" border=0 width=100/>
<h3 class="itemtitle">${title}</h3>
<p class="itemprice">${price}</p>
<div class="quantity">
<span>Quantity : </span>
<span class="qt">${qt}</span>
</div>
<div class="controlbtns">
<button class="addbtn" onClick="increaseBtn(${i})">+</button>
<button class="removebtn" onClick="decreaseBtn(${i})">-</button>
</div>
<button class="btn-add-to-cart">Add to cart</button>
<p class="description">${desc}</p>
</div>
</div>`;
// Get the menulist itens
let parentEl = document.getElementById('itemlist');
// Add item
parentEl.insertAdjacentHTML('beforeend', newItem);
}
}
}
</script>
</head>
<body>
<div id="itemlist"></div>
<script>
ShowTheMenu(1);
</script>
</body>
</html>
It's because both items are sharing the same variable, in this case, itemQuantity.
Option 1
If they all should have their own counter I would recommend using an object for tracking this.
const itemQuantity = {
'item1': 2,
'item2': 5
}
if you add some unique class or id to the element you can use this in your onclick event to use as a key. (Where I used 'item1' and 'item2')
Option 2
If you create a function that does everything that's inside your for loop and then just call that function it should also work. This works because every function then creates its own scoped variable of itemQuanity.
Go with whatever options feel best for now. How to manage data in your frontend has a lot of different ways and opinions. You'll quickly discover what works best in what scenario.
What Olavo Mello is mentioning in his answer could still make your code better. using string literals for small HTML snippets is often more readable than using document.createElement(). I would recommend fixing your counter issue first and then look if you could improve your code with Olavo Mello's answer in mind. Good luck :)
Ok,for testing purposes lets say i have a function where it appends <li> elements inside an <ol>
container,and i want to keep all list items i've added,is there a way to store them in Local Storage (or any other way,locally) so i can retrieve them every time i reload the page ?
I've studied a little bit in Window.localStorage api,i did'nt find a method to store a dynamic element like that,but again if there is something i would'nt know to recognize the right practice to do it,since i'm still a student.Any ideas?
var textcounter = 1;
var inputcounter = 1;
function addText() {
var div = document.getElementById("div");
var texttobestored =document.createElement("li");
texttobestored.id = "text" + textcounter;
texttobestored.style.color="red";
texttobestored.innerHTML = "<p>I WANT TO KEEP THIS TEXT</p>";
div.appendChild(texttobestored);
textcounter++;
}
function addInputs() {
var div = document.getElementById("div");
var inputstobestored =document.createElement("li");
inputstobestored.id = "input" + inputcounter;
inputstobestored.innerHTML = "<input placeholder = ContentsToBeSaved>";
inputstobestored.style.color = "blue";
inputstobestored.style.width = "600px";
div.appendChild(inputstobestored);
inputcounter++;
}
#div{
width:600px;
}
<html>
<body>
<ol id="div">
<button onclick="addText()" style="height:100px;width:100px">ADD TEXT</button>
<button onclick="addInputs()" style="height:100px;width:100px">ADD INPUTS</button>
</ol>
</body>
</html>
Here is a working fiddle: https://jsfiddle.net/3ez4pq2d/
This function calls saveInput to save the data to localstorage. Then it also generates the
inputs that are saved via loadInput.
This just stores the ID, COLOR and WIDTH. But using this as a base you can save additional fields also.
function saveinput(obj) {
saved = localStorage.getItem("items") || "[]"
saved = JSON.parse(saved)
saved.push(obj)
localStorage.setItem("items", JSON.stringify(saved))
}
var textcounter = 1;
var inputcounter = 1;
function addText() {
var div = document.getElementById("div");
var texttobestored = document.createElement("li");
texttobestored.id = "text" + textcounter;
texttobestored.style.color = "red";
texttobestored.innerHTML = "<p>I WANT TO KEEP THIS TEXT</p>";
div.appendChild(texttobestored);
textcounter++;
}
function addInputs() {
var div = document.getElementById("div");
var inputstobestored = document.createElement("li");
inputstobestored.id = "input" + inputcounter;
inputstobestored.innerHTML = "<input placeholder = ContentsToBeSaved>";
inputstobestored.style.color = "blue";
inputstobestored.style.width = "600px";
saveinput({
id: "input" + inputcounter,
color: "blue",
width: "600px"
})
div.appendChild(inputstobestored);
inputcounter++;
}
function loadInput() {
inputs = localStorage.getItem("items") || "[]"
inputs = JSON.parse(inputs)
inputs.forEach(function(input) {
var div = document.getElementById("div");
var inputstobestored = document.createElement("li");
inputstobestored.id = input.id;
inputstobestored.innerHTML = "<input placeholder = ContentsToBeSaved>";
inputstobestored.style.color = input.color;
inputstobestored.style.width = input.width;
div.appendChild(inputstobestored);
inputcounter++;
})
}
loadInput();
Hi I would like to know how I can style these buttons in Javascript in my quiz.
I can't figure out how to do that. Would be great if someone can help.
Sample code is below and full code is further below. I tried doing making the buttons a div but that did not work.
Would be great if someone can help.
Sample code is below and full code is further below.
thank you
for(i=0; i < options.length; i++){
document.getElementById("trivia").innerHTML += "<br><button onclick='checkAnswer(\""+options[i]+"\", this)'>" + options[i] + "</button>";
}
}
// This initialises a request to the trivia database API
var xmlhttp = new XMLHttpRequest();
var url = "https://opentdb.com/api.php?amount=1&category=21&difficulty=easy&type=multiple";
var score = 0;
var livesTaken = 0;
var question;
var type;
var correctAnswer;
var incorrect1;
var incorrect2;
var incorrect3;
// This requests the data
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var jsondata = JSON.parse(this.responseText);
getData(jsondata);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
// This function is used to extract the received data
function getData(data) {
// This is the question:
question = data.results[0].question;
// This is the question type eg. multiple choice
type = data.results[0].type;
// This is the correct answer
correctAnswer = data.results[0].correct_answer;
// These are the three incorrect answers
incorrect1 = data.results[0].incorrect_answers[0];
incorrect2 = data.results[0].incorrect_answers[1];
incorrect3 = data.results[0].incorrect_answers[2];
// randomly select answer and other options and place in array
// then display elements from array on the buttons
var randoms = []; // an array to store unique random numbers
var random;
// loop runs four times...
for(i=0; i < 4; i++){
// generates a random number between 0 and 3
random = Math.floor(Math.random() * 4);
// checks if random number already in array...
while(randoms.includes(random)){
// generates another random number
random = Math.floor(Math.random() * 4);
}
// adds random number to array
randoms.push(random);
}
var options = [];
console.log(randoms);
options[randoms[0]] = correctAnswer;
options[randoms[1]] = incorrect1;
options[randoms[2]] = incorrect2;
options[randoms[3]] = incorrect3;
console.log(options);
// This displays the question and answer options
document.getElementById("trivia").innerHTML = question;
for(i=0; i < options.length; i++){
document.getElementById("trivia").innerHTML += "<br><button onclick='checkAnswer(\""+options[i]+"\", this)'>" + options[i] + "</button>";
}
}
function checkAnswer(selected, element){
console.log("User selected: " + selected);
console.log("The correct answer is: " + correctAnswer);
if(selected == correctAnswer){
score++;
console.log("You got it right!");
element.style.background = "green";
setTimeout(function(){
getNewQuestion();
}, 2000);
}
else{
livesTaken ++;
console.log("Sorry, that's incorrect");
element.style.background = "red";
if(livesTaken ==3){
quizFailed();
}else{
setTimeout(function(){
getNewQuestion();
}, 450);
}
}
console.log(score)
console.log(livesTaken)
}
function getNewQuestion(){
document.getElementById("score").style.display = "block";
document.getElementById("score").style.float = "right";
document.getElementById("trivia").style.float = "left";
document.getElementById("score").style.align = "right";
document.getElementById("score").innerHTML = "score:" + score;
document.getElementById("trivia").style.display = "block";
document.getElementById("endingText").style.display = "none";
// This requests the data
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var jsondata = JSON.parse(this.responseText);
getData(jsondata);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
} getNewQuestion()
function quizFailed(){
document.getElementById("endingText").style.display = "block"
document.getElementById("score").style.display = "none"
document.getElementById("trivia").style.display = "none"
document.getElementById("endingText").innerHTML = "You have run out of lives, you scored " + score + " pretty bad ngl" + " <button onClick = getNewQuestion() >click to restart</button>"
score = 0;
livesTaken = 0;
}
document.getElementById("score")
<html>
<head>
<link rel="stylesheet" href="Actualquiz.css">
<title>Sport Quiz (Medium)</title>
<meta charset="utf-8" />
<script src="script.js"></script>
<div id="trivia"></div>
<div id ="endingText"></div>
<div id ="score"></div>
</head>
<body>
</body>
</html>
If this is the line where you create the btns
for(i=0; i < options.length; i++){
document.getElementById("trivia").innerHTML += "<br><button onclick='checkAnswer(\""+options[i]+"\", this)'>" + options[i] + "</button>";
}
I suggest you to opt for another way, something like this would be a bit better.
for(i=0; i < options.length; i++) {
let btn = document.createElement("button");
// You can now style it like so
btn.style.backgroundColor = "blue" // This is an example, you can use any css styling.
btn.style.padding: 0.7rem 2rem;
btn.style.color = "white";
btn.style.marginTop = ".4rem";
btn.setAttribute("onclick", `checkAnswer("${options[i]}", this)`);
btn.innerHTML = options[i];
let br = document.createElement("br");
document.getElementById("trivia").append(br, btn); // You can now use the trivia div as a container for the generated button and your br
}
}
But as you can see there's a lot of extra code to just style the button, so what I'd do is create a class with the preferred stylings, and apply it in the js, like so:
JS file
for(i=0; i < options.length; i++) {
let btn = document.createElement("button");
let br = document.createElement("br");
btn.classList.add("trivia-btn"); // We're adding the class here
btn.setAttribute("onclick", `checkAnswer("${options[i]}", this)`);
btn.innerHTML = options[i];
document.getElementById("trivia").append(br, btn); // You can now use the trivia div as a container for the generated button and your br
}
}
CSS file
.trivia-btn {
background-color: "blue";
padding: 0.7rem 2rem;
color: white;
margin-top: 0.4rem;
}
My css example is a bit ugly but of course you can choose any css styling you want, or a framework to use premade classes.
I'm trying to build a quiz with more than one questions and each get 4 options with only 1 good answer.
I built an HTML empty container, so thank to JS the next question can upload itself when the answer has been submitted. But only the question appear, and none of the 4 options.
I'm using this code on JS, could you help me to find the error please?
var currentQuestion = 0;
var score = 0;
var totQuestionScore = questions.length;
var container = document.getElementById('quizContainer');
var questionEl = document.getElementById('question');
var opt1 = document.getElementById('opt1');
var opt2 = document.getElementById('opt2');
var opt3 = document.getElementById('opt3');
var opt4 = document.getElementById('opt4');
var nextButton = document.getElementById('nextButton');
var resultCont = document.getElementById('result');
function loadQuestion (questionIndex) {
var q = questions[questionIndex];
questionEl.textContent = q.question;
opt1.textcontent = q.option1;
opt2.textcontent = q.option2;
opt3.textcontent = q.option3;
opt4.textcontent = q.option4;
};
function loadNextQuestion () {
var selectOption = document.querySelector('input [type=radio]:checked');
if(!selectOption){
alert('Please select your answer.');
return;
}
var answer = selectOption.value;
if(questions[currentQuestion].answer == answer){
score += 10;
}
selectOption.checked = false;
currentQuestion++;
if(currentQuestion == totQuestions - 4){
nextButton.textContent = 'Finish';
}
if(currentQuestion == totQuestions){
container.style.display = 'none';
resultCont.style.display = '';
resultCont.textcontent = 'Your score is' + score + 'out of 4';
return
}
loadQuestion(currentQuestion);
}
loadQuestion(currentQuestion);
Shouldn't opt1.textcontent be opt1.textContent? Remember that JavaScript is case sensitive.
I am trying to create a score keeper display.
I want to keep track of the score using html and javascript. I have everything figured out I think but I can't figure out why the line doesn't break here.
Relevant code:
var br = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(br);
scorechart.appendChild(nc);
if(tot) {
scorechart.appendChild(br);
scorechart.appendChild(nes);
scorechart.appendChild(br);
scorechart.appendChild(tot);
}
(For a full view: https://hastebin.com/osuduluvaj.js)
It breaks for everything but the "------" part: https://media.discordapp.net/attachments/240883852350980096/497957073481629696/sAAAAASUVORK5CYII.png
(I cant upload images yet as a new member)
Thank you :)
document.createElement() creates a single element, which you can only append to the DOM once. If you want to reuse the <br> element you created, you need to clone it and you can insert the cloned copy into the DOM. See: Node.cloneNode().
var score = [];
var scoreadd_button = document.querySelector('#scoreadd-button');
var scoreadd_input = document.querySelector('#scoreadd-input');
let sc1 = 0;
let sc2 = 0;
var scorechart = document.querySelector('.scores');
function totalScores() {
var i;
var sum = 0;
for (i = 0; i < score.length; i++) {
sum += score[i];
}
return sum;
}
function newScore(amm) {
score.push(amm);
if (!score[1]) {
var nc = document.createTextNode(amm)
} else {
var nc = document.createTextNode(" + " + amm);
}
if (sc1 == 0) {
sc1 = amm;
} else {
sc2 = amm;
}
if (sc2 != 0) {
var tot = document.createTextNode("= " + totalScores());
sc1 = amm;
sc2 = 0;
}
var br = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(nc);
if (tot) {
scorechart.appendChild(br.cloneNode(true));
scorechart.appendChild(nes);
scorechart.appendChild(br.cloneNode(true));
scorechart.appendChild(tot);
}
}
scoreadd_button.addEventListener('click', function() {
var amm = scoreadd_input.value;
newScore(parseInt(amm, 10));
});
<button id="scoreadd-button">button</button>
<input type="text" id="scoreadd-input" />
<div class="scores"></div>
Okay so I fixed the issue by instead of using a variable just creating the element in the statement.
var nes = document.createTextNode("---------");
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(nc);
if(tot) {
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(nes);
scorechart.appendChild(document.createElement("br"));
scorechart.appendChild(tot);
}
Thank you :)
You just need to defined unique variables for each new created element on javascript, otherwise they will counted as one.
This code should works
var scorechart = document.querySelector('.scores');
var br = document.createElement("br");
var br2 = document.createElement("br");
var nes = document.createTextNode("---------");
scorechart.appendChild(br);
scorechart.appendChild(nes);
scorechart.appendChild(br2);
<span class="scores">
text before
</span>
after text