1

Could anybody help me with this problem? I have an input price value that changes when you select different checkboxes, but it doesn't add up. I don't really know how to fix it that if you select something, it adds to the total price, and when you select another one it adds again.

The foreach is to get all the exa_names from the Extra table with the checkbox and the price from that item.

Javascript

$(document).ready(function(){
    $(".option").change(function(){
        var id = $(this).attr('id');
        console.log(id);

        var id_number = id.split("_")[1];
        console.log(id_number);

        var hidden_input = $(".option_price" + id_number).val();
        console.log(hidden_input);
    })
});

HTML

<label>Options</label><br>
@foreach($options as $option)   
    <div>                       
        <input type="checkbox" class="option" id="option_{{ $option->exa_id }}" name="option_{{ $option->exa_id }}" value="{{ $option->exa_id }}" {{ isset($cache) ? (isset($cache['option_' . $option->exa_id]) ? 'checked' : '')  : (old() ? (old('option_' . $option->exa_id) ? 'checked' : '') : ($inschrijving ? (in_array($registration->exa_id, $registration_options) ? 'checked' : '') : '')) }} >
        <input type="hidden" value="{{ $option->exa_price}}" class="option_price_{{ $option->exa_id }}">
        <label>{{ $option->exa_name }}</label>
        <label>  €{{ $option->exa_price }} </label> 
    </div>
@endforeach 

Html input totalprice(where it has to show the total price)

<div class="row">
            <div class="col-xs-12">
                <div class="form-group">
                    <label>Total</label>
                    <input type="text" name="totalprice" id="totalprice" class="form-control" data-blocked="<>{}" value="0" required>
                </div>
            </div>
        </div>

RegistrationController

$options_ids_array = array();
$options = Extra::all();
foreach($options as $option){
    $option->exa_id = "option_" . $option->exa_id;
    $input_option = $option->exa_id;
    if(!is_null($input_option)){
        $options_ids_array[] = $input_option;
    }
}

$registration->dev_option_id = implode(",", $options_ids_array);
$registration->save();
Sander105
  • 29
  • 2
  • 9

2 Answers2

0

I think it's better to store the price of your item in a javascript variable (because it prevent to change the value of hidden input and have easy access on js side) and access to your price through your checkbox value (because it is exactly the id you tried to get with id value by split it with _ character). For add price from checked checkboxes (if they are not too much checkboxes), create a check function to detect which of them are checked and then select the price of each and add them to each other, then put it to your price place. Something like:

var options = $(".option");
var options_price = ['your', 'price', 'values', 'according', 'to', 'options', 'id'];
function optionsPrice() {
    var total_price = 0;
    options.each(function () {
        var option = $(this);
        if (option.is(':checked') && option.val() != '' && $.inArray(option.val(), Object.keys(options_price))) {
                total_price += options_price[option.val()];
        }
    });

    return total_price;
}

Call optionsPrice function on any checkbox change.

OR if you have a lot of checkeboxes on your page,

you can have a global total price variable and add or sub price from it on any checkbox change. Something like:

var total_price = 0;
        var options = $(".option");
        var options_price = ['your', 'price', 'values', 'according', 'to', 'options', 'id'];

var option, val;
options.on('change', function() {
    option = $(this);
    val = option.val();
    if(val && val != '' && $.inArray(val, Object.keys(options_price)) !== -1) {
        if(option.is(':checked')) {
            total_price += options_price[option.val()];
        } else {
            if(total_price > 0) {
                total_price -= options_price[option.val()];
            } else {
                total_price = 0;
            }
        }
    }
});

I hope it helps :)

MMDM
  • 465
  • 3
  • 11
0

You've got the tricky part - uniquely identifying your inputs in JS - already done. All that is left is to sum them up!

The simplest option is to iterate over all your inputs whenever one of them changes, and recalculate the price from scratch.

I'm not 100% sure how your inputs and prices and extra costs work, but let's make it simple. Here's some example HTML in the format your Blade template could generate:

<div>                       
    <input type="checkbox" class="option" id="option_1" name="option_1" value="1" checked>
    <input type="hidden" value="1" class="option_price_1">
    <label>Orange</label>
    <label>1</label> 
</div>
<div>                       
    <input type="checkbox" class="option" id="option_2" name="option_2" value="2">
    <input type="hidden" value="2" class="option_price_2">
    <label>Apple</label>
    <label>2</label> 
</div>
<div>                       
    <input type="checkbox" class="option" id="option_3" name="option_3" value="3" checked>
    <input type="hidden" value="3" class="option_price_3">
    <label>Pear</label>
    <label>3</label> 
</div>

<!-- I've added a total area to display the total result -->
<div id="total"></div>

Now taking your code, and using jQuery's .each() to iterate over all inputs on the page:

$('.option').change(function() {

    // This is what we'll use to sum the prices
    var total = 0;

    // Use .each() to iterate over all .option inputs
    $('.option').each(function(index) {

        // Inside .each, $(this) represents the current element
        var id = $(this).attr('id');
        var id_number = id.split("_")[1];

        // Note your code was missing the _ after price here
        var hidden_input = $(".option_price_" + id_number).val();

        // Is this option checked?  If yes, we want to add its value to 
        // the total
        if ($(this).prop('checked')) {
            // .val() returns a string, prefixing hidden_input with '+' is 
            // a trick to cast it as a number
            total += +hidden_input;
        }

        console.log(id, id_number, hidden_input, total);
    });

    // We've processed all inputs and have a total, update our page with
    // the result
    $('#total').html(total);
});

Done!

The above works fine, but here are some suggestions for minor improvements:

1) Use for on your labels, so that clicking on the text will also toggle the checkbox.

2) It is good practice to cache your jQuery selectors, otherwise jQuery has to parse the DOM each time to look for them. That's trivially unimportant in this example, but it is good practice to get into so you won't get bitten by problems as your pages get more complex.

3) It is good practice to separate your JS code into smaller chunks, so eg have a function that sums up the price, and a separate event handler which simply calls that when an option is changed.

Putting all that together, here's updated code:

<!-- Just one for example -->
<div>
    <input type="checkbox" class="option" id="option_1" name="option_1" value="1" checked>
    <input type="hidden" value="1" class="option_price_1">
    <label for="option_1">Orange</label>
    <label>1</label> 
</div>

And now the JS:

// Cache your selectors
var $options = $('.option'),
    $total = $('#total');

// Event handler, with callable function
$options.on('change', sumInputs);

function sumInputs() {
    var id, id_number, hidden_input, price = 0;

    $options.each(function(index) {
        id = $(this).attr('id');
        id_number = id.split("_")[1];
        hidden_input = $(".option_price_" + id_number).val();
        if ($(this).prop('checked')) {
            price += +hidden_input;
        }
        console.log(id, id_number, hidden_input, price);
    });
    $total.html(price);
}
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
  • @sander105 Does this answer help? – Don't Panic Oct 24 '19 at 13:16
  • Sorry for the late reply! I tried it and i got an error: Undefined variable: options – Sander105 Oct 28 '19 at 10:52
  • @Sander105 Looks like you might have missed a `$` somewhere? The code I show does not include a variable called `options` ... If you're using my suggested improved code, I define a variable called `$options`, did you maybe use it without the `$` somewhere? The error should give you a line number, check that out. – Don't Panic Oct 28 '19 at 13:46