0

I'm trying to add together values of form inputs when they're clicked to get a total price of an order.

Rather than trying to explain in words, there's a jsFiddle of what I'm trying to do.

What you see there works fine if you click on any of the buttons in the top row and move from one to another. It also works fine if, after you've clicked a button in the top row, you then click on the Add 1 Spot Colour button.

Where it goes wrong is if you then try and change the number of cards you want while the spot colour button is still checked.

You have to deselect buttons in both rows and then reselect to get to the right value.

The values should be (just top row / with bottom row added):

  • 495 / 770
  • 550 / 847
  • 605 / 935
  • 660 / 1012

    var spec_price = 0, env_price = 0, liner_price = 0, card_price = 0, colour_price = 0, corner_price = 0;
    var spec_desc = '', env_desc = '', liner_desc = '', card_desc = '', colour_desc = '', corner_desc = '';
    
    $('.order-option + label').click(function(e) {
    
        var radio = $(this).attr('for');
        radio = $('#' +radio );
    
        switch($(radio).attr('name')) {
            case 'specifications':
                spec_price = parseInt(radio.val());
                spec_desc = '<p>'+radio.data('title')+' </p>';
            break;
            case 'envelopes':
                env_price = parseInt(radio.val());
                env_desc= '<p>'+radio.data('title')+' </p>';
            break;
            case 'liners':
                liner_price = parseInt(radio.val());
                liner_desc ='<p>'+radio.data('title')+' </p>';
            break;
            case 'cards':
                card_price = parseInt(radio.val());
                card_desc = '<p>'+radio.data('title')+' </p>';
            break;
            case 'colours':
                colour_price = parseInt(radio.val());
                colour_desc = '<p>'+radio.data('title')+' </p>';
            break;
            case 'corners':
                corner_price = parseInt(radio.val());
                corner_desc = '<p>'+radio.data('title')+' </p>';
            break;
        }
    
        switch($(radio).attr('id')) {
            case 'specifications-radio1':
                $('#cards-radio').val('275');
            break;
            case 'specifications-radio2':
                $('#cards-radio').val('297');
            break;
            case 'specifications-radio3':
                $('#cards-radio').val('330');
            break;
            case 'specifications-radio4':
                $('#cards-radio').val('352');
            break;
        }
    
        var total_price = +spec_price + env_price + liner_price + card_price + colour_price + corner_price;
        var full_desc = spec_desc + env_desc + liner_desc + card_desc + colour_desc + corner_desc;
    
        if(radio.is(':checked')) {
            e.preventDefault();
            var subtract = parseInt(radio.val());
            var remove = radio.data('title');
            total_price = total_price - subtract;
            full_desc = full_desc.replace(remove,'');
            radio.removeAttr('checked');
            if($('.order-option:checked').length < 1) {
                spec_price = 0, env_price = 0, liner_price = 0, card_price = 0, total_price = 0, colour_price = 0, corner_price = 0;
                spec_desc = '', env_desc = '', liner_desc = '', card_desc = '', full_desc = '', colour_desc = '', corner_desc = '';
            }
        }
        // alert(total_price);
    
        $('.order-preview-total').html('$'+total_price+' (inc gst)');
        $('#order-preview-total').val('$'+total_price);
        $('.order-preview-content').html(full_desc);
        $('#order-preview-content').val(full_desc);
    
    });
    

Anyone see where I'm going wrong?

Tyssen
  • 1,569
  • 16
  • 35

1 Answers1

1

Phew, I had a heck of a time deciphering then simplifying your logic, then figuring out how to make radio buttons toggle, then getting the correct values which all stem from the problem you're asking about.

First I have to say, you should try using the jQuery selectors to avoid writing those long switch statements, they're hard to read and harder to maintain.

I changed the card and colour selectors into these and moved the card-radio value to a data attribute in the card radio elements (the only downside being that you need to check if the radio group isNaN because parsing or selecting an undefined variable throws an exception

    var spec_price = 0, env_price = 0, liner_price = 0, card_price = 0, colour_price = 0, corner_price = 0;
    var spec_desc = '', env_desc = '', liner_desc = '', card_desc = '', colour_desc = '', corner_desc = '';

    //card selected and a colour selected
    if($('#cards-radio').is(':checked') && !isNaN($("input:radio[name ='specifications']:checked").val())) {
        price = $("input:radio[name ='specifications']:checked").data('card');
        card_price = parseInt(price);
        card_desc = '<p>'+$('#cards-radio').data('title')+' </p>';
    }

    //colour selected
    if(!isNaN($("input:radio[name ='specifications']:checked").val())) {
        price = $("input:radio[name ='specifications']:checked").val();
        spec_price = parseInt(price);
        spec_desc = $("input:radio[name ='specifications']:checked").data('title');
    }

Now the reason your total was always showing odd numbers is that the label click event that triggered the html change would happen before the radio button's event that changes which one is selected (this took me the longest to figure out). Meaning that it would think the previous selected radio is currently selected and mess with your calculations

So instead of using the label click as an event I used Rob Ws solution to wrap the elements in a div and stop all propagation for any child elements and do it manually (like you were trying to do with the label click event).

Have a look here

Community
  • 1
  • 1
Ertyguy
  • 666
  • 4
  • 13