If checbox/disable element not working properly - javascript

I'm attempting to make a script so that if you check/uncheck a checkbox input, that it will enable/disable a target input text box. My code if statement doesn't seem to function correctly sometimes firing both ifs at once, other times not firing at all. I've done debugging and tried numerous variations but it still won't work. Here is what I have, any help is greatly appreciated!
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status = true) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
}
if (status = false) {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "bfbfbf";
}
}

This code is not exhibiting proper behavior for several reasons.
The first reason is that your if statements are inline, not in an if-else form. A better organization is as follows:
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status == true) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
} else {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "#bfbfbf";
}
}
This means that even if the variable you are checking changes while the code in the block is executing, it will not execute the code in the opposing block regardless of its new value. As you have it, if the value were to change while the code in the first if statement was running, then it is possible for both control blocks to run.
The second reason it is not behaving right is due to the incorrect syntax within your if statement. You are currently using the = operator which means set the variable to what you are wanting to check against. You must use either the == or === equality checks (the latter is type strict) if you want to write them this way. An even better way is to omit that operator entirely by just checking if the value is truthy, like so:
function disable(elem) {
var obj = document.getElementById(elem);
status = obj.disabled;
console.log(status);
if (status) {
console.log("test");
obj.disabled = false;
obj.style.backgroundColor = "white";
} else {
console.log("test2");
obj.disabled = true;
obj.style.backgroundColor = "#bfbfbf";
}
}
This should give you your expected control behavior :) As was mentioned, make sure you are formatting your values appropriately (e.g. "#bfbfbf" not "bfbfbf")

Related

Why do I have to IF return, IF what?

I am learning to code or rather - even reading the code at this moment.
Could anyone please explain me, why those lines are there and what do they do?
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
What is the purpose of those two lines?
function handleCardClick(e) {
// you can use event.target to see which element was clicked
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
let currentCard = e.target;
currentCard.style.backgroundColor = currentCard.classList[0];
if (!card1 || !card2) {
currentCard.classList.add("flipped");
card1 = card1 || currentCard;
card2 = currentCard === card1 ? null : currentCard;
}
if (card1 && card2) {
noClicking = true;
// debugger
let gif1 = card1.className;
let gif2 = card2.className;
if (gif1 === gif2) {
cardsFlipped += 2;
card1.removeEventListener("click", handleCardClick);
card2.removeEventListener("click", handleCardClick);
card1 = null;
card2 = null;
noClicking = false;
} else {
setTimeout(function() {
card1.style.backgroundColor = "";
card2.style.backgroundColor = "";
card1.classList.remove("flipped");
card2.classList.remove("flipped");
card1 = null;
card2 = null;
noClicking = false;
}, 1000);
}
}
if (cardsFlipped === COLORS.length) alert("game over!");
}
if (noClicking) return;
if (e.target.classList.contains("flipped")) return;
The lines below those 2 lines will not be executed if one of the 2 lines are returned.
It means if noClicking == true or e.target.classList.contains("flipped") == true, then all the lines below those 2 lines will not be executed.
While the answers already given are correct, I thought it could help to understand why those lines are there in place. They are called guard clauses. Their purpose is to make your code more efficient.
Think of a scenario like this:
function myFunc(someParam) {
/*
do something that takes a lot of time/resources
... then somewhere you find someParam was invalid!
so all the calculations done until now was useless
*/
}
So instead of checking the validity of arguments, global variables, etc. when you need them in the function, you check for them in the beginning of the function such as like this:
function myFunc(someParam) {
//let's say valid() is a function that checks for validity of the param,
//returns true if valid, false if invalid.
if(!valid(someParam)) return;
/*
do something that takes a lot of time/resources
... then your function will only run the expensive code
if it is sure that there are no invalid arguments passed to it.
*/
}
It doesn't always have to be just return. This is your choice. Maybe the function always returns some positive number, then you could return -1 as such:
const getRoot = (num) => {
if(num < 0) return -1;
//get square root of the number
return abs(Math.sqrt(num));
}
//Then when you call the function, you could check if the result is not -1,
//to make sure you passed the correct arguments.
if (getRoot(-1) < 0)
console.error("Uh oh, you passed a negative number to the square root function");
Or you could throw an Error:
function myFunc (someParam) {
if(!valid(someParam)) throw new Error("wrong param bruh");
//do something...
}

If statement not executing correct code?

