Dave Morton Dave Morton - 3 months ago 8
jQuery Question

jQuery won't re-enable a button

I've got a simple Bingo game that I'm writing using jQuery 1.12 and in part of it, I'm disabling a "Get New Card" button (

<button id="new_card">Get a New Card</button>
) with the following line of code:

$('#new_card').attr('disabled', 'disabled');


This works in all of the major browsers I have installed (IE11, Edge, FF48 and Chrome52 - all on Windows 10, 64 bit), as expected. However, when a bingo is detected, the portion of the script that should re-enable that button is failing. I've used the following lines of code to attempt to enable the button:

$('#new_card').attr('disabled', false);
$('#new_card').removeAttr('disabled');
$('#new_card').prop('disabled', false);


In each of the major browsers listed above, all of these methods fail to enable the button. I have
console.log()
statements both before and after these lines of code, and they output to the console, so I know that they're being executed. No errors are showing up, either. Oddly, if I enter any one of those lines of code into the JS console, all three work, in all of the browsers that I can access the console on. They just don't work at run-time. The full context of the code is below:

function newGame() {
clearInterval(ballTimer);
bingoCount = 0;
ballCount = 0;
selected = [];
var name = '';
if ($('#cbNewCard').is(':checked')) newCard();
ballTimer = setInterval(callBall, 5000);
gameInProgress = true;
$('#new_card').attr('disabled', 'disabled');
}

function stopGame() {
gameInProgress = false;
$('#new_card').attr('disabled', false);
$('#new_card').removeAttr('disabled');
$('#new_card').prop('disabled', false);
clearInterval(ballTimer);
}

function callBall(){
var num = false;
do {
num = getRand(1,75);
var name = getBall(num);
console.log(selected.length);
if (selected.length >= 75) return false;
} while (findThis(num, selected));
selected.push(num);
var newBall = $('<div>').addClass(name).html(name + num);
$('#called_numbers')
.append(newBall)
.animate({scrollTop: $('#called_numbers div:last-child').position().top});
ballCount++;
$('#ballCount').text(ballCount);
check4bingos();
if (bingoCount > 0) {
console.log('Got a BINGO!');
stopGame();
console.log('Got a BINGO!');
}
}


Any suggestions would be appreciated. Thanks in advance.

Answer

Check the scopes of your bingoCount.

The top of your script you set bingoCount as a global variable to 0

      var ballCount = 0;
      var bingoCount = 0;
      var ballTimer;
      var gameInProgress = false;
      var selected = [];
      var inCard = [];

Then in check4bingos() you are trying to enumerate the variable you have var bingoCount making the scope local.

local vs global example: https://jsfiddle.net/33y55tpa/

Change the scope in check4bingos by remove the var from bingoCount. Then your condition of when to stopGame() from callBall should apply as from what i can tell your global scope bingoCount will always be 0.

You are also running clearInterval for ballTimer() once the local scope bingoCount > 0 so the logic of bingoCount > 0 {stopGame()} will never be run as the interval running that logic is removed prior.

        if (bingoCount > 0) {
            console.log('Got a BINGO!');
            clearInterval(ballTimer);
        }