If statement condition is met, but contents not executed? - javascript

I've got an two if() statements, for which the conditions are both met with the default values in the <select> and <input> form fields I've tested this by assigning the values to a variable and writing the variable. (0 and Url).
However, it seems that neither if() statement's contents execute properly.
Here's a link to my JSFiddle: http://jsfiddle.net/cfRAk/2/
Any edits/answers as to why this is happening would be greatly appreciated!

Change this line:
var geo_select_val = $('select[name=g_country\\[1\\]]').val();
To this:
var geo_select_val = parseInt($('select[name=g_country\\[1\\]]').val());
The thing is geo_select_val is actually "0" and not 0. Converting a string to boolean will only result in false if string is empty. "0" is not empty, so it was being evaluated as true. Since you are going !geo_select_val, it never goes in.
Caveat: this fix will only work if you make sure all values are numbers. If that's not the case, check for equality with "0"

Here's the code you're asking about:
$('#post-form').click( function() {
var geo_select_val = $('select[name=g_country\\[1\\]]').val();
if(!geo_select_val) {
var geo_url_val = $('input[name=g_url\\[1\\]]').val();
if(geo_url_val != "http://google.com") {
$('#notification').html("You need to enter a valid url");
}
}
});
When I set a breakpoint in this click function and then click on the Post Form div, geo_select_val comes back as "0" which means that if(!geo_select_val) will fail because geo_select_val does have a value so the first if condition will never be executed.
Perhaps you want the first if condition to be:
if (geo_select_val != "0") {
which will tell you if some other value besides the default has been selected (assuming you add other options to that select tag with different values).

Related

Check values of loop to see if ANY match?

In ruby, I would do something like:
array = [1,2,3]
array.any? {|a| a == 1}
=> true
Although, instead of an array, I am going up against a hash
var shop_products = {"607":607};
I have a checkbox loop and I want to check against all currently checked boxes for when checkboxes are both checked and unchecked to then see if there is a matching value and disable/able and hide/show a button if so.
code: https://jsfiddle.net/mk879vu2/7/
As #Mark Meyer mentioned, some can help but is there a way to use this against a hash or an alt for hashes?
I tried this: https://jsfiddle.net/jq9sgp58/
Maybe I am using this wrong?
My issue right now is when a checkbox is unchecked, it sees that the value is the "correct" one, but it isn't displaying the button when I uncheck. I'm doing something wrong in the conditional somehow.
In the jsfiddle I have all of the inputs but I only want one of the buttons (of the 2) to appear when a record with specific parameters is checked (in the example this is value=607, this can be any amount but in the example I have it as 1 record/input). But when I uncheck and the 607 is left alone as the only checked input, it runs the hide/disable and not the show.
What is wrong with my code?
It sounds like you are looking for #array.some()
let a = [1,2,3]
console.log(a.some(n => n === 1)) // true
console.log(a.some(n => n === 4)) //false
https://jsfiddle.net/2kaegb59/
The .some seemed like the way to get it done but i couldn't get it to work with the hash. I'm sure it's possible. Although, I ended up just checking for an undefined through the hash instead of trying to match up the check value with the hash value and it is likely unnoticeably faster.
for (var check of checked_checkboxes_check) {
if (shop_products[check.value] === undefined) {
print_submit.hide().prop("disabled", true);
break;
} else {
print_submit.show().prop("disabled", false);
}
}

Replace 'null' values from AJAX call

I have an AJAX call which gets time (in minutes) from a database. However, if the value fetched from the database is null, I want to replace "null" to show "0 minutes". Right now, it doesn't display anything if the time is null.
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
$(function() {
$.getJSON($SCRIPT_ROOT + '/_ajax',
function(data) {
$("#timePeriod").text(data.timePeriod);
if (data.timePeriod == null) {
data.timePeriod = '0';
}
});
});
This is then displayed in the HTML using the following span tag:
Average time: <span id="timePeriod"></span> mins
The if statement in my AJAX code doesn't work as intended. It doesn't display anything (not even null, although that is what's being returned). How can I properly replace this value so that it displays a '0' when the result is null?
If I understood the problem properly (despite I'm not really aware why you are using data.wait), it should be as easy as:
data.timePeriod = !isNaN(+data.timePeriod) ? +data.timePeriod : '0';
$("#timePeriod").text(data.timePeriod);
Explanation:
(Logically) you want to check whether the data you are receiving is valid. It may be null (sure), but it also may hold any other strange value. So, to be 100% sure that the value actually can be parsed, we firstly try to cast it to a number (using the unary operator +), then we check whether it's NOT a NaN: !isNan, the evaluation will return true if the the result effectively is a number.
If it is, it assigns the value to the data object, else it assigns '0'.
The second line just put the value in the span element.
document.getElementById('timePeriod').innerText = +data.timePeriod
Using + converts to a number, +null is already 0.
document.getElementById('timePeriod').innerText = +null
Average time: <span id="timePeriod"></span> mins

How do you compare JavaScript innerHTML return values, when there's a special character involved?

I have a web page with a form on it. The "submit" button is supposed to remain deactivated until the user fills in all the necessary fields. When they fill in a field, a checkmark appears next to it. When all the checkmarks are there, we're good to go.
A checkmark might be set by code like this:
if (whatever) checkLocation.innerHTML = CHECKMARK;
Here's the code I'm using to do the final check. It just loops through all the locations where there may be checkmarks. If it finds a location without a mark, it disables the submit button and leaves. If it gets through them all, it activates the button and returns true.
function checkSubmitButton() {
var button = document.getElementById(SUBMIT_BUTTON);
for (var i=0; i<CHECK_LOCATIONS.length; i++) { // should be for-each, but JS support is wonky
var element = document.getElementById(CHECK_LOCATIONS[i]);
console.log(CHECK_LOCATIONS[i] +": " +element.innerHTML);
// if found unchecked box, deactivate & leave
if (element.innerHTML != CHECKMARK) {
button.disabled = true;
return false;
}
}
// all true--activate!
console.log("ACTIVATING BUTTON!");
button.disabled = false;
return true;
}
Here's the problem: this works so long as the const CHECKMARK contains something simple, like "X". But specs call for a special HTML character to be used: in this case ✓, or ✓. When I do the comparison (in the if line) it ends up comparing the string "✓" to the string "✓". Since these two are not equal, it doesn't recognize a valid checkmark and the button never activates. How can I compare the contents of the HTML element my constant? (And hopefully make the code work even if down the road somebody replaces the checkmark with something else.)
Thanks.
There is no problem with the check character and it behaves exactly like the X character. The problem is, that your html have the checkmark character stored as html entity in hex string. If you compare checkmark to checkmark it works just fine: https://jsfiddle.net/m7yoh026/
What you can do in your case is to make sure the CHECKMARK variable is the actuall checkmark character, not the html entity.
Other option is to decode the html entity: https://jsfiddle.net/m7yoh026/3/
var CHECKMARK = '✓'
var decoded_checkmark = $('<textarea />').html(CHECKMARK).text();
console.log($('div')[0].innerHTML)
if ($('div')[0].innerHTML == decoded_checkmark) {
$('body').append('checkmark recognized<br>')
}
You can convert a character to its HTML entity equivalent like so:
var encoded = raw.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#'+i.charCodeAt(0)+';';
});
Well, here's what I ended up doing: I made a function called encodeHtml() that takes a character or string, writes it to a brand new div, and then returns what's contained in that div:
function encodeHtml(character) {
var element = document.createElement("div");
element.innerHTML = character;
return element.innerHTML;
}
Then I can compare to what it returns, since it automatically changes "✓" to "✓", and will work with any unforeseen changes to that character. It's a bit of a kludge, but it works. (It's still not clear to me why JavaScript does this automatic conversion...but there are many design choices in which JavaScript mystifies me, so there you go.)
Thanks all for the help.

