logic error in javascript code - javascript

I am trying to write some logic that will check for the existence of a specific record in two tables.
If the row exists in either table, I want to return TRUE.
For table A, when the record is added to the table, the id field looks like "123".
For table B, the same record would have the id of "a123". However, the value i have to search for the record is "row_123".
This is what my code looks like right now :
var checkForDuplicates = function(row_id) {
return !!($('#existing_members').find('#' + row_id.replace('row_','')).length || $('#selected_users').find('#' + row_id.replace('row_','a').length) );
};
I want the function to return true if the record exists in either table.
However, this statement returns true in cases when it should be false.
What I've tried so Far
I've been playing around in the console to make sure that my logic is correct:
!!(1 || 0) //returns true
!!(0 || 0) //returns false
!!(0 || 1) //returns true
I'm also currently reviewing the replace statements to make sure the find() is being supplied the right strings.
But a second pair of eyes to confirm that my logic is correct would be appreciated.
Thanks
EDIT 1
The solution, using Max's suggestion would be:
var checkForDuplicates = function(row_id) {
var parts = row_id.split('_');
var tableB = '#a'+ parts[1];
var tableA = '#' + parts[1];
return !!($('#existing_members').find(tableA).length || $('#selected_users').find(tableB).length);
}
However, as Ankit points out, I just had a typo in my original code. So this would be my final answer / solution:
var checkForDuplicates(row_id) {
return !!( $('#existing_members').find('#' + row_id.replace('row_', '')).length || $('#selected_users').find('#' + row_id.replace('row_','a')).length);
}

Your code has a typo at the end of return statement
...'a').length)); //it returns object which always evaluates to true
it should be
...'a')).length);
DEMO
var checkforduplicates = function(row_id){
//row_id looks like "row_123"
return !!($('#tableA').find('#' + row_id.replace('row_','')).length || $('#tableB').find('#' + row_id.replace('row_','a')).length );
}
alert(checkforduplicates("row_123"));
<table id=tableA><tr><td id="123">123 ID</td></tr></table>
<table id=tableA><tr><td id="a13">a13 ID</td></tr></table>

Corrected few issues to make the code more efficient:
var checkforduplicates = function(row_id) {
var id = row_id.split('_')[1]; // [ 'row', '123']
return $('#'+id).length || $('#a'+id).length;
}
No need for !! as operator || produces boolean result (true or
false)
Used $('#'+id) as more efficient jQuery selector
Removed unnecessary find(..) call
Eliminated unnecessary parenthesis (which had an issue)

I want the function to return true if the record exists in either table.
var checkForDuplicates = function(row_id) {
row_id = row_id.substring(4); // 'row_123' -> '123'
var table_A_row_id = row_id;
var table_A_row_exists = $('#tableA').find('#' + table_A_row_id).length > 0;
var table_B_row_id = 'a' + row_id;
var table_B_row_exists = $('#tableB').find('#' + table_B_row_id).length > 0;
return table_A_row_exists || table_B_row_exists;
};

of course it is returning the opposite of the things you want, cause you are using !!.
! is used to negotiate the return value of the specific function/variable e.g.:
if(!var_x == false)
this example only works if var_x is true.
So please be aware to avoid !! ;)
Please use a single ! instead!

Related

find specific number in array for if statement

I know there are alot of questions like this on here but they keep pointing me to using includes and that is not working for me for some reason.
Goal - use an if statement to find out if a number exists in an array. (Don't care if its jQuery or plan JS)
I tried using includes but that failed:
testdata = [1,256]
testdata.includes(1) #or testdata.includes(256)
\\false
I also tried using indexof but that failed too:
testdata = [1,256]
testdata.indexOf('256') >= 0
\\false
Indeed, it looks like your array [1,256] is the first element of testdata array. In fact, you can see that testdata length is 1.
You should check if testdata[0].includes(1)
Your array is numbers but your .indexOf argument is a string.
The snippet below works fine.
If you need true/false, use a conditional block like:
let numberFound = false;
if (testdata.indexOf(256)>-1) {
numberFound = true;
} else {
numberFound = false;
}
Instead of the full if/else block, it is more usual to condense the conditional using the ternary operator
like this:
numberFound = (testdata.indexOf(256) > -1) ? true : false)
finally, if you're testing several entries, use a function to return true/false depending on what was passed to it:
function numberFound(number,array) {
return (array.indexOf(number) > -1) ? true : false;
}
I've amended the snippet:
const testdata = [1,256]
console.log(testdata.indexOf(256));
console.log("test for 25: ", (testdata.indexOf(25) > -1) ? true : false);
console.log("test for 56: ", (testdata.indexOf(56) > -1) ? true : false);
console.log("test for 256: ", (testdata.indexOf(256) > -1) ? true : false);
function numberFound(number,array) {
return (array.indexOf(number) > -1) ? true : false;
}
console.log("function testing 256:", numberFound(256,testdata));
console.log("function testing 25:", numberFound(25,testdata));
It is not working for you because you use it in the wrong way. # is the private identifier in JS. If you use // instead it works.
testdata = [1,256];
console.log(testdata.includes(1)); // or testdata.includes(256)

