Kirsty Burgoine
Kirsty Burgoine

Reputation: 53

jQuery calculation updating one row at a time

So, I'm trying to create a small table for working out the potential winnings of betting on a rubber duck race when each duck has certain odds.

I sort of have this working but have hit a stumbling block...

When the page loads all of the maths is done correctly based on the default value of £10. What I then want to do is allow people to change the amount of money they would like to bet per duck and the potential winnings for that duck only updates automatically.

This is what I have so far:

function calculate_odds(row) {
    var winnings = 0;
    // Set winnings to 0

    var odds = $(row).find('#theodds').attr('data-duckodds'),
    // Find the value of the data attribute for a specific td

    betting_amount = $('[name="betting-amount"]').val(),
    // Find the value entered into an input field

    winnings = (parseFloat(odds) / 1 + 1) * betting_amount;
    // Work out the winnings based on the odds given. 
    // Divide first number by 1 as all odds are something to 1 for now, then +1
    // Multiply that number by the bet
    // For example Bet 30 on 3/1 odds
    // 3 / 1 = 3 + 1 = 4 * 30 = 120

    $(row).find('.js-winnings').html(winnings.toFixed(2));
    // Show the winnings amount in the final td in each row     
}

$(document).ready(function() {
    $('.lineup tbody tr').each(function() {
        // Run the function calculate_odds() initially based on the default value;
        calculate_odds();

        $(this).find('[name="betting-amount"]').on('keyup', function() {
            // Now loop through each row and change the winnings amount if the betting amount is changed    
            calculate_odds($(this).closest('tr'));
        }).trigger('keyup');
    })
});

From what I understand (my jQuery is not great), within this line: $(this).find('[name="betting-amount"]').on('keyup', function() { all I should need to do is select the specific row I want to update. Which should be simple right?

Instead what this does is takes the updated value from the first row and then applies as that as you change the later rows.

Can anyone point our where I'm going wrong? You can see the calculator here: http://www.kb-client-area.co.uk/ducks/races/race-1/

Thanks in advance :)

Upvotes: 1

Views: 225

Answers (3)

lshettyl
lshettyl

Reputation: 8181

As I said earlier, element IDs must be unique in a given document. You have the id theodds repeated as many times as the number of rows in your table which makes your HTML invalid! Remove those IDs and you could just work around the data-* that you already have.

function calculate_odds(row) {
    row = $(row);
    var winnings = 0,
        //find the data-* from within the context of the keyup - the row
        odds = row.find('[data-duckodds]').attr('data-duckodds'),
        //find the entered amount from within the context of the keyup - the row
        betting_amount = row.find('[name="betting-amount"]').val(),
        //Your math
        winnings = (parseFloat(odds) / 1 + 1) * betting_amount;
    row.find('.js-winnings').html(winnings.toFixed(2)); 
}

$(document).ready(function() {
    //You don't need an each loop here as the keyup will be triggered on every amount box on load as well.
    $('.lineup').on("keyup", "[name='betting-amount']", function() {
        calculate_odds($(this).closest('tr'));
    })
    .find("[name='betting-amount']").keyup();
});

Take a look at this fiddle for a demo.

Upvotes: 0

Tom Hudson
Tom Hudson

Reputation: 136

The specific problem you're encountering is where you're setting betting_amount:

betting_amount = $('[name="betting-amount"]').val()

You're looking globally in the document, and so finding the first instance. Switching it to this makes it work:

betting_amount = $(row).find('[name="betting-amount"]').val()

As an aside: it would be better to use a class instead of an ID for #theodds, as IDs are supposed to be unique per document :)

Upvotes: 2

stef
stef

Reputation: 14268

I think perhaps your 'this' isn't referring to what you think it is in this line: calculate_odds($(this).closest('tr'));

Could you try something along the lines of:

$(this).find('[name="betting-amount"]').on('keyup', function(e) {
            // Now loop through each row and change the winnings amount if the betting amount is changed    
            calculate_odds($(e.target).closest('tr'));
        }).trigger('keyup');
    })

Upvotes: 0

Related Questions