HTML5 Javascript, Updating a text using arrays - javascript

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.

Related

Js returns 0 instead on value

function TipCalc(){
var Amount = Number(document.getElementById("billamt").innerHTML);
var TipPercent = Number(document.getElementById("tipper").innerHTML);
var Answer = 0;
alert(Amount,TipPercent);
if (TipPercent > 0){
Answer = Amount * TipPercent;
document.getElementById("ac").innerHTML ="$ "+ Answer;
}
else{
document.getElementById("ac").innerHTML = "Error!!";
}
}
alert returns 0 instead of values
It's probably simple but i'm new to js
I am not completely sure on what it is you are trying to accomplish with the alert, is it for your reference on the code working or are you trying to calculate the values?
Either way I have modified your alert to show both values
TipCalc()
function TipCalc(){
var Amount = Number(document.getElementById("billant").innerHTML);
var TipPercent = Number(document.getElementById("tipper").innerHTML);
var Answer = 0;
alert(`Amount:${Amount}, TipPercent: ${TipPercent}`);
if (TipPercent > 0){
Answer = Amount * TipPercent;
document.getElementById("ac").innerHTML ="$"+ Answer;
}
else{
document.getElementById("ac").innerHTML = "Error!!";
}
}
function Number(elValue){
return parseInt(elValue);
}
<p id="billant">
42
</p>
<p id="tipper">
4
</p>
<div id="ac">
</div>

adding event listeners in Javascript is doubling my (simple) maths

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);
}

innerHTML but with multiple options to choose from

