Using conditionals within variable declaration - javascript

I'm trying to detect the "Do not track" setting on browsers... the origionla working code is:
if(navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1"){
alert("true");
}else{
alert("false");
}
I'm trying to re-write it slightly and I'm wondering how to use a conditional within a variable declaration? I've come up with a not-working snippet that I was wondering if someone could help me with?
var DNT = navigator.doNotTrack,
msDNT = navigator.msDoNotTrack,
DNTtrue = "yes" || "1";
if(DNT === DNTtrue || msDNT === DNTtrue){
alert("true");
}else{
alert("false");
}

You can't to it like this. The expression "yes" || "1" is evaluated at the moment it is encountered. So you end up comparing DNT and msDNT to "yes". There is no way to tell JS to evaluate an expression later instead. In even then, DNT === "yes" || "1" or DNT === ("yes" || "1") would not yield desired results either.
Here is an alternative solution, which simply tests whether the value of DNT or msDNT exists are property in an object:
var DNTtrue = {"yes": true, "1": true};
if (DNTtrue[DNT] || DNTtrue[msDNT]) {
// ...
}
If DNT or msDNT have a different value than "yes" and "1", then DNTtrue[...] tries to access a non-existing property which will result in undefined (a falsy value).

In modern browsers you could use an array and the indexOf() method:
DNTtrue = ["yes", "1"];
if(DNTtrue.indexOf(DNT) > -1 || DNTtrue.indexOf(msDNT) > -1){
alert("true");
}else{
alert("false");
}

Try DNT.value inside if statement
Make DNTtrue=true not to yes

Related

using if statement with && and || inside for loop

I have an if statement inside for loop with more than one condition. I want to match the data in database with input data in an HTML form. When the input field in the form is blank it is stored as null in the database. I have this column(itemsSortedByDate[i].FD_MIMO) in the database which can be null or can have some value. I am unable to match the blank field with null in the database. Also even if that column(itemsSortedByDate[i].FD_MIMO) has some value in the database, my for loop searches for the database which has null field just because other fields are matching. My Javascript is as below. The last condition is creating problems. ScenarioListViewModel.fdMimo()and itemsSortedByDate[i].FD_MIMO are supposed to be same whether it's null or has some value. But in the console.log they are different. Thank you for your help, much appreciated.
self.getJobIdForCapacity = function(itemsSortedByDate){
var jobIdForCapacity;
var found = false;
for (var i = 0, len = itemsSortedByDate.length; i < len; i++) {
if(itemsSortedByDate[i].DB_Name == ScenarioListViewModel.db_name()
&& itemsSortedByDate[i].Split_Mode == ScenarioListViewModel.splitMode()
&& itemsSortedByDate[i].Full_Output == ScenarioListViewModel.fullOutput()
&& (itemsSortedByDate[i].Workflow_Status == "Completed" || itemsSortedByDate[i].Workflow_Status == "Running")
&& (itemsSortedByDate[i].Disposition == "Success" || itemsSortedByDate[i].Disposition == "None")
&& (itemsSortedByDate[i].FD_MIMO == ScenarioListViewModel.fdMimo() || itemsSortedByDate[i].FD_MIMO == null)){
jobIdForCapacity = itemsSortedByDate[i].Title;
console.log("Job Id:" + jobIdForCapacity);
console.log("fdmimo from form:" +ScenarioListViewModel.fdMimo());
console.log("fdmimo from list:" +itemsSortedByDate[i].FD_MIMO);
self.getJobResults(jobIdForCapacity);
found = true;
break;
}
}
if (!found) {
alert("Job not found in Sharepoint Execution History List. Click Execute Model to run");
}
};
I would suggest you use === in all the conditions in if statement and it may help you solve your problem as there is difference in === vs ==.
Please refer this question for the difference.
For example:
itemsSortedByDate[i].DB_Name == ScenarioListViewModel.db_name()
will be
itemsSortedByDate[i].DB_Name === ScenarioListViewModel.db_name()
Condition:
"Completed" || itemsSortedByDate[i].Workflow_Status == "Running"
will always return "Completed" does not matter itemsSortedByDate[i].Workflow_Status == "Running" is true or false. Here your can use ternary operator like
itemsSortedByDate[i].Workflow_Status == "Running"? "Running" : "Compelted"
Something of this kind. Check all conditions like this.

