74

I'm trying to add all of the calorie contents in my javascript like this:

$(function() {
    var data = [];

    $( "#draggable1" ).draggable();
    $( "#draggable2" ).draggable();
    $( "#draggable3" ).draggable();

    $("#droppable_box").droppable({
        drop: function(event, ui) {
            var currentId = $(ui.draggable).attr('id');
            var total = 0;
            data.push($(ui.draggable).attr('id'));

            if(currentId == "draggable1"){
            var myInt1 = parseFloat($('#MealplanCalsPerServing1').val());
            }
            if(currentId == "draggable2"){
            var myInt2 = parseFloat($('#MealplanCalsPerServing2').val());
            }
            if(currentId == "draggable3"){
            var myInt3 = parseFloat($('#MealplanCalsPerServing3').val());
            }
        if ( typeof myInt1 === 'undefined' || !myInt1 ) {
        myInt1 = parseInt(0);
        }
        if ( typeof myInt2 === 'undefined' || !myInt2){
        myInt2 = parseInt(0);
        }
        if ( typeof myInt3 === 'undefined' || !myInt3){
        myInt3 = parseInt(0);
        }
        total = parseFloat(myInt1 + myInt2 + myInt3);
        $('#response').append(total);
        }
    });
    $('#myId').click(function(event) {
        $.post("process.php", ({ id: data }), function(return_data, status) {
            alert(data);
            //alert(total);
        });
    });
});

Instead of adding the variables they get concatenated. I've tried using parseInt, parseFloat, and Number but I still just get concatenation and not addition. Please look at the view source at http://maureenmoore.com/momp_112412/121912_800.html

Maureen Moore
  • 1,049
  • 2
  • 9
  • 21
  • I found a simple way out. You can decrement -1 or any negative value it would work the same as addition. For example: If I want to add 1 in a given value of an item, I can do this: var quantity=document.getElementById("quantity"); var btn=document.querySelector("button"); btn.onclick=()=>quantity.value-=(-1); – shakeel70 Nov 12 '22 at 16:16

3 Answers3

113

Your code concatenates three strings, then converts the result to a number.

You need to convert each variable to a number by calling parseFloat() around each one.

total = parseFloat(myInt1) + parseFloat(myInt2) + parseFloat(myInt3);
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
24

Should also be able to do this:

total += eval(myInt1) + eval(myInt2) + eval(myInt3);

This helped me in a different, but similar, situation.

vapcguy
  • 7,097
  • 1
  • 56
  • 52
  • 3
    Why -1? Worked for me. – vapcguy Aug 06 '15 at 18:33
  • 9
    Don't use eval - it's evil! Better to use the specific parseFloat as in the current top voted answer http://stackoverflow.com/a/13953998/283991 – mwotton Nov 13 '16 at 23:59
  • 1
    It largely depends on the input. It is only "evil" if you are using it to evaluate variables that can have user input, because it can allow things like SQL injection attacks since it doesn't do anything to text/string input. By the time in the code above that it got to `total`, the individual components had already had `parseFloat` applied. It didn't need it a 2nd time, for the total. – vapcguy Nov 14 '16 at 14:53
  • It also prevents optimization by the JIT compiler - any use of `eval` prevents optimization of lexical scope because the engine assumes you might be changing the scope. `eval` is ONLY a valid choice when you have no other options - and in this case you have `parseFloat` as an option. – mwotton Nov 16 '16 at 23:17
  • Personally, I'd believe that "optimization" to have a negligible impact on runtime - a few milliseconds at best. But I won't argue the point. Either seems well enough, in this instance, for me. – vapcguy Nov 17 '16 at 15:26
3

The following statement appends the value to the element with the id of response

$('#response').append(total);

This makes it look like you are concatenating the strings, but you aren't, you're actually appending them to the element

change that to

$('#response').text(total);

You need to change the drop event so that it replaces the value of the element with the total, you also need to keep track of what the total is, I suggest something like the following

$(function() {
    var data = [];
    var total = 0;

    $( "#draggable1" ).draggable();
    $( "#draggable2" ).draggable();
    $( "#draggable3" ).draggable();

    $("#droppable_box").droppable({
        drop: function(event, ui) {
        var currentId = $(ui.draggable).attr('id');
        data.push($(ui.draggable).attr('id'));

        if(currentId == "draggable1"){
            var myInt1 = parseFloat($('#MealplanCalsPerServing1').val());
        }
        if(currentId == "draggable2"){
            var myInt2 = parseFloat($('#MealplanCalsPerServing2').val());
        }
        if(currentId == "draggable3"){
            var myInt3 = parseFloat($('#MealplanCalsPerServing3').val());
        }
        if ( typeof myInt1 === 'undefined' || !myInt1 ) {
            myInt1 = parseInt(0);
        }
        if ( typeof myInt2 === 'undefined' || !myInt2){
            myInt2 = parseInt(0);
        }
        if ( typeof myInt3 === 'undefined' || !myInt3){
        myInt3 = parseInt(0);
        }
        total += parseFloat(myInt1 + myInt2 + myInt3);
        $('#response').text(total);
        }
    });

    $('#myId').click(function(event) {
        $.post("process.php", ({ id: data }), function(return_data, status) {
            alert(data);
            //alert(total);
        });
    });
});

I moved the var total = 0; statement out of the drop event and changed the assignment statment from this

total = parseFloat(myInt1 + myInt2 + myInt3);

to this

total += parseFloat(myInt1 + myInt2 + myInt3);

Here is a working example http://jsfiddle.net/axrwkr/RCzGn/