So I am trying to develop a Tic Tac Toe game for practice with javascript but I've hit a roadblock. I have an if statement that should be returning true but it isn't. Here is a sample.
var game = true;
var x = 'X';
var o = 'O';
var blank = '';
var turn = x;
var board = [blank, blank, blank,
blank, blank, blank,
blank, blank, blank];
function write() {
$('td').click(function() {
//Making sure that the block that was clicked can only be clicked once
var id = $(event.target).attr('id');
var digit = parseInt(id.slice(-1));
//check to see of the block has been clicked on
if (board[digit] = blank) {
board[digit] = turn;
$(board[digit]).html(turn.toUpperCase());
if (turn = x) {
turn = o;
} else if (turn = o) {
turn = x;
}
} else {
alert("That box has already been clicked on!")
}
});
}
You have two issues at first glance.
First, event is undefined. Define it as a function parameter in your .click call.
$('td').click(function(event) { /* rest of the code */ }
Second, as Pointy commented, = is for assignment, == and === are meant for comparisons.
Thus
if (board[digit] = blank) { /**/ }
needs to be
if (board[digit] === blank) { /**/ }
Regarding the difference between == and === you can get more information here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
Short version, prefer === unless you're absolutely sure you know what you're doing and want to explicitly use ==.
if (board[digit] === blank) {
^^

Why wont my function return true?

I cant seem to get this function to return true even after ticking the two check boxes I have on the page. I've been working on this for hours now and running out of ideas. Any help would be much appreciated.
if(myfunction() == true){
alert('YAY!');
}
function myfunction(){
if($("input[type=checkbox]").length > 0){
$('.checkbox').each(function(){
if($(this).prop('checked')){
return true;
}
else{
$(this).find(".CheckboxCheck").show();
return false;
}
});
}
else{
return true;
}
}
You are returning true from within the function that you passed to each, not from myfunction. Except in the case that there are no check boxes on your page, and thus the else block executes in myfunction, myfunction is returning undefined.
You can do something like this however:
if(myfunction() == true){
alert('YAY!');
}
function myfunction(){
var returnValue = true;
if($("input[type=checkbox]").length > 0) {
$('.checkbox').each(function(){
if($(this).prop('checked')){
returnValue = true;
return false; // Stops the each loop.
}
else {
$(this).find(".CheckboxCheck").show();
returnValue = false;
return false; // Stops the each loop.
}
});
}
return returnValue;
}
Now, I'm not exactly sure of what you're trying to do, and you will almost certainly need to tweak the code above. I'm just providing it as a way to illustrate how to get a value out of the function passed to each. If you're trying to determine if all of the checkboxes are checked, for example, then you'll want your each function to look something like this:
var returnValue = true;
...
$('.checkbox').each(function() {
if (!$(this).prop('checked')) {
returnValue = false;
return false;
}
});
EDIT: After looking at the second code snippet again, I realized that the each loop is unnecessary. If you want to determine if all check boxes are checked, all you need is this:
if ($('.checkbox:not(:checked)').length == 0) {
// All .checkbox elements are checked.
}
Now, keep in mind that the :not() and :checked selectors can't utilize the native JS functions, so they are slower, but probably not enough to matter. I prefer the conciseness.
Returning from inside the each callback function will not return from the outer function. The function will return undefined as you haven't specified any return value for it, and that is not equal to true.
You can use a variable for the result, that you set from within the loop:
function myfunction(){
var result = true;
$('.checkbox').each(function(){
if(!$(this).prop('checked')){
result = false;
$(this).find(".CheckboxCheck").show();
return false; // exit the loop
}
});
return result;
}

Is there "return false;" code for an "if" statement that is not located in a function?

I am currently working on a class assignment and we are learning if/else statements. I would like to know if there is code similar to return false; for an if statement.
For example:
var why = prompt("Why won't you fill in my prompt?");
if(why === "" || why === null){
// How can you make this false, so that it will ask the prompt question again?
return false; /*Like that--but not a function*/
}
Define a container for your response first and prompt until it's an acceptable value:
var reason = null;
while (reason === "" || reason === null) {
reason = prompt("Why won't you fill in my prompt?");
}
// continue with the reason defined
var why=null;
while (why===null||why===""){
why = prompt("Why won't you fill in my prompt?");
}

Avoid execution goes on in a .each loop

I've got a code like this one to see whether some radio buttons have been checked or not. I'm using .each function of jquery to show an alert when I find a group of radio buttons with the same name value and none of them have been checked. When I find one I want to fire an alert and return false, but after the alert is shown the execution of the .each stops but the lines after .each function are executed (I mean true value is executed).
$(":radio").each(function(){
var name = $(this).attr('name');
var numAnswered = $(":radio").filter('[name='+name+']').filter(":checked").length;
var notAnswered = numAnswered == 0;
if(notAnswered){
alert("Must answer all questions");
return false;
}
});
console.log('still goes here even when alert is fired');
return true;
How can I avoid this situation?
Thanks.
var myreturnvalue = true;
$(":radio").each(function(){
var name = $(this).attr('name');
var numAnswered = $(":radio").filter('[name='+name+']').filter(":checked").length;
var notAnswered = numAnswered == 0;
if(notAnswered){
alert("Must answer all questions");
myreturnvalue = false;
return false;
}
});
console.log('still goes here even when alert is fired');
return myreturnvalue;
You can use that same notAnswered variable (or another, whatever floats your boat) at a higher scope, like this:
var notAnswered;
$(":radio").each(function(){
notAnswered = $(":radio[name="+this.name+"]:checked").length == 0;
if(notAnswered){
alert("Must answer all questions");
return false;
}
});
if(notAnswered) return false;
console.log("will only fire if there's an answer");
return true;
The other changes above are just slimming down the code, you can get away with far fewer selector engine invocations :)

Categories

Resources