javascript if statement checking for true/false - javascript

I wrote, what I thought, was a straight forward if statement in JS but it is running incorrectly.
function printLetter(LetterId) {
var studentflag = $("#IsStudent").val();
if (studentflag)
{
//do option 1
} else {
//do option 2
}
}
Everytime it runs, the studentflag var value is correct, but regardless of whether it is true or false, it goes into option 1. I am pretty sure I have done true/false checks like this before in JS, but do I need to spell it out (studentflag == true) instead?

This is known as truthy and falsy Values
The following values are always falsy:
false
0 (zero)
"" (empty string)
null
undefined
NaN (a special Number value meaning Not-a-Number!)
All other values are truthy:
including "0" (zero in quotes),
"false" (false in quotes) like if (studentflag) //being studentflag "false",
empty functions,
empty arrays, and
empty objects.

If #StudentFlag is either "true" or "false", then if(studentFlag) will always follow the true route because both are non-empty strings (truthy). You need to do something along these lines:
var studentflag = $("#IsStudent").val();
if (studentflag === "true") {
//do option 1
} else {
//do option 2
}

.val () doesn't return a boolean.
Try this instead;
function printLetter(LetterId) {
var studentflag = $("#IsStudent").is (':checked');
if (studentflag)
{
//do option 1
} else {
//do option 2
}
}
This is assuming #IsStudent is a checkbox. If it's not, try this (assuming the value is true (as a string, not a boolean));
function printLetter(LetterId) {
var studentflag = ($("#IsStudent").val () == 'true')
if (studentflag)
{
//do option 1
} else {
//do option 2
}
}

IMO there should be more context in the question. If submitted solution works for OP that is great, but for others using this as a resource, the accepted solution might not work in all cases.
The value retrieved from an element via JS actually depends on the input itself and its HTML structure. Here's a demo explaining the difference between using .val(), .attr('val'), and .is(':checked') with checkboxes and radios. All of those variants can pull different values from an element depending on its HTML structure and current UI state.
Fiddle : http://jsfiddle.net/h6csLaun/2/

