3

I am doing some calculations based on values from two text inputs. Values could be floats or ints. The calculations are triggered on the keyup event.

So at the moment I have to evaluate the val to determine if it is a float or int and then use parseInt or parseFloat as appropriate.

This seems a bit hacky or overkill. Is there a better way to do this?

Here's a fiddle to demonstrate: https://jsfiddle.net/2hw0tnhb/

HTML:

<label id="x-label" for="x">Float</label>
<br/>
<input type="text" name="x" id="x" value="29.7" class="axis"/>

<br/>
<br/>

<label id="y-label" for="y">Int</label>
<br/>
<input type="text" name="y" id="y" value="21" class="axis"/>

JS:

var $x = $('#x');
var $y = $('#y');
var $axis = $('.axis');
var x_label = $('#x-label');
var y_label = $('#y-label');

$axis.keyup(function(){

    var $this = $(this);
    var val = $this.val();
    var axis = 'x';

    if($this.attr('id') === 'y') axis = 'y';

    //check if int or float:
    if(parseFloat(val) > Math.floor(parseFloat(val))){
        //it is a float - use parseFloat()   
        if( axis === 'x' ){
           x_label.text('Float'); 
        }else{
           y_label.text('Float'); 
        }        
    }
    else{
        //it is an int - use parseInt()
        if( axis === 'x' ){
           x_label.text('Int'); 
        }else{
           y_label.text('Int'); 
        }
    }
});
user3065931
  • 531
  • 7
  • 20

2 Answers2

6

You can use a leading + and the result will be numeric, int or float:

var val = +$this.val(); //or +this.value

And you can use type="number" to keep entries into .axis numeric:

<input type="number" name="x" id="x" value="29.7" class="axis"/>

$(function() {
    var $x = $('#x');
    var $y = $('#y');
    var $axis = $('.axis');
    var x_label = $('#x-label');
    var y_label = $('#y-label');

    $axis.keyup(function(){

        var $this = $(this);
        var val = +$this.val();
        var axis = this.name;
        
        console.log( val );
        console.log( val + 3.5 );
        console.log( val + 4 );
    })
    .trigger('keyup');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label id="x-label" for="x">Float</label>
<br/>
<input type="number" name="x" id="x" value="29.7" class="axis"/>

<br/>
<br/>

<label id="y-label" for="y">Int</label>
<br/>
<input type="number" name="y" id="y" value="21" class="axis"/>

Unary plus (+)
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number. It can convert string representations of integers and floats, as well as the non-string values true, false, and null. Integers in both decimal and hexadecimal ("0x"-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to NaN.

Ref: Arithmetic Operators

PeterKA
  • 24,158
  • 5
  • 26
  • 48
  • That's really cool - I've never seen `+` placed before something like this. How does this work exactly? I know about `type="number"` but I think browser support is a bit patchy. – user3065931 Aug 16 '15 at 13:04
  • 1
    I'm upvoting this but what I've always preferred about parseInt and/or parseFloat is that they more clearly express the intent – Dexygen Aug 16 '15 at 13:54
  • splendid solution worked perfectly :) – Mohammed Baashar Nov 28 '22 at 19:28
0

It seems hacky, yes, however this is one of those unfortunate side-effects of JavaScript's type system. Checking that a number is an integer can be done by looking for a remainder when dividing by 1:

function isInt(n) {
    return n % 1 === 0;
}

You could also refactor your code a little to make it feel less bloated:

$axis.keyup(function(){
    var $this = $(this);
    var axis = $this.attr('id');
    var val = $this.val();
    var isInt = isInt(val);
    var text = (isInt) ? 'Int' : 'Float';

    var labelMap = {
        x: x_label,
        y: y_label
    };

    labelMap[axis].text(text);
});
sdgluck
  • 24,894
  • 8
  • 75
  • 90