Reputation: 1111
I have the following code with following conditions:
My only problem is that the code interprets 0
as null
. So, If I put 1 minutes 0 seconds, then nothing shows.
I want it to show "fast" when I enter 1 minute 0 seconds.
Thanks in advance.
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<!-- TODO: Missing CoffeeScript 2 -->
<script type="text/javascript">//<![CDATA[
$(window).load(function(){
$('input').keyup(function(){
var min = 60 * Number($('#D').val());
var sec = Number($('#E').val());
if ((min+sec) <= 60) {document.getElementById("Run").innerHTML = "Fast";}
if ((min+sec) >= 61) {document.getElementById("Run").innerHTML = "Slow";}
if (min == null | min == "") {document.getElementById("Run").innerHTML = "";}
if (sec == null | sec == "") {document.getElementById("Run").innerHTML = "";}
});
});
</script>
<style>
h1 { margin: 0 10px 25px 5px; padding: 5px; font-size: 32px; font-family: Arial }
input { margin: 0 10px 10px 10px; padding: 5px; font-size: 24px; width: 200px }
label { margin: 0 10px 10px 10px; font-size: 20px; display: block; font-family: Arial }
span { margin: 0 0px 0px 10px; font-size: 44px; font-family: Arial }
stat { margin: 0 0px 0px 10px; font-size: 24px; font-family: Arial }
</style>
</head>
<body>
<input id="D"
type="number"
class="form-control formBlock"
placeholder="Minutes"
required=""
min="1"
max="59"
onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
>
<stat id="Run"></stat><br>
<input id="E"
type="number"
class="form-control formBlock"
placeholder="Seconds"
required=""
min="1"
max="59"
onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
>
<br>
<br>
<script>
// results
if (window.parent && window.parent.parent){
window.parent.parent.postMessage(["resultsFrame", {
height: document.body.getBoundingClientRect().height,
slug: ""
}], "*")
}
window.name = "result"
//
</script>
</body>
</html>
Upvotes: 4
Views: 2900
Reputation: 136638
When using type="number"
inputs, use it completely.
They do offer a valueAsNumber
property getter, which will coerce your values directly to Numbers, so all you have to do next, is to use them after a fool-guard check against isNaN()
:
$(window).load(function() {
const min_input = $('#D')[0];
const sec_input = $('#E')[0];
const run_elem = document.getElementById("Run");
$('input').keyup(function() {
var min = 60 * min_input.valueAsNumber;
var sec = sec_input.valueAsNumber;
if( isNaN(min + sec) ) {
run_elem.innerHTML = "";
}
else if ((min + sec) <= 60) {
run_elem.innerHTML = "Fast";
}
else if ((min + sec) >= 61) {
run_elem.innerHTML = "Slow";
}
});
});
h1 {
margin: 0 10px 25px 5px;
padding: 5px;
font-size: 32px;
font-family: Arial
}
input {
margin: 0 10px 10px 10px;
padding: 5px;
font-size: 24px;
width: 200px
}
label {
margin: 0 10px 10px 10px;
font-size: 20px;
display: block;
font-family: Arial
}
span {
margin: 0 0px 0px 10px;
font-size: 44px;
font-family: Arial
}
stat {
margin: 0 0px 0px 10px;
font-size: 24px;
font-family: Arial
}
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<input id="D" type="number" class="form-control formBlock" placeholder="Minutes" required="" min="0" max="59" onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }">
<stat id="Run"></stat><br>
<input id="E" type="number" class="form-control formBlock" placeholder="Seconds" required="" min="0" max="59" onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }">
Upvotes: 1
Reputation: 43718
"My only problem is that the code interprets 0 as null"
That's an incorrect assumption, since Number('0') == null
is false
.
The reason your code behaves like that is 0 == ''
is true in JavaScript. You could use ===
for strict equality, but then both of your conditions would never be entered since min
nor sec
can be === null
or === ''
.
min
and sec
are assigned the result of a number conversion which can only yield a valid number or NaN
. Anything that doesn't coerce to a number would give NaN
. Unfortunately blank strings does coerce to 0
, but you can use the ||
operator to coerce ''
into NaN
, since empty string is the only falsy value you can get from your input values (given type="number"
).
From that point the values can either be numbers or NaN
. Given that NaN + number
gives out NaN
you can safely assume that if isNaN(min + sec)
then one of the inputs were invalid or blank.
Also note that you're using |
(bitwise or) instead of ||
. The if branching outcome was the same as ||
in your code because the left-hand-side and right-hand-side were booleans, but it's more semantically correct to use ||
.
EDIT: @Kaiido makes a point using input.valueAsNumber
, which properly coerces ''
to NaN
already, removing the need for Number(input.value || NaN)
. See his answer for a slightly better solution.
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<!-- TODO: Missing CoffeeScript 2 -->
<script type="text/javascript">//<![CDATA[
$(window).load(function(){
$('input').keyup(function(){
const min = 60 * Number($('#D').val() || NaN);
const sec = Number($('#E').val() || NaN);
const total = min + sec;
const speed = isNaN(total)? '' : (total <= 60? 'Fast' : 'Slow');
document.getElementById("Run").innerHTML = speed;
});
});
</script>
<style>
h1 { margin: 0 10px 25px 5px; padding: 5px; font-size: 32px; font-family: Arial }
input { margin: 0 10px 10px 10px; padding: 5px; font-size: 24px; width: 200px }
label { margin: 0 10px 10px 10px; font-size: 20px; display: block; font-family: Arial }
span { margin: 0 0px 0px 10px; font-size: 44px; font-family: Arial }
stat { margin: 0 0px 0px 10px; font-size: 24px; font-family: Arial }
</style>
</head>
<body>
<input id="D"
type="number"
class="form-control formBlock"
placeholder="Minutes"
required=""
min="1"
max="59"
onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
>
<stat id="Run"></stat><br>
<input id="E"
type="number"
class="form-control formBlock"
placeholder="Seconds"
required=""
min="1"
max="59"
onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
>
<br>
<br>
<script>
// results
if (window.parent && window.parent.parent){
window.parent.parent.postMessage(["resultsFrame", {
height: document.body.getBoundingClientRect().height,
slug: ""
}], "*")
}
window.name = "result"
//
</script>
</body>
</html>
Upvotes: 3
Reputation: 7305
Marco's got the fix for your immediate problem, where you need to compare for type as well as value by using ===
(strict comparison). More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
You also have an issue with your logic, where you are using the bitwise OR |
in your conditionals. I'm sure you mean to use a normal OR comparison, ||
:
if (min === null || min === "") {document.getElementById("Run").innerHTML = "";}
if (sec === null || sec === "") {document.getElementById("Run").innerHTML = "";}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
Upvotes: 2