data attribute grouped by value calculate sum of other data attribute - javascript

I am trying to calculate all the huishoudens that are in each provincie. For this question I created a fiddle which can be found here: http://jsfiddle.net/Lyf1sak3/1/
With this sample data:
<div data-provincie="Noord-Holland" data-huishoudens="102"></div>
<div data-provincie="Noord-Holland" data-huishoudens="1250"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="956"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="235"></div>
<div data-provincie="Groningen" data-huishoudens="495"></div>
<div data-provincie="Groningen" data-huishoudens="55"></div>
<div data-provincie="Groningen" data-huishoudens="247"></div>
<div data-provincie="Utrecht" data-huishoudens="123"></div>
<div data-provincie="Utrecht" data-huishoudens="675"></div>
And this code:
var provincies = {},
provincie;
sum = 0;
$('*[data-provincie]').each(function(i, el){
provincie = $(el).data('provincie');
if (provincies.hasOwnProperty(provincie)) {
provincies[provincie] += 1;
sum += $(this).data('huishoudens');
}
else {
provincies[provincie] = 1;
}
});
// print results
$('#result').append('<hr>');
for(var key in provincies){
$('#result').append(key + ' (' + provincies[key] + '|' + sum + ')<br>');
}
I am grouping each provincie by its own property and now I just need to calculate the other data attribute, but I am completely stuck here. I am getting either the result 675 which is the last div in the sample data or I get 2462 and I have no clue how it gets that number.
What do I need to modify to get this result:
Noord-Holland (2|1352)
Zuid-Holland (2|1191)
Groningen (3|797)
Utrecht (2|798)
Whatever answer you give it is really appreciated but please don't post answers where it requires to hard code the names of provincie like $('*[data-provincie="Noord-Holland"]');

