jQuery Knob displays NaN when value is 0 - javascript

It's really weird.
$(function(){
$('.dial').knob({
return value + '%';
});
});
That was my original code to get the percent sign to show up, which works great. For some reason, when the value is 0, on page load it displays as NaN. The weird thing is that only once you highlight the text and then click off does it show the actual value of 0 (replacing the NaN value). Any idea what is causing this to happen? I tried to handle it in the format hook:
$(function(){
$('.dial').knob({
'format': function( value ){
if(value == undefined || value == NaN {
value = 0;
return value + '%';
}
else{
return value + '%';
}
}
});
});
It still doesn't work. I console logged the value I'm passing in, and sure enough it is 0. I'm thinking it may be an 'x loads before y' and therefore it sees the value as undefined, since I am passing in the value attribute by an angularJS data binding. But I'm trying to handle it to no avail. Any thought's on this?

value == NaN will not work because, surprisingly, in javascript NaN does not equal NaN. try isNaN() instead.

Related

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

Strange result while using Javascript not operator

Before anyone jumps in to answer and bash me for asking a silly question; I'm aware of what the not operator does, at least in other languages it should invert a result from true to false and vice versa. The thing I'm stuck on is the strange behavior I get from time to time. I.e. I had this in my code. It's not doing what I expect it to do.
_checkOnOff: function(inst) {
return (!$.suggestBox.onOff || !$.suggestBox._get(inst, 'onOff')) ? false : true;
},
The actual values for the 'onOff' variables that I'm dealing with here are 0 and 1. I'm assuming that the '!' operator will reverse them.
However I couldn't get it to work until I changed the function to explicitly state '== 0' like so...
_checkOnOff: function(inst) {
return ($.suggestBox.onOff == 0 || $.suggestBox._get(inst, 'onOff') == 0) ? false : true;
},
Edit: Added info Both $.suggestBox.onOff and $.suggestBox._get(inst, 'onOff') will be either 0 or 1.
My question is why didn't !$.suggestBox.onOff produce true when $.suggestBox.onOff was equal to 0? Is Javascript ! equivalant to the bitwise operator?
Edit: Second attempt
I tried using '!!' like was suggested (to get a bool) and found nothing changed. Here is the code and outputs:
console.log('val: ' + $.suggestBox.onOff); // outputs: 0
console.log('! : ' + !$.suggestBox.onOff); // outputs: false
console.log('!! : ' + !!$.suggestBox.onOff); //outputs: true
console.log('!!! : ' + !!!$.suggestBox.onOff); //outputs: false
The output doesn't change if $.suggestBox.onOff is 1 or 0!!! it's still false, true, false. What is going on?!
Edit: Third attempt I found out that it has something to do with my variable. I don't know how, but it has to do with the way that it has been set. Ok, prepare yourselves, what I'm about to tell you, may very well blow your mind and change the way you type on the keyboard. It's that incredible:
//this.onOff = 0;
console.log('this.onOff: ' + this.onOff); //output: 0
console.log('! : ' + ! this.onOff); //output: false
console.log('!! : ' + !! this.onOff); //output: true
If I uncomment out the 'this.onOff = 0', thereby explicitly assigning this.onOff to a literal, it changes the output to:
0
true
false
I just found out why. I will write it down in the answer section. Small clue is that it's the way the variable $.suggestBox.onOff was set.
It seems that $.suggestBox.onOff is set with "0" as a string, which in JavaScript is always truthy.
Since "0" is truthy and 0 is falsy, you'd expect 0 == "0" to be false, but it's not.
Try the following in your console:
!! "0"; // true
!! 0; // false
0 == "0"; // true
Weird? Yes. Welcome to the awkward world of JavaScript!
To get around this issue, you should either have $.suggestBox.onOff be an actual number, or convert it on the fly:
_checkOnOff: function(inst) {
return !! ( +$.suggestBox.onOff && +$.suggestBox._get(inst, 'onOff') );
}
Update: Since you pointed out in the comments that you're setting it by a text value, use this when setting it so that it's always set as a number:
$.suggestBox.onOff = +$(this).val();
I think you're confused, because you're negating a string, not a number. Strings are a bit different and handled a bit funny when it comes to their evaluation as a boolean.
!0
is true, as expected.
!"0"
is false... so, the question, is "0" truthy?
I wish I had a better source (sitepoint isn't bad, but it's not as authoritative as a w3 document), but, according to http://www.sitepoint.com/javascript-truthy-falsy/
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), empty functions,
empty arrays, and empty objects.
So, what you are seeing is indeed expected.