if statements in for loop both executing instead of just one

First If statement works just fine, then it goes into the for loop as expected BUT THEN OUT OF NOWHERE, it decides to execute both if statements (which they are contradictory of each other "==" and "!=")..I don't understand :(
if($scope.firstinitial==$scope.firstinput&&$scope.secondinitial==$scope.secondinput){
$scope.initialmatches="MATCHES THE INITIALS";
for (var i=0; i<$scope.discountcodes.length; i++) {
console.log($scope.discountcodes[i]);
if($rootScope.discountcodeinput.attempt.toLowerCase()!=$scope.discountcodes[i]){
$scope.changeBack();//DOES ONLY IF INPUT DOES NOT MATCH DATA
}
if($rootScope.discountcodeinput.attempt.toLowerCase()==$scope.discountcodes[i]){
console.log($scope.discountcodes[i]);//DOES ONLY IF INPUT MATCHES DATA
$scope.changeBackAgain();
}
}
}
UPDATE:
After bug testing, only the last discount code when matched works correctly...which boggles my mind even further. So when the user types in the discount code which matches the last discount code in the array, then only the first if statement triggers and not the second one. Any ideas?
I think whatever is happening inside $scope.changeBack(); is making the second condition true
If $scope.changeBack(); does something to modify discountcodes[i] or $rootScope.discountcodeinput.attempt it is possible for the second if statement to execute. What you probably mean to do is:
for (var i=0; i<$scope.discountcodes.length; i++) {
if($rootScope.discountcodeinput.attempt.toLowerCase()!=$scope.discountcodes[i]){
$scope.changeBack();//DOES ONLY IF INPUT DOES NOT MATCH DATA
}
else {
$scope.changeBackAgain();
}
}
Apparently using the == operator can have very unexpected results due to the type-coercion internally, so using === is always the recommended
also add an else statement in there if you don't need both of them executing.
Other than that I would say that something is changing, I would step through it in the debug window and see what the current results are for each variable or print them to the console.
if($scope.firstinitial==$scope.firstinput&&$scope.secondinitial==$scope.secondinput){
$scope.initialmatches="MATCHES THE INITIALS";
for (var i=0; i<$scope.discountcodes.length; i++) {
console.log($scope.discountcodes[i]);
if($rootScope.discountcodeinput.attempt.toLowerCase()!==$scope.discountcodes[i]){
$scope.changeBack();//DOES ONLY IF INPUT DOES NOT MATCH DATA
}
else if($rootScope.discountcodeinput.attempt.toLowerCase()===$scope.discountcodes[i]){
console.log($scope.discountcodes[i]);//DOES ONLY IF INPUT MATCHES DATA
$scope.changeBackAgain();
}
}
}
Trying using the else if statement to run one code then the other
<script>
if($scope.firstinitial==$scope.firstinput&&$scope.secondinitial==$scope.secondinput){
$scope.initialmatches="MATCHES THE INITIALS";
for (var i=0; i<$scope.discountcodes.length; i++) {
console.log($scope.discountcodes[i]);
if($rootScope.discountcodeinput.attempt.toLowerCase()==$scope.discountcodes[i]){
console.log($scope.discountcodes[i]);//DOES ONLY IF INPUT MATCHES DATA
$scope.changeBackAgain();
} else if($rootScope.discountcodeinput.attempt.toLowerCase()!=$scope.discountcodes[i]){
$scope.changeBack();
}
}
}
</script>
Obviously ($rootScope.discountcodeinput.attempt.toLowerCase()!=$scope.discountcodes[i] and ($rootScope.discountcodeinput.attempt.toLowerCase()==$scope.discountcodes[i] can not be true at the same time. So I guess you are doing some magic inside $scope.changeBack() that changes the value of either $rootScope.discountcodeinput.attempt or $scope.discountcodes[i], so when the second if gets checked, the value has already changed and the condition passes.
I would suggest breaking out of the iteration as soon as you know you are done, by adding a continue statement. Something like this:
for (var i = 0; i < $scope.discountcodes.length; i++) {
console.log($scope.discountcodes[i]);
if ($rootScope.discountcodeinput.attempt.toLowerCase() != $scope.discountcodes[i]) {
$scope.changeBack(); //DOES ONLY IF INPUT DOES NOT MATCH DATA
continue; // done
}
// no need to check again
console.log($scope.discountcodes[i]); //DOES ONLY IF INPUT MATCHES DATA
$scope.changeBackAgain();
}
I figured it out...
Essentially the for loop was going through and checking both if statements with each object, if the first object matched it would trigger the first if statement and not the second. BUT then the for loop would continue and look at the next object in the array and only trigger the second if statement...then it would loop through with the third object in the array and again only trigger the second if statement...so on and so on.
The workaround I came up with was just embedding both into another if statement that checked for a var value of yes
if($scope.value=="no")
then I placed the not equal if statement (!=) first and the equal if statement (==) second. Finally, I added in the (==) if statement:
$scope.value="yes";
thus avoiding going through the parent if statement on every loop of the for loop.
Thanks everyone for the help...this was killing me!

javascript variables always not equal

I have two variables, totalGuess and condensedAnswer. I am creating a jQuery click event and if totalGuess doesn't equal condensedAnswer then the click event will not occur and a div called message will display the message "Sorry, but your answer is incorrect. Please try again."
The problem is, totalGuess in the if statement is never equal to condensedAnswer. I've tried seeing typeof and they are both strings. I've tried console.log(totalGuess+"\n"+condensedAnswer); and they both return the same value. I've tried hardcoding the condensedAnswer, and totalGuess was able to be equal to the hardcoded answer. But when I tried comparing condensedAnswer with the hardcoded answer, it's not equal, even though the console.log value for condensedAnswer is the same. I'm not what's wrong.
Here's the code snippet:
$('.submitGuess').click(function(e){
var totalGuess = "";
var condensedAnswer = answer.replace(new RegExp(" ","g"), "");
$('.crypto-input').each(function(){
totalGuess += $(this).val();
});
// if incorrect guess
if(totalGuess !== condensedAnswer) {
$('.message').text("Sorry, but your answer is incorrect. Please try again.");
e.preventDefault();
}
// if user wins, congratulate them and submit the form
else {
return true;
}
});
If it helps, here's the page, just a random test cryptogram plugin for Wordpress:
http://playfuldevotions.com/archives/140
The problem has nothing to do with the check. The problem is the fact your value you are checking against has hidden characters. However you are getting that string has the issue.
Simple debugging shows the problem
> escape(totalGuess)
"God%27sMasterpieceMatthew15%3A99Psalms129%3A158"
> escape(condensedAnswer)
"God%27sMasterpieceMatthew15%3A99Psalms129%3A158%00"
It has a null character at the end.
Now looking at how you fill in the answer you have an array with numbers
"071,111,100,039,...49,053,056,"
Look at the end we have a trailing comma
when you do a split that means the last index of your array is going to be "" and hence why you get a null.
Remove the trailing comma and it will magically work.

Categories