Append class with if statement

I just created a variable for a specific site of mine but I want to append a class entitled "partner-text" if I'm actually on that site. If I'm on a different site then don't append it. How can I do that?
use(function() {
var inPartnerPath = currentPage.getPath().indexOf("partners_Skate_Daily");
// to check if the site is under partners_Skate_Daily folder if yes then it should return true
var isPartner = (inPartnerPath != -1) ? 'true' : 'false';
return {
isPartner: isPartner
};
});
'true' and 'false' are strings. You want to use the boolean values true/false.
You don't even need the ?: here, != already returns you a boolean.
var isPartner = inPartnerPath != -1;

Javascript - check if string is part of a string in an array

I have an array which lists a couple of websites:
var validSites = new Array();
validSites[0] = "example_1.com";
validSites[1] = "example_2.com";
validSites[2] = "example_3.com";
now i have a small script which checks what web address you are on and could return something like this:
example_1.com/something/something_else
now i need to check if that address is one of the valid sites.
so
example_1.com/*ANYTHING*
would pass as correct.
but
exampleshmample.com
would pass as incorrect.
Now i know you can do an indexOf() which can check if a string is part of a string and it would return -1 if false. but how would i check it through the entire array?
P.s - its for a Chrome Extension.
thanks
Here’s an idea:
var str = 'example_1.com/something/something_else';
if( validSites.indexOf( str.split('/')[0] ) > -1 ) {
// is valid
}
Another one is to use regexp on a joined array:
var str = 'example_1.com/something/something_else';
new RegExp('^('+validSites.join('|')+')','i').test(str);
This will also match f.ex example_1.comyoyoyo
if (validStates.indexOf("example_1.com") > -1) {
// Then it's inside your array
}
else {
// Then it's not inside your array
}
I'd go with json notation, if you can switch from an array, in this scenario
var validSites = {
"example_1.com":"valid",
"example_2.com":true,
"example_3.com":1 //you could even start putting paths in here to beef up your check.
};
//..your check function would be:
.....
if(validSites[window.location.hostname]){
return true;
}else{
return false;
}
You can achieve this by looping and setting flag variable, Try this, i am not tested this.
Just i typed the code directly. i think this may help you
var flag =0;
var givenurl='example_1.com/*ANYTHING*';
for(int i=0 i<validSites.length;i++){
if(givenurl.indexOf(validSites[i])){
flag=1 //Found
}
}
if(flag) { //Url Found }else{ //not found }

Is there a way that I can check if a data attribute exists?

Is there some way that I can run the following:
var data = $("#dataTable").data('timer');
var diffs = [];
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
Only if there is an attribute called data-timer on the element with an id of #dataTable?
if ($("#dataTable").data('timer')) {
...
}
NOTE this only returns true if the data attribute is not empty string or a "falsey" value e.g. 0 or false.
If you want to check for the existence of the data attribute, even if empty, do this:
if (typeof $("#dataTable").data('timer') !== 'undefined') {
...
}
if (typeof $("#dataTable").data('timer') !== 'undefined')
{
// your code here
}
In the interest of providing a different answer from the ones above; you could check it with Object.hasOwnProperty(...) like this:
if( $("#dataTable").data().hasOwnProperty("timer") ){
// the data-time property exists, now do you business! .....
}
alternatively, if you have multiple data elements you want to iterate over you can variablize the .data() object and iterate over it like this:
var objData = $("#dataTable").data();
for ( data in objData ){
if( data == 'timer' ){
//...do the do
}
}
Not saying this solution is better than any of the other ones in here, but at least it's another approach...
Or combine with some vanilla JS
if ($("#dataTable").get(0).hasAttribute("data-timer")) {
...
}
All the answers here use the jQuery library.
But the vanilla javascript is very straightforward.
If you want to run a script only if the element with an id of #dataTable also has a data-timer attribute, then the steps are as follows:
// Locate the element
const myElement = document.getElementById('dataTable');
// Run conditional code
if (myElement.dataset.hasOwnProperty('timer')) {
[... CODE HERE...]
}
You can use jQuery's hasData method.
http://api.jquery.com/jQuery.hasData/
The primary advantage of jQuery.hasData(element) is that it does not create and associate a data object with the element if none currently exists. In contrast, jQuery.data(element) always returns a data object to the caller, creating one if no data object previously existed.
This will only check for the existence of any data objects (or events) on your element, it won't be able to confirm if it specifically has a "timer" object.
If you want to distinguish between empty values and missing values you can use jQuery to check like this.
<div id="element" data-foo="bar" data-empty=""></div>
<script>
"foo" in $('#element').data(); // true
"empty" in $('#element').data(); // true
"other" in $('#element').data(); // false
</script>
So from the original question you'd do this.
if("timer" in $("#dataTable").data()) {
// code
}
You can create an extremely simple jQuery-plugin to query an element for this:
$.fn.hasData = function(key) {
return (typeof $(this).data(key) != 'undefined');
};
Then you can simply use $("#dataTable").hasData('timer')
Gotchas:
Will return false only if the value does not exist (is undefined); if it's set to false/null it hasData() will still return true.
It's different from the built-in $.hasData() which only checks if any data on the element is set.
You can check by css attribute selection with
if ($('#dataTable').is('[data-timer]')) {
// data-timer attribute exists
}
This is the easiest solution in my opinion is to select all the element which has certain data attribute:
var data = $("#dataTable[data-timer]");
var diffs = [];
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
Here is the screenshot of how it works.
I've found this works better with dynamically set data elements:
if ($("#myelement").data('myfield')) {
...
}
Wrong answer - see EDIT at the end
Let me build on Alex's answer.
To prevent the creation of a data object if it doesn't exists, I would better do:
$.fn.hasData = function(key) {
var $this = $(this);
return $.hasData($this) && typeof $this.data(key) !== 'undefined';
};
Then, where $this has no data object created, $.hasData returns false and it will not execute $this.data(key).
EDIT: function $.hasData(element) works only if the data was set using $.data(element, key, value), not element.data(key, value). Due to that, my answer is not correct.
I needed a simple boolean to work with. Because it's undefined of not present, and not false, I use the !! to convert to boolean:
var hasTimer = !!$("#dataTable").data('timer');
if( hasTimer ){ /* ....... */ }
An alternative solution would be using filter:
if( $("#dataTable").filter('[data-timer]').length!==0) { /* ....... */ }
var data = $("#dataTable").data('timer');
var diffs = [];
if( data.length > 0 ) {
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
}
And what about:
if ($('#dataTable[data-timer]').length > 0) {
// logic here
}