I am a fresh programmer and I'm trying to create my own quiz, I want to display only one set of a question and its answers at a time and would like to show a question counter. I am having trouble selection which one i want to display.
numberSpot.innerHTML = `Q${sequence}.${questionNumber}
I was trying to do something like this where sequence is equal to a variable and that variable is increased when you click next question. it wasn't working so i deleted the next question function to try and figure out what i could do.
//Questions and answers
class Question {
constructor(question, questionNumber, answer1, answer2, answer3, answer4, correctAnswer) {
this.question = question;
this.questionNumber = questionNumber;
this.answer1 = answer1;
this.answer2 = answer2;
this.answer3 = answer3;
this.answer4 = answer4;
this.correctAnswer = correctAnswer;
}
}
var q1 = new Question('How much do i weigh?', '1', '123lbs', '170lbs', '200lbs', '13lbs', '170lbs')
var q2 = new Question('how much do you weigh?', '2', '123lbs', '170lbs', '200lbs', '13lbs', '170lbs')
//the displaying function
var numberSpot = document.getElementById('qNumber');
var qSpot = document.getElementById('Question');
var answer1Spot = document.getElementById('answer1');
var answer2Spot = document.getElementById('answer2');
var answer3Spot = document.getElementById('answer3');
var answer4Spot = document.getElementById('answer4');
//score counter
//next question
This solution uses your single-container approach.
(...Although it also includes some hints as to how you could make a separate container for each question and simply keep all the containers hidden except the one containing the current question.)
class Question {
constructor(question, questionNumber, answer1, answer2, answer3, answer4, correctAnswer) {
this.question = question;
this.questionNumber = questionNumber;
this.answer1 = answer1;
this.answer2 = answer2;
this.answer3 = answer3;
this.answer4 = answer4;
this.correctAnswer = correctAnswer;
}
}
const
// Makes a short function name to get elements by id
getById = (id) => document.getElementById(id),
// Defines questions
q1 = new Question('How much do I weigh?', '1', '123lbs', '170lbs', '200lbs', '13lbs', '170lbs'),
q2 = new Question('how much do you weigh?', '2', '123lbs', '170lbs', '200lbs', '13lbs', '170lbs'),
// Selects HTML elements
container1 = getById('q1-container'), // HTML attributes should use lower case
numberSpot = getById('q-number'),
qSpot = getById('question'),
answer1Spot = getById('answer1'),
answer2Spot = getById('answer2'),
answer3Spot = getById('answer3'),
answer4Spot = getById('answer4');
// Inserts text into pre-selected elements
function populateElements(q){
numberSpot.textContent = q.questionNumber + ")";
qSpot.textContent = q.question;
answer1Spot.textContent = "a) " + q.answer1;
answer2Spot.textContent = "b) " + q.answer2;
answer3Spot.textContent = "c) " + q.answer3;
answer4Spot.textContent = "d) " + q.answer4;
}
// Stores questions in an array (not necessary, but may be more convenient)
const questions = [];
questions.push(q1, q2);
let currentQuestion = questions[0];
// Defines a function to get the next question in the array (untested)
const nextQuestion = () => {
const ind = questions.findIndex( (q) =>
q.questionNumber === currentQuestion.questionNumber
);
nextIfAny = (++ind < questions.length) ? questions[ind] : currentQuestion;
return nextIfAny;
};
// Shows a particular container depending on the current question
if(currentQuestion = q1){
container1.classList.remove("no-display");
}
// Shows a question in the single container
populateElements(currentQuestion);
.answer{ padding-left: 1em; }
.no-display{ display: none; }
<div id="q1-container">
<span id="q-number"></span>
<span id="question"></span>
<div id="answer1" class="answer"></div>
<div id="answer2" class="answer"></div>
<div id="answer3" class="answer"></div>
<div id="answer4" class="answer"></div>
</div>

Repopulating objects with a click

I'm attempting to repopulate my radio buttons with the next question that is stored in my array. I'm unsure of how to remove the current question and repopulate the radio buttons with the next question.
var questionsArray = [];
//Create counters for both correct answers and current question
var correctAnswers = 0;
var currentQuestion = 0;
//Contructor Function to create questions
function Question (question, choices, answer){
this.question = question;
this.choices = choices;
this.answer = answer;
}
//Question Creations
questionsArray.push(new Question(...
To append the questions to my radio buttons I've used this code:
$('.q_question').append(questionsArray[0]['question']);
//In order to be able to check what radio is click you have to change to value of the radio buttons to the correct answer.
$('.btn1').after(questionsArray[0]['choices'][0]);
$('.btn1').val(questionsArray[0]['choices'][0]);
$('.btn2').after(questionsArray[0]['choices'][1]);
$('.btn2').val(questionsArray[0]['choices'][1]);
$('.btn3').after(questionsArray[0]['choices'][2]);
$('.btn3').val(questionsArray[0]['choices'][2]);
$('.btn4').after(questionsArray[0]['choices'][3]);
$('.btn4').val(questionsArray[0]['choices'][3]);
To check the answers I've got with:
$('#submit').on('click', function(){
currentQuestion ++;
var answer = $('input[name="1"]:checked').val(); //By creating the answer variable we are able to store which radio button value is submitted.
if(answer == questionsArray[0]['answer']){
correctAnswers ++;
$('.jumbotron').append(answer + "?<br><br> That's correct! You have " + correctAnswers + " out of 10 correct!");
} else {
$('.jumbotron').append(answer+ "? <br><br> Oh dear, that's so so wrong! You have " + correctAnswers + " out of 10 correct");
}
return false;
});
I'm totally stuck now.
Here's an example of something you could do: Fiddle
Create a function to populate the question and options. Add <span> or <label> elements and change the html in them instead of just using .after().
function populateQuestion(index) {
$('.q_question').html(questionsArray[index]['question']);
for (var i = 0; i < 4; i++) {
$('.jumbotron').html('');
$('.btn' + (i + 1)).val(questionsArray[index]['choices'][i]).prop('checked', false);
$('.label' + (i + 1)).html(questionsArray[index]['choices'][i]);
}
}
Add an event listener for the "Continue" button that runs the function with the correct (updated) index:
$('.continue').on('click', function() {
populateQuestion(++currentQuestion);
});
Just be sure to remove currentQuestion++ from your submit handler.
I had the urge to restructure the questionnaire, so here is my proposal:
var questions = [];
questions.push({
question: "What does HTML stand for?",
choices: [
"Hyper Text Markup Language",
"High Text Main Language",
"Hyper Translated Modern Language"
],
answer: 0
});
questions.push({
question: "What does CSS stand for?",
choices: [
"C-Style-Source",
"Cascading Style Source",
"Cascading Style Sheets"
],
answer: 2
});
questions.push({
question: "What does JS stand for?",
choices: [
"JavaSource",
"JavaScript",
"JavaStuff"
],
answer: 1
});
// create question elements
for (var i = 0; i < questions.length; i++) {
var question = $('<div>').addClass('question');
question.append(
$('<div>').addClass('caption').text(questions[i].question)
);
var choices = $('<ul>').addClass('choices');
for (var n = 0; n < questions[i].choices.length; n++) {
var choice = $('<li>').addClass('choice');
choice.append(
$('<input>').attr('type', 'radio').attr('name', 'question' + i).val(n).attr('id', 'label_question' + i + '_' + n)
);
choice.append(
$('<label>').attr('for', 'label_question' + i + '_' + n).text(questions[i].choices[n])
);
choices.append(choice);
}
question.append(choices);
$('.questions').append(question);
}
// attach evaluation of answers
$('#submit').click(function() {
var result = $('#result');
var correctAnswers = 0;
for (var i = 0; i < questions.length; i++) {
if ( $('input[name="question' + i + '"]:checked').val() == questions[i].answer ) {
correctAnswers += 1;
}
}
result.text('You answered ' + correctAnswers + ' of ' + questions.length + ' questions correctly.').show();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="questions">
</div>
<button id="submit" type="button">
check answers
</button>
<div id="result" style="display: none;">
</div>

How to create a visual diff view like Stack Overflow does?

Stack Overflow's diff view is very good. I want to do this using javascript, but I don't know how to start, who can give some suggestion?
such as:
you can try google-diff-match-patch project ,this project offer robust algorithms to perform the operations required for synchronizing plain text.
Demo:http://jsfiddle.net/N6bAn/
Code:
<div class="test">
<div id="oldStr" class="text">the stackoverflow question and answer version control is very well,i want to do this use javascript,but i don't know how to start,who can give some suggestion?thanks</div>
<div id="newStr" class="text">Stack Overflow's diff view is very good. I want to do this using javascript,but i don't know how to start,who can give some suggestion?thanks</div>
</div>
<input type="button" value="GO" onclick="launch()" />
<div class="test">
<div class="text" id="outputOldStr"></div>
<div class="text" id="outputNewStr"></div>
</div>
<script type="text/javascript">
var dmp = new diff_match_patch();
function launch() {
var text1 = document.getElementById('oldStr').innerHTML;
var text2 = document.getElementById('newStr').innerHTML;
dmp.Diff_EditCost = 8;
var d = dmp.diff_main(text1, text2);
dmp.diff_cleanupEfficiency(d);
var oldStr = "", newStr = "";
for (var i = 0, j = d.length; i < j; i++) {
var arr=d[i];
if (arr[0] == 0) {
oldStr += arr[1];
newStr += arr[1];
} else if (arr[0] == -1) {
oldStr += "<span class='text-del'>" + arr[1] + "</span>";
} else {
newStr += "<span class='text-add'>" + arr[1] + "</span>";
}
}
document.getElementById('outputOldStr').innerHTML = oldStr;
document.getElementById('outputNewStr').innerHTML = newStr;
}
</script>
There are JavaScript libraries that does diff visualization. These are a few examples I found:
https://github.com/cemerick/jsdifflib
http://prettydiff.com/
I haven't tried any of them, so unfortunately I can't tell you which is most suited for you needs, but it might be worth checking them out.
Update
jsdifflib looks promising, there is a demo available that you could try.

Categories

Resources