If-statement never reaches the else part

I'm trying to change the text of a button with the following code.
// hide unavailable courses
$("#availability_button").click(function () {
$(".availability_red").toggle();
if ($(this).val('Show Unavailable')){
$(this).html('Hide Unavailable');
} else {
$(this).html('Show Unavailable');
}
});
The button text changes the first time I use it, but never again. Not sure why that is and I have pretty much hit the limits of my JS debugging knowledge.
I put an alert into it and proved it never reaches down to the else path.
What am i doing wrong?
It always evaluates to true because .val(val) returns the jQuery object and objects are truthy (ToBoolean gives true) values.
Also, you are using .val() whereas you probably want to check the .html()
Try this:
if ($(this).html() === 'Show Unavailable') {
$(this).html('Hide Unavailable');
} else {
$(this).html('Show Unavailable');
}
Demo http://jsfiddle.net/jfetf/
$(this).val("Show Unavailable") is setting the value and returning an object, it's not checking equality.
Try $(this).val() == "Show Unavailable" instead. It will take the current value and compare it to the string.
$(this).val('Show Unavailable') return jQuery object which is interprete as true.
Also $(this).val('Show Unavailable') set value to element...

Setting the value in a select dropdown using javascript

I am having trouble when trying to set a value in a select. I keep seeing NaN as my result (in some browsers - mainly android smartphone / tablet default browsers)
I am running a simply if statement and setting the value if the condition is true:
if (variable1 >= variable2)
{
$('select[title="title"]').val(variable1);
}
Where a 'typeof' check on both variable1 and variable2 before the if statement show them both as numbers. Despite this the resulting value shown in select in the browser is NaN.
I've even tried wrapping the javascript Number() function around the variables like so:
if (Number(variable1) >= Number(variable2))
{
$('select[title="myTitle"]').val(Number(variable1));
}
But I still get the same result!
Note: This works fine in desktop / laptop browsers and even Opera Mobile on my Samsung Galaxy S2 but as I'm working towards this being an app to run on any phone I wanted to be complete in my error checking.
edit:
In case it's my select thats the problem (as suggested below) what's wrong with it here?
Is it because it is converted to a string at the point I return it?
var startPoint = this.do_calcTotal(); // typeof startPoint shows as number
var endPoint = startPoint + 12; // typeof endPoint shows as number
var mySelect = '<select title="myTitle" class="myClass">';
for (o=startPoint; o<endPoint; o++)
{
mySelect += '<option>'+Number(o)+'</option>'; // is this right?? it shows 'o' and 'Number(o)' as typeof number!?
}
mySelect += '</select></span></div>';
return mySelect;
Edit: and the code to add the current selected value to the span for display...
function do_changeNumberSpan(value)
{
$('.mySpan').text(Number(value)); // even tried throwing a Number() round the value here!!
}
Ok. Check out this jsfiddle. This should help you understand a little bit of what your goal is... and how you can accomplish it.
http://jsfiddle.net/aaronfrost/yFuyu/

Detect [i] value

I am trying to make a condition where [i] is a value for data.length, the problem is that everything works okay when there are more than 1 value, but when theres only 1 value, the script doesnt work.
out.href = data[i].href;
out.innerHTML = data[i].alt;
out.appendChild(document.createElement('br'));
}
}
Explanation:
When data.length is more than 1, the result will be object1.href, object2.href, etc.
But when the returned query is only of 1 value, i want it to write just "object.href" without the [i] in it, because this works with yql and when yql returns only 1 object, the object number is direct, doesnt have any value. Instead of object1.href, there will only be object.href but the script keeps placing the value in object[i].href thus failing when only 1 result is returned.
Is there any if...else method for this?
Check the count value which is returned with every YQL response.
if (o.query.count == "1") {
data = [data];
}

Categories