validate 2 dropdowns (only some combinations valid)

I am completely new to JavaScript.
I have size and color dropdowns on a page for users to order a product, but only certain combinations are available i.e. pink is the only color in large sizes.
I thought I'd make an array of allowed sizes and test the user input against these.
If the choice is invalid then I want a popup to tell the user why.
In the real world I'll use SQL & PHP to create the array of allowed choices, in the example below I've hard coded 3 valid choices for testing. Unfortunately the code below doesn't do anything.
I'm sure it's a simple newb mistake. I really don't know what I'm doing :)
Can somebody help me out?
The validation function is supposed to happen when user clicks the form submit...
<form id="form1" name="form1" method="post" onsubmit="return validate_form()"
action="cart.php">
Here's the function:
<script type="text/javascript">
function validate_form() {
var allowed = new Array();
allowed[0]="10,beige";
allowed[1]="10,black";
allowed[2]="10,pink";
var chosenColInd = document.getElementById("colID");
var chosenColText = colID.options[colID.selectedIndex].text;
var chosenSizeInd = document.getElementById("sizeID");
var chosenSizeText = sizeID.options[sizeID.selectedIndex].text;
var chosenSizeCol = chosenSizeText+","+chosenColText;
var found = "false";
for ( var i = 0; i < allowed.length; i++ ) {
if (allowed[i]=chosenSizeCol) {
found = "true";
}
}
if (found = "false") {
alert( 'The variation you have selected is currently unavailable. Please select another.' );
return false;
} else {
return true;
}
}
</script>
There are a few lines where you use the assignment operator (that is single equals =) instead of one of the equality operators (that is double or triple equals, triple is usually preferred in JavaScript). Example:
if (found = "false") {
Would appear to be the problem at first sight - it's an assignment not a comparison :) use triple equals === instead of single:
if(found === "false") {
Also, consider the following (commented) updates to your code, which reflects more the typical style of JavaScript code:
function validate_form() {
//no need to use new Array(), use array literal instead
var allowed = [
"10,beige",
"10,black",
"10,pink"
];
var chosenColInd = document.getElementById("colID");
var chosenColText = colID.options[colID.selectedIndex].text;
var chosenSizeInd = document.getElementById("sizeID");
var chosenSizeText = sizeID.options[sizeID.selectedIndex].text;
var chosenSizeCol = chosenColText+","+chosenSizeText;
var found = "false";
for ( var i = 0; i < allowed.length; i++ ) {
//use equality operator instead of assignment
if (allowed[i]===chosenSizeCol) {
found = true; //may as well use a boolean rather than string
break; //exit loop early, no need to continue if we've already found
}
}
if (!found) { //no need to do a comparison with already boolean values
alert( 'The variation you have selected is currently unavailable. Please select another.' );
}
//may as well just return found here now that we're using a boolean
return found;
}

Categories

Resources