I am creating a simple numeracy game where by there is a grid populated with numbers. The numbers are hidden and when the game is run the grid space is highlighted. A div on the side produces a sum to help the user get the correct answer. The user then clicks the corresponding numbers that animate into position and signal whether they are right or wrong.
I have but in a next button ('.minibutton'), so that if the user gets the answer wrong 3 times they have a chance to move to the next question. The button also has a .trigger('click') function so that when a word is completed correctly it moves on automatically and keeps the game flowing.
My problem is the button has stopped working and I am clueless as to why. Here is the ".minibutton" function...
$('.minibutton').click(function() {
var sum = $('#answerlist li[data-answer="' + answer + '"]').data('sum');
$(right).val('');
$(wrong).val('');
$('td').removeClass('spellanswer');
score.wrong = 0;
var r = rndanswer;
while (r == rndanswer) {
rndanswer = Math.floor(Math.random() * (listOfanswers.length));
}
when I added this statement the button stopped working
//for (var x = 0; x < listOfanswers.length; x++) {
//if (eval(sum.replace("=", "").replace("x", "*")) == listOfanswers[x].name) {
// rndanswer = x;
// }
//}
$('td[data-answer="' + listOfanswers[rndanswer].name + '"]').addClass('spellanswer');
$('td[data-answer=' + answer + ']').removeClass('answerglow').removeClass('answerglow4').removeClass('answerglow3').css('color', 'transparent');
var noExist = $('td[data-answer=' + listOfanswers[rndanswer].name + ']').hasClass('answerglow2');
if (noExist) {
$('.minibutton').prop('disabled', false);
} else {
$('.sumstyle').text(sum);
sum.hide();
}
}).trigger("click");
http://jsfiddle.net/ZAfVZ/28/
Running the jsFiddle gives this error:
Object 1 + 2 = has no method 'hide'
You're trying to hide a string, which is obviously wrong. It's causing the script to stop executing after that point. Remove/comment out sum.hide(), and the 'next' button appears after three wrong guesses.
I've edited the JSFiddle to define sum (a text string containing the sum that the player is trying to answer) and seumElem (the HTML element containing the sum) at the top of the function: http://jsfiddle.net/ZAfVZ/30/
Related
He y'all.
I've been stuck on this button for the past 45 minutes or so and I can't seem to figure out exactly how to fix my problem. I created three buttons.
(html)
<div class="action">
<button id="start" onclick="start()">Start</button>
// I have not done the Stay function yet
<button id="stay">Stay</button>
</div>
<div class="announce" id="afterStart">
<p id="hit"></p>
(javascript)
function start() {
let score = Math.floor(Math.random() * 11 + 1);
let scoreTotal = document.getElementById("score-total");
scoreTotal.textContent = `Your score: ${score}`
The first part of the button grabs the button ID of my Start button. Doing so displays the text "Your Score" followed by a random number between 1 - 11.
let proceed = document.getElementById("hit");
if (score < 21) {
proceed.textContent = "Do you wish to use another card?"
let hitButton = document.createElement("button");
hitButton.innerHTML = "Hit";
This grabs the ID of the second div in my HTML and creates a new button, which displays the text "Hit". By clicking "Hit" it does the following function:
hitButton.onclick = function () {
let score = Math.floor(Math.random() * 11 + 1);
scoreTotal.textContent += score;
}
And herein lies the problem. For example, if I click "Start" and randomly get the number 3, it'll display:
Your score: 3
But when I click Hit, if I randomly got the number 11, it would turn my score into 311, instead of adding 3 + 11 together. It's effectively turning my code into a string, and no matter what I do I can't seem to fix it. I've tried adding a + in front of various things, as well as using parseInt. Nothing seems to work. Here is the rest of my code.
let myButton = document.getElementById("afterStart")
myButton.appendChild(hitButton);
document.getElementById("start").onclick = null;
This is just creating the Hit button below some text. After clicking "Start" I decided to disable the button.
} else if (score === 21) {
proceed.textContent = "You won!"
} else {
proceed.textContent = "You lose!"
}
And here is my function in full in case all the spaces is confusing.
What I'm basically asking is this.
How can I get my "Hit" button to add to my total score as an integer instead of a string?
I'm attempting my second ever project: Blackjack! I've had a lot of success in my first project, which was a unit converter, but struggling a bit with this. I'm doing my best not to follow any tutorials or anything, as I've been in tutorial hell for months.
Try this:
scoreTotal.textContent = parseInt(scoreTotal.textContent) + score;
You are making a string concatenation and you dont want it :)
You want 11 + 3 and not '11' + 3. .textContent returns a string.
I’m facing a small issue in JavaScript. I need to to make a code stop and do nothing for a while. I tried setTimeout, but it only scheludes the function, continues in executing the code and then comes back. I really need to wait for the user to put some value in the input field and then press the button. The sleep function on the beginning of my code works, but the code somehow stops showing my html input form and button. I can’t figure out why. I also can’t use onclick attribute on the submit button, because of the same problem. Does someone know what can be the problem here??
var returning = 0; // variable for deciding which part of function to use
function sleep(milliseconds) { // sleep method found here on stackoverflow
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function acceptValue(){
// show an input field with button next to it
if (returning == 0) {
var co = document.createElement("input"); // show input field and set attributes
var kam = document.getElementById("telo");
var indexId = 0;
while(document.getElementById("pole" + indexId) != null) {
indexId++; // look for closest unused id name
}
co.setAttribute("id", "pole" + indexId);
kam.appendChild(co);
var co1 = document.createElement("input");
var kam1 = document.getElementById("telo");
var indexId1 = 0;
while(document.getElementById("cudlik" + indexId1) != null) {
indexId1++; // look for closest unused id name
}
co1.setAttribute("id", "cudlik" + indexId1); // show button and set attributes
co1.setAttribute("type", "submit");
co1.setAttribute("value", ">");
co1.setAttribute("onclick", "vraceni()");
kam1.appendChild(co1);
console.log(document);
document.getElementById("telo").appendChild(document.createElement("br"));
returning = 1;
acceptValue();
} else if (vrat == 1) {
sleep(500);
acceptValue();
}
} else {
var indexPole = 0;
while (document.getElementById("pole" + indexPole) != null) {
indexPole++;
}
vrat = 0;
return document.getElementById("pole" + (indexPole - 1)).value; // return the value from last shown input field
}
}
function returnFunc() {
vrat = 2; // called from html button
}
Thanks,
Adam Hendrych
I think the feature you are attempting to create here may need some re-architecting. It feels very strange to have all these while loops and sleep tricks in place.
What you describe wanting this code to do is basically the default behavior of how inputs and buttons work. A simple form containing an input and submit button, with an onsubmit handler on the form, should meet the "accept input and fire an action when the button is pressed" requirement.
An example
I've recently completed an evaluation on a jsfiddle and completed it but probably not in the way they asked. I attempted a for loop to begin with but could not get anything print initially and tested different environments. When I finally did get it to print, it would only print the last number rather the numbers 1-10. This was my solution to printing it but not listing them out. What would be your approach to listing them out? in the Div class box provided when a button is pressed to initiate it.
https://jsfiddle.net/vjoehmq6/
function change(){
function count(num) {
if(!num)
num = 1;
var x = document.getElementsByClassName("box");
x[0].innerHTML = num;
if(num < 10) {
setTimeout(function() { count(num + 1); }, 1000);
}
}
setTimeout(count, 1000);
}
If you want to append text vertically
x[0].innerHTML += '<br>'+num;
I thought that this onClick event in a For loop would help me but when I tried it, it still didn't work.
I am making a simple Battleship game, and while I'm trying to have the user click on only 4 squares to place on ship, the loop keeps going and doesn't stop after 4 tries. I have my onclick even handler in a for loop, but after 4 tries it doesn't stop. I've tried adding a count variable after the end, and even tried adding a break statement but can't get it to work.
Here's my code:
function placeShips() {
var playerTable = document.getElementById("mainPlayer");
var playerCells = playerTable.getElementsByTagName("td");
var count = 1;
alert("Please place the first ship. Click on 4 squares.");
while (count <= 4) {
for (i = 0; i < playerCells.length; i++) {
playerCells[i].onclick = placeBattleship;
}
count++;
}
}
The placeBattleship function contains the code to change the grid square to a background color of red to mark it. My problem is that once the user clicks 4 squares, you can keep going and click on more and more. I can't get the above for loop that calls the placeBattleship function to stop after the user clicks on 4 squares. I've tried putting it in a while loop, and even the solution in the above link, as well as moving the assignment of count, but can't get it to stop after x amount of times (in this case, 4).
Any ideas on what I'm doing wrong, or a better way to do it?
Wouldn't you consider to use jQuery?
Look your function much shorter:
function placeShips() {
$("td:lt(4)").click(placeBattleship);
}
You can testify on the code below:
<table>
<tr>
<td>1.1</td><td>2.1</td>
</tr>
<tr>
<td>1.2</td><td>2.2</td>
</tr>
<tr>
<td>1.3</td><td>2.3</td>
</tr>
</table>
<div id="console"></div>
<script>
$("td:lt(4)").each(function(){
$("#console").append("Content of "+ $(this).html() + "<br/>");
});
$("td:lt(4)").click(function(){
$("#console").append("Clicking "+ $(this).html() + "<br/>");
});
</script>
...or on my Plunker: https://plnkr.co/edit/yNZw6ZhkNfA9E0NdQg7V
So, now we have a solution that stop for 4th click on the squares:
function placeBattleship() {
var $shipDisplay = $("#shipDisplay");
var counter = $shipDisplay.data("counter");
if(counter++ < 4) {
$(this).css("background-color", "red");
$shipDisplay.data("counter", counter);
}
}
function placeShips() {
$("td").click(placeBattleship);
}
$(document).ready(function(){
placeShips();
});
I use a div with id shipDisplay to store a data-attribute for count the clicks.
Look at the plunker: http://plnkr.co/edit/PEba15PSLv2LK6qjY7AD?p=preview
You should separate priorities in your logic and removeEventListener when counter hits 4 , hopefully this helps you :
//defined outside the function
var counter = 0;
playerCells.addEventListener("click" , placeShips );
Then
function placeShips() {
if(counter <= 4){
//Move ship
placeBattleship();
//add to counter
counter++
}else{
//Remove click event if counter reaches 4 .
playerCells.removeEventListener("click" , doSomethingElse)
}
}
You question needs a bit clarification. To my current understanding, you need to move the checking of count to placeBattleship.
What you are doing is binding click to same tds 4 times, not limiting the number of event triggering to 4 times.
// pseudo code
var count = 4; // this is global
var currentCount = 0;
initFunc() {
// bind click events ONCE
}
startPlacing() {
// accept user click and place ship
// set currentCount to zero
}
placeShip() {
// the callback of user `click`
// check for currentCount == count then move on (no more placement)
// increase currentCount by 1
// place ship
}
Note that after an event is triggered, the listener will not be removed. Until you removeEventListener() from it, it will always be listening.
Everything works fine, except the problem with a pricing plan selection. What I want is that whenever user clicks on a specified price (even while the text is already present in textarea), it should immediately update the final Price. But it won't change at first click.
I should click twice on it instead. Any one got an idea what's wrong ?
So here how it looks like:
And here comes the javascript code:
function __textCalculatorCounter(){
var value = $('#calculateText').val();
var spanWords = $('#calculatedWordsTotal'),
spanChars = $('#calculatedCharsTotal'),
spanPrice = $('#calculatedPriceTotal');
if (value.length == 0) {
spanWords.html(0);
spanChars.html(0);
return;
}
var selectedPricing = $("input[name=calculatePrice]:checked").val();
var wordCount = value.trim().replace(/\s+/gi, ' ').split(' ').length;
var totalChars = value.length;
var totalPrice = (wordCount * parseFloat(Math.round(selectedPricing * 100) / 100));
spanWords.html(wordCount);
spanChars.html(totalChars);
spanPrice.html(totalPrice.toFixed(2));
}
function _initTextCalculator(){
var textblock = $('#calculateText');
textblock.change(__textCalculatorCounter);
textblock.keydown(__textCalculatorCounter);
textblock.keypress(__textCalculatorCounter);
textblock.keyup(__textCalculatorCounter);
textblock.blur(__textCalculatorCounter);
textblock.focus(__textCalculatorCounter);
$('label', '#pricesGroup').click(__textCalculatorCounter);
}
==== UPDATED ====
I don't know why, but it works fine in jsfiddle... it's exactly the same code extracted from html and javascript.
JSFIDDLE
So, since no one had an answer, I post mine, which solved the issue.
The problem is in Twitter's Bootstrap 3 radio button styles which is actually common issue when using along with javascript.
I've changed a click handler for radio buttons:
function _initTextCalculator(){
var textblock = $('#calculateText');
textblock.change(_textCalculatorTrigger);
textblock.keydown(_textCalculatorTrigger);
textblock.keypress(_textCalculatorTrigger);
textblock.keyup(_textCalculatorTrigger);
textblock.blur(_textCalculatorTrigger);
textblock.focus(_textCalculatorTrigger);
// Fixing bootstrap 3 radio buttons
$("#pricesGroup label").on('click', function(){
// Once clicked, mark current radio as checked
$('input:radio', this).prop("checked", true);
// Then call a function to calculate the price
_textCalculatorTrigger();
});
}
As it already commented, it assigns a property "checked" to radio button first once it's parent label tag is clicked, and then it calls a function to calculate the price.
Thanks to everyone