var studentflag = $("#IsStudent").val();//This is a string .. not a boolean
if (studentflag === "true") //therefore this has to be string comparison
Or you can make studentflag boolean as follows:
var studentflag = $("#IsStudent").val() === "true";
if (studentflag) { ....

Related

Variable not updating its value

var canAssignMultiple="true";
var canWithdrawMultiple="true";
function onCheckUncheck()
{
if($(':checkbox[name^="checkedRecords"]:checked').length>0)
{
$("input[name='checkedRecords']:checked").each(function()
{
debugger;
var canAssign = $(this).attr("canAssign").toLowerCase();
var canWithdraw = $(this).attr("canWithdraw").toLowerCase();
canAssignMultiple= canAssignMultiple && canAssign;
canWithdrawMultiple= canWithdrawMultiple && canWithdraw;
if (canAssignMultiple == "false")
$("#assaignbutton").attr("disabled", "disabled");
else
$("#assaignbutton").removeAttr("disabled");
if (canWithdrawMultiple == "false")
$("#withdrawbutton").attr("disabled", "disabled");
else
$("#withdrawbutton").removeAttr("disabled");
});
}
else
{
$("#assaignbutton").attr("disabled", "disabled");
$("#withdrawbutton").attr("disabled", "disabled");
}
}
The variable canAssignMultiple is becoming true when each() function is called the second time though its value has changed to false in the first iteration.It should retain its value evrytime the loop runs.How to do this?
boolean (false, true) values are different than strings ("false", "true")
try
var canAssignMultiple = true;
var canWithdrawMultiple = true;
function onCheckUncheck() {
if ($(':checkbox[name^="checkedRecords"]:checked').length > 0) {
$("input[name='checkedRecords']:checked").each(function() {
debugger;
var canAssign = $(this).attr("canAssign").toLowerCase() == "true"; // make this a boolean expression
var canWithdraw = $(this).attr("canWithdraw").toLowerCase() == "true"; // make this a boolean expression
canAssignMultiple = canAssignMultiple && canAssign;
canWithdrawMultiple = canWithdrawMultiple && canWithdraw;
if (canAssignMultiple === false) $("#assaignbutton").attr("disabled", "disabled"); // use false (instead of "false")
else $("#assaignbutton").removeAttr("disabled");
if (canWithdrawMultiple === false) $("#withdrawbutton").attr("disabled", "disabled"); // use false (instead of "false")
else $("#withdrawbutton").removeAttr("disabled");
});
}
else {
$("#assaignbutton").attr("disabled", "disabled");
$("#withdrawbutton").attr("disabled", "disabled");
}
}​
left comments where changes were made
As others have noted, the strings "true" and "false" do not function the same as the boolean values true and false. If you try to use a string in an if statement or with a logical operator such as &&, the string is converted to a boolean; and all non-empty strings are converted to true (i.e. they are "truthy"). That means the string "false" will work the opposite of how you expect, e.g. in ("false" && x) or in if ("false") {...}.
One way to fix your code is to change this line
canAssignMultiple = canAssignMultiple && canAssign;
to convert canAssign to a boolean in an explicit and correct way:
canAssignMultiple = canAssignMultiple && (canAssign == "true");
Then the && operator will work correctly, and canAssignMultiple will hold an actual boolean value.
And (as #mdmullinax noted, but I would do it differently) once canAssignMultiple is actually a boolean, you can change your if statements to treat them as such:
if (canAssignMultiple == "false")
should become
if (!canAssignMultiple)
And similarly with the corresponding withdraw stuff.
Does your HTML look like this?
<input canAssign="false" ...>
<input canAssign="true" ...>
If so, and you can't change the HTML, I suggest changing this:
canAssign = $(this).attr("canAssign").toLowerCase()
to this (to work with booleans from then on):
canAssign = $(this).attr("canAssign") == "true"
and this:
if(canAssignMultiple == "false")
to this (since it is a real boolean now):
if(canAssignMultiple)
If you can change HTML, I suggest you do it the HTML5-compliant way. First, all of your made up attributes should be prefixed data-. You can also change camelCase to hyphen-case. JQuery, when loading your data-attributes, will then perform the conversion from string if possible:
<input data-can-assign="false" ...>
<input data-can-assign="true" ...>
then jQuery will give you the boolean you want from this call:
canAssign = $(this).data("canAssign")
Of course, the same fix should be applied to all other string pseudo-booleans (that don't quite work with the boolean operators) as well.
The reason is: "false" is not exactly false. "false" && x will evaluate to x (not to "false" as you expect). On the other hand, false && x will evaluate to false.

How to set a var to true or false using .val()

I have a textbox, I need to check if the textbox is empty and set a variable accordingly to true or false.
my code at the moment print the value of the textbox.
var isDateTimEndEmpty = dateTimeEnd.val() == null ? true : false;
what am I doing wrong here?
Here is the correct way:
var isDateTimEndEmpty = !$.trim(dateTimeEnd.val()).length;
Good practice is to use $.trim which makes the code to ignore spaces in the input field. So if the length of trimmed value is 0 then the value is empty.
Check its length
var isDateTimeEndEmpty = $.trim($('#txtboxID').val()).length > 0;
the result of dateTimeEnd.val() won't be null. it always a string, might be empty string.
in actually, you don't need to get a 'true' of 'false', just a "truly" or "falsy" value, like empty or non-empty string:
var isDateTimEndEmpty = $.trim(dateTimeEnd.val()) //remove spaces at start and end
if (isDateTimEndEmpty) {
//if dataTimeEnd is not empty, go here
} else {
//if dateTimeEnd is empty, go here
}
if you were uncomfortable with the implicit casting, you can code it in explicit way as well:
var isDateTimEndEmpty = Boolean($.trim(dateTimeEnd.val())); //explicit casting

Strange data-attribute boolean issue

I have a live -on click- event for a Header which has an arrow flipping up/down upon opening & closing it's contents.
The strangest thing is happening with ! followed by a variable -- which is supposed to flip it from true -> false, and vice versa. Basically it's not working at all, and it flips to false and stays there... Check out the fiddle to see what I mean.
I've deleted lots of code for the sake of brevity.
Demo Code
$(document).on('click', '.regimenHeader', function () {
var _state = $(this).attr('data-state');
if (_state === 'true') {
// do stuff
}
else {
// do stuff
}
// This is where the issue is happening, it isn't flipping the Boolean value
// !"true" = false, !true = false, it works with strings or booleans
$(this).attr('data-state', !_state);
});​
I can get it working perfectly fine if I do the following:
if (_state === 'true') {
// Manually flip the data-state boolean
$(this).attr('data-state', false);
}
Is there something I'm missing why this isn't working the way it should ?? Just wondering why it's doing this!
I think you are trying to do this:
http://jsfiddle.net/JKUJb/2/
if so, the problem was that you are using .attr() which returns a string, so if you convert:
!"true" //false
!"false" //false
.data() on the other hand returns the value already "casted
EDIT:
Just to be more clear, in javascript the only falsy values are:
false;
null;
undefined;
'';
0;
NaN;
So if you really wanted to use .attr(), you could, but I recommend that first you do:
var _state = $(this).attr('data-state') === 'true'; //if 'true' then true, false otherwise
Good luck!
Change your second line to:
var _state = $(this).attr('data-state') == 'true';
And in the if statement check for boolean:
if ( _state ) {
// do stuff
...
_state is a String (typeof _state === String //true) you need to convert it to a boolean first
(a String will alwase be true)
If you really want to use data- attributes for this, use jQuery's .data method to retrieve and set the value. It will automatically convert the string "true" into a Boolean, or the string "1" into a number:
$(document).on('click', '.regimenHeader', function () {
var _state = $(this).data('state');
if (_state) {
// do something
}
$(this).data('state', !_state);
});​
http://jsfiddle.net/mblase75/JKUJb/6/
Or you could toggle a class -- you can use the .hasClass method to return a Boolean:
$(document).on('click', '.regimenHeader', function () {
var _state = $(this).hasClass('data-state');
if (_state) {
// do something
}
$(this).toggleClass('data-state');
});​
http://jsfiddle.net/mblase75/JKUJb/3/

check if html attribute exist and has right value with jquery

Is there a better way for checking an attribute for:
it exist. so value must be false if attribute doesn't exist
Value is correct (boolean)
var isOwner = false;
if ($(selectedItem).is('[data-isOwner="True"]') || $(selectedItem).is('[data-isOwner="true"]')) {
isOwner = true;
} else {
isOwner = false;
}
Now I need to check for 'True' and 'true'...
Thanks
You can convert the value stored in data-isOwner to lower case and only compare the value to 'true'.
if (($(selectedItem).attr ('data-isOwner') || '').toLowerCase () == 'true')
The above use of <wanted-value> || '' will make it so that if the selectedItem doesn't have the attribute data-isOwner the expression will result in an empty string, on which you can call toLowerCase without errors.
Without this little hack you'd have to manually check so that the attribute is indeed present, otherwise you'd run into a runtime-error when trying to call toLowerCase on an undefined object.
If you find the previously mentioned solution confusing you could use something as
var attr_value = $(selectedItem).attr ('data-isOwner');
if (typeof(attr_value) == 'string' && attr_value.toLowerCase () == 'true') {
...
}

Why doesn't my simple if-statement render false in javascript?

I call a function like this:
call_facebook(103138046395999, "samåkning.se", "http://www.facebook.com/samakning", "page");
call_facebook(16089699074, "Jag ska köra bil, vem vill åka med", "http://www.facebook.com/groups/16089699074/", "grupp")
The function looks like this:
function call_facebook(id, name, link, type){
//snip
console.log(type)
if (type = "grupp"){
var postid=fbposts[fbpost].id.split("_");
return "https://www.facebook.com/groups/"+postid[0]+"/permalink/"+postid[1]+'/'
}
else {
return fbposts[fbpost].actions[0].link;
}
}
//snip
};
I have confirmed that they have different type arguments, but still the first case if (type = "grupp") always ends up true. Why?
A single equals character (=) does not compare. It assigns! Therefore, your if statement always assigns "grupp" into type and returns true.
Use == or === to compare.
I guess you meant
if (type == "grupp"){
You have to use == to compare values. Just a single = is used to assign values.

Categories