in my while loop I was hoping it will keep prompting the user for entry unless I break out of the loop. However, once I get into my if block it wont to peform printToScreen(message) function unless I terminate the code.
Not sure what I am doing wrong here. I am expecting it to print message before continuing to prompt.
how can I fix this?
let message;
let search;
function printToScreen(message){
let outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function promptUser (){
search = prompt("Enter student name");
return search;
}
function searchStudent(){
while(true){
search =promptUser();
for(let i = 0; i<students.length; i++){
if(search.toLowerCase() === students[i].name.toLowerCase())
{
let student = students[i];
message = `<h4>Student: ${student.name}</h4>`;
message += `<p> Track: ${student.track}
<br> Achievements:${student.achievements}
<br> Points: ${student.points}
</p>`;
printToScreen(message);
}
else if( search ===null || search.toLowerCase() === 'quit'){
message = `<p>Thanks.Goodbye! </p>`;
printToScreen(message);
break;
}
else{
message = `<p> Student ${search} does not exist. Try Again!</p>`;
printToScreen(message);
}
}
}
}
searchStudent();
That's because the browser won't redraw the page while it is still computing some js.
What you could do is replace your while(true) by a recursive call in a setTimeout:
function searchStudent(){
search =promptUser();
for(let i = 0; i<students.length; i++){
if(search.toLowerCase() === students[i].name.toLowerCase())
{
let student = students[i];
message = `<h4>Student: ${student.name}</h4>`;
message += `<p> Track: ${student.track}
<br> Achievements:${student.achievements}
<br> Points: ${student.points}
</p>`;
printToScreen(message);
}
else if( search ===null || search.toLowerCase() === 'quit'){
message = `<p>Thanks.Goodbye! </p>`;
printToScreen(message);
break;
}
else{
message = `<p> Student ${search} does not exist. Try Again!</p>`;
printToScreen(message);
}
}
setTimeout(function(){
searchStudent();
},5);
}
searchStudent();
Ive been developing a Simon says game recently that adds to the score if you click the correct button which there are 3,
1) green 1
2) red 2
3) trick
I've noticed that when I run the game and click the appropriate buttons only one will add to the score whilst the other two subtract from it (Regardless of what the statement says). Im unsure why this is the case and was wondering if anyone had any insights). My thought is that the if functions don't seem to correlate to the new statement that is generated.
Any suggestions are appreciated,
var answers = [
"Simon says click red !",
"Simon says click green !",
"Simon says click 1 !",
"Simon says click 2 !",
"Click green",
"Click red",
"Click 1",
"Click 2!"
];
var score = 0;
var total = document.getElementById("score");
var statement = document.getElementById("instruct");
var randomStatement = answers[Math.floor(Math.random() * answers.length)];
function refresh(){
var randomStatement = answers[Math.floor(Math.random() * answers.length)];
statement.innerHTML = randomStatement;
}
function pressTrick(){
if(randomStatement === "Click green" || randomStatement === "Click red" || randomStatement === "Click 1" || randomStatement === "Click2!"){
score++;
total.style.color = "green";
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
} else {
total.style.color = "red";
score--;
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
}
}
function pressRed(){
if(randomStatement === "Simon says click red !" || randomStatement === "Simon says click 2 !"){
score++;
total.style.color = "green";
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
} else {
total.style.color = "red";
score--;
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
}}
function pressGreen(){
if(randomStatement === "Simon says click 1 !" || randomStatement === "Simon says click green !"){
score++;
total.style.color = "green";
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
} else {
total.style.color = "red";
score--;
total.innerHTML = "Total score: " + score;
setTimeout(refresh,900);
}}
function start(){
var i = 60;
var count = setInterval(timer,1000);
refresh();
function timer() {
var display = document.getElementById("timer");
var finished = document.getElementById("heading");
if(i < 1){
clearInterval(count);
finished.innerHTML = "Game Over! Your final Score is : " + score;
display.style.color = "red";
display.style.fontWeight = "bold";
document.body.style.backgroundColor = "black";
} else if(i <= 10) {
i--;
display.style.color = " red";
display.style.fontWeight = "bold";
display.innerHTML = i + " Seconds Left";
} else {
i--;
display.style.color = "green";
display.style.fontWeight = "bold";
display.innerHTML = i + " Seconds Left";
}}}
<html>
<head>
<title> Simon Says! </title>
<link rel = "stylesheet" href = "simonsays.css"/>
</head>
<body>
</br>
<h1> Test Your Reflexes! </h1>
<div id = "heading"; class = "h2"> Click on Simon to Begin! </div>
</br>
<img src = "boy.jpg" onclick = "start()"; onclick = "timer()"; onclick = "returnStatement";/>
</br>
<div id = "instruct" class="statement"></div>
</br>
<div class = "align">
<input type = "button" class = "button2" id = "button2" value = "1" onclick = "pressGreen()"; ></input>
<input type = "button" class = "button" id = "button" value = "2" onclick = "pressRed()"; ></input>
<input type = "button" class = "button3" id = "button3 " value = "Trick" onclick = "pressTrick()";></input>
</div>
</br>
<div id = "score" class = "score"><b> Score: </b></div>
<div id = "timer" class = "timer"><b> Time left: </b></div>
<script src = "simonsays.js"></script>
</body>
</html>
Thank you!
There's just one word too much: var. In
function refresh(){
var randomStatement = answers[Math.floor(Math.random() * answers.length)];
statement.innerHTML = randomStatement;
}
the var causes a new, local variable randomStatement to be defined, and the global randomStatement remains unchanged, so all comparisons in the rest of the program use the initial rather than the refreshed value of randomStatement. Drop the var here, and it works as expected.
This is the code I used for my shopping cart. When I use this code the problem is that when I click the clear button, and then I add another item, the previous Item that I cleared came back
I have tried to move around the saveCart function so it will properly do its job, but there are still no progress in solving the problem
This is the buttons to buy the Item ( I only show the button since probably the effect is only at here )
<input type="button" name="" value="B U Y" class="buyBut add-to-cart" data-name="Avocado & Brownie Cake" data-price="150000">
<input type="button" name="" value="B U Y" class="buyBut add-to-cart" data-name="Strawberry & Watermelon Cake" data-price="65000">
This is the space to show the items and the clear button
<table id="show-cart">
<br>
</table>
<br>
<button id="clear-cart" onClick="clearCart()">Clear Cart</button>
This is the JQuery ( I use JQuery 3.3.1.min )
$(".add-to-cart").click(function(event){
event.preventDefault();
var name = $(this).attr("data-name");
var price = Number($(this).attr("data-price"));
addItemToCart(name, price, 1);
displayCart();
});
function displayCart(){
var cartArray = listCart();
var output ="";
for (var i in cartArray){
output +=
"<tr>"
+"<td class='itemName'>"
+cartArray[i].name
+"</td>"
+"<td class='itemPrice'>"
+"Rp "
+cartArray[i].price
+"</td>"
+"<td>"
+" "
+"</td>"
+"<td class='itemCount'>"
+cartArray[i].count
+"</td>"
+"<td style='width:20px;'>"
+"</td>"
+"<td>"
+"<span class='sub-item' data-name='"+cartArray[i].name+"'>-</span>"
+"</td>"
+"<td style='width:12px;'>"
+"</td>"
+"<td>"
+"<span class='delete-item' data-name='"+cartArray[i].name+"'>×</span>"
+"</td>"
+"</tr>"
}
$("#show-cart").html(output);
$("#total-cart").html( totalCart() );
$("#cart-count").html( countCart() );
saveCart();
}
$("#show-cart").on("click", ".delete-item", function(event) {
var name = $(this).attr("data-name");
removeItemFromCartAll(name);
displayCart();
});
$("#show-cart").on("click", ".sub-item", function(event) {
var name = $(this).attr("data-name");
removeItemFromCart(name);
displayCart();
});
This is the Javascript
var cart = [];
var Item = function(name, price, count){
this.name = name;
this.price = price;
this.count = count;
}
// adding item to cart
function addItemToCart(name, price, count) {
for (var i in cart) {
if (cart[i].name === name ) {
cart[i].count += count;
return;
}
}
var item = new Item(name, price, count);
cart.push(item);
saveCart();
}
// Removes 1 Item From Cart
function removeItemFromCart(name){
for (var i in cart) {
if (cart[i].name === name){
cart[i].count --;
if (cart[i].count === 0){
cart.splice(i, 1)
}
break;
}
}
saveCart();
}
// Clear 1 Object From Cart
function removeItemFromCartAll(name){
for (var i in cart) {
if (cart[i].name === name){
cart.splice(i,1);
break;
}
}
saveCart();
}
// Clear The Cart
function clearCart(){
cart = [];
document.getElementById("show-cart").innerHTML = "";
saveCart();
document.getElementById("total-cart").innerHTML = "0";
}
// Shows Total Count Of Item
function countCart(){
var totalCount = 0;
for (var i in cart){
totalCount += cart[i].count;
}
return totalCount;
}
// Shows Total Price
function totalCart(){
var totalCost = 0;
for (var i in cart){
totalCost += cart[i].price * cart[i].count
}
return totalCost;
saveCart();
}
// Returns an array
function listCart(){
var cartCopy = [];
for (var i in cart){
var item = cart[i];
var itemCopy = {};
for (var p in item){
itemCopy[p] = item[p];
}
cartCopy.push(itemCopy);
}
return cartCopy;
}
function saveCart(){
localStorage.setItem("shoppingCart", JSON.stringify(cart));
}
function loadCart(){
cart = JSON.parse(localStorage.getItem("shoppingCart"));
}
loadCart();
displayCart();
I expected the output that when the clear button is clicked, and I add an item, the item shown is only 1 and the previous item in the cart before I clicked is gone.
Sorry, I can not read your code, there is too much to say, and I guess your mistake comes from bad management on the addressing of tables and their elements.
I adapted one of my old code to match it to your work; this is a big technical gap for you, but I think it will be useful for you to program on better rails :)
HTML part:
`
<div id="Bt_BUY">
<button data-price="150000" >Avocado & Brownie Cake</button>
<button data-price="65000" >Strawberry & Watermelon Cake</button>
</div>
<table id="show-cart">
<thead>
<tr>
<th>name</th>
<th>price</th>
<th>count</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button id="clear-cart" >Clear Cart</button>
`
JS part
`
"use strict"
const Buy_obj = {
List : [],
DisplayTable : null,
add( x_name, x_price, x_count ) {
let idx = this.List.findIndex( e=>e.name=== x_name);
if (idx>=0)
{ this.List[idx].count += x_count; }
else
{ this.List.push( { 'name' : x_name, 'price' : x_price, 'count' : x_count } ) }
this.saveList();
this.drawTable();
}
,
clear(){
this.List.length = 0;
this.saveList();
this.drawTable();
}
,
remove( x_name ) {
let idx = this.List.findIndex( e=>e.name=== x_name);
if (idx>=0) {
this.List[idx].count--;
if (this.List[idx].count <= 0)
{ this.List.splice(idx,1) }
}
this.saveList();
this.drawTable();
}
,
saveList() {
localStorage.setItem("shoppingCart", JSON.stringify(this.List));
}
,
loadList() {
let ls_list = localStorage.getItem("shoppingCart");
if ( ls_list)
{ this.List = JSON.parse(ls_list); }
}
,
initialise( $xTable ) {
this.DisplayTable = $xTable;
this.loadList();
this.drawTable();
}
,
drawTable() {
this.DisplayTable.innerHTML = "";
this.List.forEach(e=>{
let
T_row = this.DisplayTable.insertRow(-1),
T_cell_0 = T_row.insertCell(0),
T_cell_1 = T_row.insertCell(1),
T_cell_2 = T_row.insertCell(2);
T_cell_0.textContent = e.name;
T_cell_1.textContent = e.price;
T_cell_2.textContent = e.count;
})
}
}
// *************************** Main *****************************
Buy_obj.initialise ( document.querySelector('#show-cart tbody') );
document.querySelector('#Bt_BUY').onclick = function(e) {
if (!e.target.matches('button')) return;
e.stopPropagation();
Buy_obj.add( e.target.textContent, e.target.dataset.price, 1 );
}
document.querySelector('#clear-cart').onclick = function(e) {
Buy_obj.clear();
}
`
I am making a quiz with my son to teach him HTML. But i'm having trouble with some JavaScript(no jquery or any other libraries). Everything works okay until the end. It's suppose to tell us how many are right and wrong, but instead we get undefined.
error reads:Uncaught TypeError: Cannot assign to read only property 'innerHTML' of Question 17 of 16
HTML
<body id="body">
<div id="pokeBallL"> </div>
<div id="pokeBallR"> </div>
<div id="spacer"> </div>
<h2 id="tstat"></h2>
<div id="test"> </div>
</body>
JavaScript
(function () {
"use strict";
/*global window,alert*/
var UIlogic = {
myStuff: function () {
var pos = 0, question, test, tstat, Myquestions, btnCheck, choice, choices, chA, chB, chC, chD, correct;
Myquestions = [
["What decade wear you born?","1980's","1990's","2000's","2010's","A"],
["What activity do you like more","Gaming","Camping","Travelling","Sleeping","A"],
["Pick a color","Black","Pink","Red","Blue","A"],
["Pick a number","22","42","4","7","A"],
["Choose a weapon","Battleaxe","Sword","Daggers","pen","A"],
["Pick an animal","Tiger","Monkey","Elephant","Human","A"],
["Pick a music genre","Rock","Hip-hop","Country","Folk","A"],
["How many legs do Butterflies have?","4 legs","6 legs","2 legs","3 legs","A"],
["How many stripes are on the American flag?","13","15","7","19","A"],
["Which is the nearest star?","Centauri A","Sol","Sirius","Proxima Centauri","A"],
["Longest river in the world is...?","Mississippi","Nile","Amazon","Ohio","A"],
["Pick one...","PS4","PC Master Race","XB One","Puny Apple","A"],
["Pop or Soda?","Pop","Both","Soda","Soft Drink","A"],
["What is your favorite creature","Amphibian","Mammal","Reptile","Avian","A"],
["Pick a squad position","Squad Leader","FTL","","Grenadier","A"],
["The Zombie apocalypse has begun! CHoose your path...","Get to lifeboat","Live inside mountains","Hold-up above gas station","Become Zombie","A"]
];
function _(x) {
return document.getElementById(x);
}
function renderQuestion() {
test = _("test");
tstat = _("tstat").innerHTML = "Question " +(pos + 1)+ " of " +Myquestions.length;//seems to have an issue here
if(pos >= Myquestions.length) {
test.innerHTML = "<h2>You got " +correct+ " out of " +Myquestions.length+ " questions correct!</h2>";
tstat.innerHTML = "<h2>Test completed</h2>";
pos = 0;
correct = 0;
return false;
}
question = Myquestions[pos][0];
chA = Myquestions[pos][1];
chB = Myquestions[pos][2];
chC = Myquestions[pos][3];
chD = Myquestions[pos][4];
test.innerHTML = "<h3>"+question+"</h3><hr />";
test.innerHTML += "<h4><input type='radio' name='choices' value='A'>"+chA+"</h4><br />";
test.innerHTML += "<h4><input type='radio' name='choices' value='B'>"+chB+"</h4><br />";
test.innerHTML += "<h4><input type='radio' name='choices' value='C'>"+chC+"</h4><br />";
test.innerHTML += "<h4><input type='radio' name='choices' value='D'>"+chD+"</h4><br />";
test.innerHTML += "<button id='btnCheck' class='btnClass'>Submit</button>";
btnCheck = document.getElementById("btnCheck");
btnCheck.addEventListener('click', checkAnswer, false);
}
renderQuestion();
function checkAnswer() {
choices = document.getElementsByName("choices");
for(var i = 0; i<choices.length; i++) {
if(choices[i].checked){
choice = choices[i].value;
}
}
if(choice == Myquestions[pos][5]) {//somewhere here doesn't seem right either.
correct++;
}
pos++;
renderQuestion();
}
}
};
window.onload = function () {
UIlogic.myStuff();
};
}());
separate this line
tstat = _("tstat").innerHTML = "Question " +(pos + 1)+ " of " +Myquestions.length;//seems to have an issue here
into this:
tstat = _("tstat");
tstat.innerHTML = "Question " +(pos + 1)+ " of " + (Myquestions.length + 1);
Demo
I got it... i changed
var correct;
to
var correct = 0;
turns out, the index wasn't counting because correct was reading NAN
Although, i should make a function to check the radios first before entering, a non-answer will answer correctly. This is what i made for that...
function checkAnswer() {
choices = document.getElementsByName("choices");
var found = 1;
for (var i = 0; i < choices.length; i++) {
if (choices[i].checked) {
choice = choices[i].value;
found = 0;
break;
}
}
if(found == 1)
{
alert("Please Select Radio");
return false;
}
if (choice === Myquestions[pos][5]) { //somewhere here doesn't seem right either.
correct++;
}
pos++;
renderQuestion();
}
Can anyone see what the problem is here? It keeps saying that the basket_text function is not defined but i don't know why?
HTML
<script type='text/javascript'>
document.write(basket_text());
</script>
first.js
function basket_text(){
var emptyBasketHTML = "<span class='header_text'>My Bag: (0 items) Total: £0.00</span>";
var populated = "<span class='header_text'><a href='/basket'>##ITEMS##</a><br />Total: ##VALUE##</span>";
//populated += "<input type='submit' value='Checkout' name='commit' class='go_botton header-checkout-button'>"
populated += "<form action='/basket'>";
populated += "<input type='submit' value='Checkout' class='header-checkout-button'>"
populated += "</form>";
return fc_basket_text_from_cookie(emptyBasketHTML,populated);
}
second.js
function fc_basket_text_from_cookie(empty_text, normal_text)
{
var basket = readCookie('bk');
if (basket)
{
var parts = decodeURIComponent(basket.replace(/\+/g, '%20')).split('|')
if (parseInt(parts[1]) == 0)
return normal_text.replace(/##VALUE##/g, parts[0]).replace(/##ITEMS##/g, parseInt(parts[1]));
// return empty_text
else
return normal_text.replace(/##VALUE##/g, parts[0]).replace(/##ITEMS##/g, parseInt(parts[1]));
} else {
return '';
}
}
function basket_text()
{
return fc_basket_text_from_cookie('<span>Your basket is empty (not used?)</span>', '<span>Items in basket: ##ITEMS##</span><div><span> </span><span>##VALUE##</span></div>')
}
Any insight is much appreciated?
Cheers