If you know provincie before only you can create an array with all provincie and then you can use this as a key to compare it with all the div if matches you can add same to sum variable and finally append final result to your result div.
Demo Code :
//all data provinces
//var json_ = ["Noord-Holland", "Zuid-Holland", "Groningen", "Utrecht"]
var json_ = [];
$('*[data-provincie]').each(function(i, el) {
//check if in array or not
if ($.inArray($(this).data('provincie'), json_) < 0) {
json_.push($(this).data('provincie'));//push same
}
});
console.log(json_)
sum = 0;
count = 0;
//loop through keys
for (var key in json_) {
$('*[data-provincie]').each(function(i, el) {
var provincie = $(el).data('provincie');
//if key matches
if (json_[key] == provincie) {
sum += $(el).data('huishoudens');
count++;
}
});
//append result
$('#result').append(count + ' (' + json_[key] + '|' + sum + ')<br/>')
count = 0;
sum = 0 //change sum to 0 again
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-provincie="Noord-Holland" data-huishoudens="102"></div>
<div data-provincie="Noord-Holland" data-huishoudens="1250"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="956"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="235"></div>
<div data-provincie="Groningen" data-huishoudens="495"></div>
<div data-provincie="Groningen" data-huishoudens="55"></div>
<div data-provincie="Groningen" data-huishoudens="247"></div>
<div data-provincie="Utrecht" data-huishoudens="123"></div>
<div data-provincie="Utrecht" data-huishoudens="675"></div>
<div id="result"></div>

You could modify the function like,
Get the count attributes like,
var count = parseInt($(this).data('huishoudens'));
Then inside the condition assign it like,
if (provincies.hasOwnProperty(provincie)) {
provincies[provincie]["sum"] += count;
}
else {
provincies[provincie] = {"sum": count};
}
Working Snippet:
var provincies = {},
provincie;
sum = 0;
$('*[data-provincie]').each(function(i, el){
provincie = $(el).data('provincie');
var count = parseInt($(this).data('huishoudens'));
if (provincies.hasOwnProperty(provincie)) {
provincies[provincie]["sum"] += count;
provincies[provincie]["provinceCount"] += 1;
}
else {
provincies[provincie] = {"sum": count, "provinceCount": 1};
}
});
// print results
$('#result').append('<hr>');
for(var key in provincies){
$('#result').append(key + ' (' + provincies[key].provinceCount + '|' + provincies[key].sum + ')<br>');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<title>Course example</title>
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<div data-provincie="Noord-Holland" data-huishoudens="102"></div>
<div data-provincie="Noord-Holland" data-huishoudens="1250"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="956"></div>
<div data-provincie="Zuid-Holland" data-huishoudens="235"></div>
<div data-provincie="Groningen" data-huishoudens="495"></div>
<div data-provincie="Groningen" data-huishoudens="55"></div>
<div data-provincie="Groningen" data-huishoudens="247"></div>
<div data-provincie="Utrecht" data-huishoudens="123"></div>
<div data-provincie="Utrecht" data-huishoudens="675"></div>
<div id="result"></div>
</body>
</html>

Related

Show javascript function output in html

My JavaScript contains two functions. One function gets a number from the user and returns a string that shows if the number is a prime or not and then store the number and the result in an array.
results = new Array();
i = 0;
function isPrime(num) {
flag = false;
if (num > 1) {
for (i = 2; i < num; i++) {
if (num % i == 0) {
flag = true;
break;
}
}
}
return !flag;
}
function getNumberPrime(number) {
condition = (isPrime(number)) ? ('is') : ('is not');
console.log('' + number + ' ' + condition + ' prime');
dict = {}
dict['number'] = number
dict['isPrime'] = isPrime(number);
results.push(dict);
}
function getAll() {
for (i = 0; i < results.length; i++) {
condition = (results[i]['isPrime']) ? ('is') : ('is not');
number = results[i]['number']
console.log('' + number + ' ' + condition + ' prime');
}
}
My HTML has an input and two buttons. One button returns the output of the first function and the second should show the items of array.
<!DOCTYPE html>
<html lang="fa">
<head>
<title>Prime Number</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="prime.js"></script>
</head>
<body>
<div class="container">
<h2>Find Prime Numbers</h2>
<form>
<div class="form-group">
<label class="control-label col-sm-2">Numbers:</label>
<div class="col-sm-10">
<input class="form-control" id="inp" name="nums" style="margin-left: -11%">
</div>
</div>
<button type="submit" class="btn btn-default" style=" margin-top: 2%;" onclick="getNumberPrime()">Check</button>
<button type="submit" class="btn btn-default" style="margin-top: 2%;" onclick="document.getElementById('showprime').innerHTML =getAll()">Show Result</button>
<p id="showprime"></p>
</form>
</div>
</body>
</html>
But the first button doesn't work and I don't know how to implement the second button.
Prime numbers must be blue and none primes must be red.
First: Your buttons need to have type="button" to prevent a reload because of the submit.
Your function getNumberPrime() wants a parameter number which you aren't offering in your inline event handler. Therefor you should get the number in that function by selecting the input and getting its value:
let number = document.querySelector('#inp').value;
Your function getAll() doesn't return anything and therefor the result isn't inserted in #showprime. Instead of loging the values to the console you could add them to an output string and return that string after the for loop:
let output = '';
for (i = 0; i < results.length; i++) {
...
output += number + ' ' + condition + ' prime<br>';
}
return output;
If you want the output to be colored you could wrap each result in a paragraph tag and give it a class dependent on the condition. In this case #showprime should be container element like a div. The class would be styled with CSS.
Inside the for loop:
check = (results[i]['isPrime']) ? true : false;
condition = check ? ('is') : ('is not');
...
output += '<p class=' + check + '>' + number + ' ' + condition + ' prime</p>';
In your CSS-file:
.true {
color: blue;
}
.false {
color: red;
}
Last: It's better to devide Javascript and HTML and not to use inline event handlers. Therefor you should change this:
<button ... onclick="getNumberPrime()">Check</button>
<button ... onclick="document.getElementById('showprime').innerHTML = getAll()">Show Result</button>
to this:
<button id="check" ...>Check</button>
<button id="show" ...>Show Result</button>
document.querySelector('#check').addEventListener('click', getNumberPrime);
document.querySelector('#show').addEventListener('click', function() {
document.getElementById('showprime').innerHTML = getAll();
});
Working example:
results = new Array();
i = 0;
function isPrime(num) {
flag = false;
if (num > 1) {
for (i = 2; i < num; i++) {
if (num % i == 0) {
flag = true;
break;
}
}
}
return !flag;
}
function getNumberPrime() {
let number = document.querySelector('#inp').value;
condition = (isPrime(number)) ? ('is') : ('is not');
console.log('' + number + ' ' + condition + ' prime');
dict = {}
dict['number'] = number
dict['isPrime'] = isPrime(number);
results.push(dict);
}
function getAll() {
let output = '';
for (i = 0; i < results.length; i++) {
check = (results[i]['isPrime']) ? true : false;
condition = check ? ('is') : ('is not');
number = results[i]['number'];
output += '<p class=' + check + '>' + number + ' ' + condition + ' prime</p>';
}
return output;
}
document.querySelector('#check').addEventListener('click', getNumberPrime);
document.querySelector('#show').addEventListener('click', function() {
document.getElementById('showprime').innerHTML = getAll();
});
.true {
color: blue;
}
.false {
color: red;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
<h2>Find Prime Numbers</h2>
<form>
<div class="form-group">
<label class="control-label col-sm-2">Numbers:</label>
<div class="col-sm-10">
<input class="form-control" id="inp" name="nums" style="margin-left: -11%">
</div>
</div>
<button id="check" type="button" class="btn btn-default" style=" margin-top: 2%;">Check</button>
<button id="show" type="button" class="btn btn-default" style="margin-top: 2%;">Show Result</button>
<div id="showprime"></div>
</form>
</div>

Javascript: Don't sum elements that are not visible

I'm trying to sum a list of values from HTML elements, but I want to EXCLUDE values are that hidden using pure JS.
HTML:
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>
JS:
window.addEventListener('load', function() {
let gramdivs = document.getElementsByClassName("grams");
let milligramdivs = document.getElementsByClassName("milligrams");
var total = 0;
for (let item of gramdivs) {
let itemPrice=parseFloat(item.textContent);
total += itemPrice;
}
for (let item of milligramdivs) {
let itemPrice=parseFloat(item.textContent);
total = total + itemPrice / 1000;
}
document.getElementsByClassName("servings")[0].innerText = total.toFixed(3);
})
https://jsfiddle.net/smhok7yd/2/
In the JS Fiddle, you can see that all the numbers are being added, including the hidden one.
The correct output should be 1.102.
Please note that I cannot change the hierarchy of the HTML.
I am relatively new to JS and have been trying to find a solution all day.
When iterating over elements, check to see if their offsetParent is null - if so, they're not visible:
const getClassValues = (className, multiplier = 1) => [...document.getElementsByClassName(className)]
.filter(elm => elm.offsetParent !== null)
.reduce((a, b) => a + (b.textContent * multiplier), 0);
document.querySelector('.servings').textContent = (
getClassValues('grams') + getClassValues('milligrams', 0.001)
);
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>
If you set display: none; on the specific grams div you can check for the property before adding it to the total:
https://jsfiddle.net/et6wzph2/28/
function isVisible(e) {
return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}
window.addEventListener('load', function() {
let gramdivs = document.getElementsByClassName("grams");
let milligramdivs = document.getElementsByClassName("milligrams");
let total = 0;
for (let item of gramdivs) {
if(!isVisible(item)) continue;
let itemPrice = parseFloat(item.textContent);
total += itemPrice;
}
for (let item of milligramdivs) {
if(!isVisible(item)) continue;
let itemPrice = parseFloat(item.textContent);
total = total + itemPrice / 1000;
}
document.getElementsByClassName("servings")[0].innerText = total.toFixed(3);
})
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>

javascript adding new buildings

I'm not sure how to add a new building by array. I'm a beginner javascript person.
I added saving/loading among other things to the back end but the client side is giving me issues for some reason.
I think it has something to do with me not under standing arrays correctly but if you could point me in the right direction i would love to learn.
I want to add a second building called
loadbuilding("taco stand")
Here is the code:
var Timer = window.setInterval(function() {
Tick()
}, 1000);
var buildings = [];
//The object declaration for game saves
function GameSave() {
this.money = 0;
this.buildings = [];
for (var i = 0; i < buildings.length; i++) {
this.buildings[i] = 0;
}
}
//The object declaration for buildings
function Building() {
this.Name = "Lemonade Stand";
this.Cost = 10;
this.PerSec = 1;
}
//The function to initialise all buildings
function InitBuildings() {
LoadBuilding("Lemonade Stand", 10, 1);
LoadBuilding("Taco Stand", 100, 1);
}
//The function to automatically load a building into the buildings array
function LoadBuilding(name, cost, persec) {
var cur = buildings.length;
buildings[cur] = new Building();
buildings[cur].Name = name;
buildings[cur].Cost = cost;
buildings[cur].PerSec = persec;
}
//The function used to gather money
function GatherMoney() {
game.money++; //++ tells javascript to add 1 to the variable
//Display the player's current money
document.getElementById("money").innerHTML = game.money;
}
//The function that gets run every second
function Tick() {
for (var i = 0; i < buildings.length; i++) {
game.money += game.buildings[i] * buildings[i].PerSec;
}
document.getElementById("money").innerHTML = game.money;
}
//The function to buy a lemonade stand
function Build(id) {
if (game.money >= buildings[id].Cost) { //Check if the player has enough money, then subtract it and add a new building if they do
game.money -= buildings[id].Cost;
game.buildings[id] = game.buildings[id] + 1;
document.getElementById("money").innerHTML = game.money;
document.getElementById("Building1Qty").innerHTML = game.buildings[id];
}
}
//Run this code once the page has loaded fully
window.onload = function() {
InitBuildings();
window.game = new GameSave();
};
<!--Pleae refer to Lesson 9.txt for a full description on this lesson -->
<html>
<head>
<title>Basic Incremental Game</title>
<link rel="stylesheet" type="text/css" href="css/Incremental.css">
<script src="js/Incremental.js"></script>
</head>
<body>
<div id="page">
<div id="header">
<div id="game-title">
Basic Incremental Game
</div>
</div>
<div id="content">
<div id="stats" class="block">
<div class="label">Money:</div>
<div id="money" class="label">0</div>
</div>
<div id="clickables" class="block">
<input type="button" value="Click Me!" onclick="GatherMoney();">
</div>
<div id="buildings" class="block">
<div id="Building1">
<input type="button" value="Lemonade Stand" onclick="Build(0);">
<div>
<div class="label">Cost:</div>
<div id="Building1Cost" class="label">10</div>
</div>
<div>
<div class="label">Per Sec:</div>
<div id="Building1PerSec" class="label">1</div>
</div>
<div>
<div class="label">Quantity:</div>
<div id="Building1Qty" class="label">0</div>
</div>
</div>
<div id="Building2">
<input type="button" value="Taco Stand" onclick="Build(1);">
<div>
<div class="label">Cost:</div>
<div id="Building2Cost" class="label">10</div>
</div>
<div>
<div class="label">Per Sec:</div>
<div id="Building2PerSec" class="label">1</div>
</div>
<div>
<div class="label">Quantity:</div>
<div id="Building2Qty" class="label">0</div>
</div>
</div>
</div>
<div id="upgrades" class="block">
This is where our upgrades will go!
</div>
</div>
</body>
EDIT:
i tried changing the but tit didnt work
buildings[]
to
buildings["Lemonade Stand", "Taco Stand"]
How about,
LoadBuilding("myBuilding", 12, 1);
Because you have this factory function,
function LoadBuilding(name, cost, persec) {
var cur = buildings.length;
buildings[cur] = new Building();
buildings[cur].Name = name;
buildings[cur].Cost = cost;
buildings[cur].PerSec = persec;
}
You could build an array of Building objects then iterate through them using a while loop.
See JSFIDDLE, or attached code.
Let me know if that helps.
class Building {
constructor(name, cost, persec) {
this.name = name;
this.cost = cost;
this.persec = persec;
}
}
var buildings = [];
buildings.push(new Building('Building One', '$10', '1'));
buildings.push(new Building('Building Two', '$20', '0.5'));
buildings.push(new Building('Building Three', '$25', '2'));
var count = 0;
while(count < buildings.length) {
document.getElementById('stores').innerHTML += '<p>' + buildings[count].name + '<br />' + buildings[count].cost + '<br />' + buildings[count].persec + '</p>';
count++;
}
<div id="stores">
</div>

How can I compare numbers in an object against text in the dom?

I have a function that picks a random number from 1 - 6 and then appends it to the DOM. I am trying to compare that number to numbers that are currently in a div in the DOM. So I stored those numbers in a var called cards. When I console.log() the var it returns an array. I converted that array to a string and then I retrieved the text. What is the best way to go about comparing the numbers? Should I do a for loop and if any of those numbers match one of the random numbers drawn take some action? Can some one show me an example of doing this? My code is below.
$(function(){
function dice1(){
var randomNumber = Math.floor(Math.random() * 6) + 1;
$('#instructions').text(randomNumber);
return randomNumber;
}
function dice2(){
var randomNumber = Math.floor(Math.random() * 6) + 1;
$('#instructions2').text(randomNumber);
return randomNumber;
}
$('#dice1').click(function() {
dice1();
var cards = $('#cards div');
var single = cards.toString();
console.log(cards.text());
if ($('#instructions').text() == cards.text()) {
console.log('match');
}
});
$('#dice2').click(function(){
dice2();
});
});
<section id="container">
<div id="cards">
<div id="1">1</div>
<div id="2">2</div>
<div id="3">3</div>
<div id="4">4</div>
<div id="5">5</div>
<div id="6">6</div>
<div id="7">7</div>
<div id="8">8</div>
<div id="9">9</div>
</div>
<section>
<button id="dice1">Roll dice1</button>
<button id="dice2">Roll dice2</button>
<div id="instructions"></div>
<div id="instructions2"></div>
</section>
</section>
Why not store the cards directly in an array like this:
var cards = [1,2,3,4,5,6,7,8,9];
Then do the comparison like this:
var number = parseInt($("#instructions").text());
if(cards.indexOf(number) >= 0)
console.log("Number found");
else
console.log("Number not found");
If you really want to do it your way, you can do this:
$(".cards div").each(function(){
var number = parseInt($("#instructions").text());
var card = parseInt($(this).text());
if(card == number)
console.log("Number found");
});
Well you could indeed do it with a for loop:
$('#dice1').click(function() {
var random_number = dice1();
var cards = $('#cards div');
for(var i = 0; i < cards.length; i++ ) {
if($(this).html() == random_number) {
alert('Do something!');
}
}
console.log(cards.text());
if ($('#instructions').text() == cards.text()) {
console.log('match');
}
});
But you could also directly match to the ID you've set:
$('#dice1').click(function() {
var random_number = dice1();
var card = $('#cards div[id='+random_number+']');
if(card.length > 0) {
alert('Do something!');
}
});
Remember though, that the ID attribute can not start with a number, so I would create my own attribute here:
<div id="cards">
<div data-number="1">1</div>
<div data-number="2">2</div>
<div data-number="3">3</div>
<div data-number="4">4</div>
<div data-number="5">5</div>
<div data-number="6">6</div>
<div data-number="7">7</div>
<div data-number="8">8</div>
<div data-number="9">9</div>
</div>
And then use jQuery like so:
$('#dice1').click(function() {
var random_number = dice1();
var card = $('#cards div[data-number='+random_number+']');
if(card.length > 0) {
alert('Do something!');
}
});
You can do something like this:
New JS:
$(function () {
function dice1() {
var randomNumber = Math.floor(Math.random() * 6) + 1;
$('#instructions').text(randomNumber);
return randomNumber;
}
function dice2() {
var randomNumber = Math.floor(Math.random() * 6) + 1;
$('#instructions2').text(randomNumber);
return randomNumber;
}
$('#dice1').click(function () {
var num1 = dice1();
$('#cards div').each(function (index,item) {
if ($(item).text() == num1) {
$(item).css("color", "red");
}
});
$('#dice2').click(function () {
dice2();
});
});
});
Fiddle example
I just learned a way of doing it that solves it dynamically and personally I think it's easier to follow.
<div data-hook="cards" id="cards">
<div data-value="1" id="1">1</div>
<div data-value="2" id="2">2</div>
<div data-value="3" id="3">3</div>
<div data-value="4" id="4">4</div>
<div data-value="5" id="5">5</div>
<div data-value="6" id="6">6</div>
<div data-value="7" id="7">7</div>
<div data-value="8" id="8">8</div>
<div data-value="9" id="9">9</div>
</div>
$(function(){
function dice1(){
var randomNumber = Math.floor(Math.random() * 6) + 1;
$('#instructions').text(randomNumber);
return randomNumber;
}
$('#dice1').click(function() {
dice1();
$('[data-hook=cards] [data-value]').find('#instructions'); //'data-hook=cards] [data-value]' selects the element by attr'
var rolledNum = $('#instructions').text(),
selector = '[data-value=' + rolledNum + ']',
$card = $('[data-hook=cards]').find(selector);
//Instead of using an $.each or for loop to compare two numbers I am taking the random number and finding it on the div and then modifying the div.
console.log($card);
$card.css({'opacity':.2});
});
});

Start the function again on click

I've created a quiz which takes answer from user, checks it and shows whether the answer is correct or incorrect. There are 8 questions in it. I want to start the quiz again once all these 8 questions are completed. How do I do it ?
This is my code
HTML
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<div class="qscore">
<span id="scr"></span>
</div>
<center>
<div class="qstart">start</div>
</center>
<div class="qarea">
<div class="question">father</div>
<div class="canswer">Vater</div>
<textarea class="abox" placeholder="Translate the text to German"></textarea>
</div>
<div class="qarea">
<div class="question">My father is baba</div>
<div class="canswer">Mein Vater ist baba</div>
<textarea class="abox"></textarea>
</div>
<div class="qarea">
<div class="question">Land</div>
<div class="canswer">Land</div>
<textarea class="abox"></textarea>
</div>
<div class="qarea">
<div class="question">My Mother</div>
<div class="canswer">Meine Mutter</div>
<textarea class="abox"></textarea>
</div>
<div class="qarea">
<div class="question">Brother</div>
<div class="canswer">Bruder</div>
<textarea class="abox" placeholder="Translate the text to German"></textarea>
</div>
<div class="qarea">
<div class="question">City</div>
<div class="canswer">Stadt</div>
<textarea class="abox"></textarea>
</div>
<div class="qarea">
<div class="question">Woman</div>
<div class="canswer">Frau</div>
<textarea class="abox"></textarea>
</div>
<div class="qarea">
<div class="question">Man</div>
<div class="canswer">Mann</div>
<textarea class="abox"></textarea>
</div>
<div class="qsubmit">submit</div>
<div class="qcontinue">continue</div>
<div class="correct">Correct</div>
<div class="incorrect">Incorrect</div>
<div class="qrating"></div>
<div class="startagain">startagain</div>
Jquery
$(document).ready(function () {
//declare variables
var qarea = $(".qarea");
var totalqarea = qarea.length;
var startagain = $(".startagain");
var canswer = $(".canswer")
var qsubmit = $(".qsubmit");
var qcontinue = $(".qcontinue");
var qscore = $(".qscore");
var counter = 0;
//hide unrequired
qcontinue.hide();
qsubmit.hide();
startagain.hide();
$("startagain")
$(".correct,.incorrect").hide();
qsubmit.hide();
$(".qscore,.qrating").hide();
$(".canswer").hide();
qarea.hide();
var qstart = $(".qstart");
//intiate click on start
qstart.click(function () {
$(".correct,.incorrect").hide();
var counter = 0;
$(".abox").val('');
qsubmit.show();
$(".qrating").hide();
qarea.eq(counter).show();
qstart.hide();
var i = 0;
$(".qscore").text("Score:" + i + "/" + totalqarea).show();
//loop(); function loop()
//initate submit
qsubmit.bind("click", function () {
qstart.hide();
var ma = canswer.eq(counter).text();
var mal = ma.replace(/^\s+|\s+$|\s+(?=\s)/g, "").replace("ü", "u").replace("ä", "ä").replace("ö", "o").replace("ß", "ss").replace("Ä", "A").replace("Ö", "O").replace("Ü", "U").toLowerCase();
var masplt = mal.split(" ");
var ua = $("textarea").eq(counter).val();
var ual = ua.replace(/^\s+|\s+$|\s+(?=\s)/g, "").replace("ü", "u").replace("ä", "a").replace("ö", "o").replace("ß", "ss").replace("Ä", "A").replace("Ö", "O").replace("Ü", "U").toLowerCase();
var uasplt = ual.split(" ");
var n = mal.localeCompare(ual);
counter = counter + 1;
qarea.eq(counter - 1).hide();
// checks correct answer and gives score
if (n == 0) {
var praise = ["Well Done !!..You got it right !! ", "Nice....You got it right!! ", "Perfect....You got it right!! "]
var r = Math.round(Math.random());
$(".correct").text(praise[r] + " : The answer is " + ma).show();
i = i + 1;
$(".qscore").text("Score:" + i + "/" + totalqarea).show();
//gives incorrect
} else {
qarea.hide();
$(".incorrect").text("Oops....the correct answer is....");
for (var j = 0; j < masplt.length; j++) {
if (masplt[j] !== uasplt[j]) {
$(".incorrect").append(" <span style='font-size:32px'>" + masplt[j] + "</span>").show();
} else {
$(".incorrect").append(" " + masplt[j]).show();
}
}
//$(".incorrect").text("Oops....the correct answer is " + ma).show();
}
qsubmit.hide();
qcontinue.show();
qcontinue.click(function () {
qarea.eq(counter).show();
$(".correct,.incorrect").hide();
qsubmit.show();
qcontinue.hide();
})
if (totalqarea == counter) {
qcontinue.show();
qcontinue.click(function () {
qsubmit.hide();
qstart.text("start again").show();
if (i < (totalqarea - 6) && i < (totalqarea - 4)) {
$(".qrating").text("Your scored " + i + "/" + totalqarea + ". ...You need some more practice. Try it again.").show();
} else if (i > (totalqarea - 4) && i < (totalqarea - 2)) {
$(".qrating").text("Your scored " + i + "/" + totalqarea + "....Not bad !!").show();
} else {
$(".qrating").html("Your scored " + i + "/" + totalqarea + "....Wünderbar !! Keep it up !!").show();
}
$("#scr").text('');
})
qstart.click(function () {
})
}
})
})
})
Here is the fiddle
http://jsfiddle.net/qFa39/11/
Thanks.
Currently you're declaring 2 different counter variables. The one declared under the "declare variables" comment and the one declared within qstart.click(). To fix your problem replace the line inside qstart.click() (line 31 in the jsfiddle) with:
counter = 0;
No var preceeding it. This way javascript will understand you are refering to the first counter and not creating a new var called counter. Have a read up on scope in javascript for more info.
Although this does reveal another bug with our code where the 'Start Again' button does then not hide properly.

Categories