nested if statement in one line

if(something.food == true){
if(something.food.fruit == 'apple' || something.food.fruit == 'mango'){
//do something
}
}
this is clear where food must be true later check it's child object, but how to write this in one line? I mean with single if.
If something.food is true then it can not be an object containing fields as well. Though your current check does check for a "truthy" value, it reads quite strange (thanks for pointing this out T. J. Crowder). Instead you should just leave out the == true part.
The resulting check is:
if (something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango') {
//do something
}
That's all
if(something.food && (something.food.fruit == 'apple' || something.food.fruit == 'mango')) {
//do something
}
As a petition in the comments, I will explain that.
First we check something.food without == true because we need to check if it exists. Then wrap the rest of code into parenthesis and the expression will run ok

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.

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') {
...
}

Javascript OR in an IF statement

I am trying to make an if statement in javascript that will do something if the variable does not equal one of a few different things. I have been trying many different variations of the OR operator, but I cant get it to work.
if(var != "One" || "Two" || "Three"){
// Do Something
}
Any ideas? Thanks!
Update:
I have tried this before:
if(var != "One" || var != "Two" || var != "Three"){
// Do Something
}
For some reason it does not work. My variable is pulling information from the DOM i dont know if that would effect this.
Actual Code
// Gets Value of the Field (Drop Down box)
var itemtype = document.forms[0].elements['itemtype' + i];
if(itemtype.value != "Silverware" || itemtype.value != "Gold Coins" || itemtype.value != "Silver Coins"){
// Do Something
}
Your expression is always true, you need:
if(!(myVar == "One" || myVar == "Two" || myVar == "Three")) {
// myVar is not One, Two or Three
}
Or:
if ((myVar != "One") && (myVar != "Two") && (myVar != "Three")) {
// myVar is not One, Two or Three
}
And, for shortness:
if (!/One|Two|Three/.test(myVar)) {
// myVar is not One, Two or Three
}
// Or:
if (!myVar.match("One|Two|Three")) {
// ...
}
More info:
De Morgan's Laws
Edit: If you go for the last approaches, since the code you posted seems to be part of a loop, I would recommend you to create the regular expression outside the loop, and use the RegExp.prototype.test method rather than String.prototype.match, also you might want to care about word boundaries, i.e. "noOne" will match "One" without them...
Assuming you mean "val does not equal One or Two or Three" then De Morgan's Theorem applies:
if ((val != "One") && (val != "Two") && (val != "Three")) {
// Do something...
}
For a shorter way to do it, try this format (copied from http://snook.ca/archives/javascript/testing_for_a_v):
if(name in {'bobby':'', 'sue':'','smith':''}) { ... }
or
function oc(a)
{
var o = {};
for(var i=0;i<a.length;i++)
{
o[a[i]]='';
}
return o;
}
if( name in oc(['bobby', 'sue','smith']) ) { ... }
The method mentioned by Mike will work fine for just 3 values, but if you want to extend it to n values, your if blocks will rapidly get ugly. Firefox 1.5+ and IE 8 have an Array.indexOf method you can use like so:
if(["One","Two","Test"].indexOf(myVar)!=-1)
{
//do stuff
}
To support this method on IE<=7, you could define a method called Array.hasElement() like so:
Array.prototype.hasElement = function hasElement(someElement)
{
for(var i=0;i<this.length;i++)
{
if(this[i]==someElement)
return true;
}
return false;
}
And then call it like so:
if(!["One","Two","Three"].hasElement(myVar))
{
//do stuff
}
Note: only tested in Firefox, where this works perfectly.
In addition to expanding the expression into three clauses, I think you'd better name your variable something other than var. In JavaScript, var is a keyword. Most browsers aren't going to alert you to this error.
Alternate way using an array:
var selected = ['Silverware', 'Gold Coins', 'Silver Coins'];
if ( selected.indexOf( el.value ) != -1 ) {
// do something if it *was* found in the array of strings.
}
Note: indexOf isnt a native method, grab the snippet here for IE:
https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf

Categories