I currently have an array that is populated by changing the value/option of many select fields. E.g. If two select fields are in the dom and the options selected are 2 & 3 then the array would look like this - Array [ "2", "3" ]
Each select has a data attribute data-ticketprice which I would like to bind to each of the option values. So I can get the sum of both of the numbers e.g.
data attribute = 100
Select option value = 5
Sum = 100 x 5;
HTML -
<select class="ticket-qty" data-ticketprice="280.88" name="34">
<option value="0">0 Tickets</option>
<option value="1">1 Ticket</option>
<option value="2">2 Tickets</option>
<option value="3">3 Tickets</option>
<option value="4">4 Tickets</option>
<option value="5">5 Tickets</option>
</select>
<select class="ticket-qty" data-ticketprice="390" name="39">
<option value="0">0 Tickets</option>
<option value="1">1 Ticket</option>
<option value="2">2 Tickets</option>
<option value="3">3 Tickets</option>
<option value="4">4 Tickets</option>
<option value="5">5 Tickets</option>
</select>
Current jQuery -
//When select is changed update value to array
$('select.ticket-qty').on('change', function (e) {
//Map the values for the array
var arr = $('select.ticket-qty').map(function(){
return this.value
}).get()
//This sums the all the select options (not what I want)
var total = 0;
for (var i = 0; i < arr.length; i++) {
total += arr[i] << 0;
}
console.log(total);
});
-
Please consider using an MVC framework for this type of project. Vue JS is easy to get started with if you haven't done so before.Adam Leggett– Adam Leggett2018年02月21日 16:29:32 +00:00Commented Feb 21, 2018 at 16:29
-
2You don't need a big framework for every little problem.user9366559– user93665592018年02月21日 16:34:13 +00:00Commented Feb 21, 2018 at 16:34
-
If this is a school project, probably not. If he is really selling tickets to something, this will outgrow jQuery within a day.Adam Leggett– Adam Leggett2018年02月21日 16:44:17 +00:00Commented Feb 21, 2018 at 16:44
-
@AdamLeggett I'm already using an MVC framework such as Laravel. I don't like VueJS because you end up with around 100 libraries. It's never just vue, its axios, vue routing etc.. This is a really basic application with almost no JS requirements.archvist– archvist2018年02月21日 17:16:42 +00:00Commented Feb 21, 2018 at 17:16
4 Answers 4
You need to fill the array you build with map() with the selected quantity multiplied by the cost per item, which you can retrieve from the data attribute. From there you can use reduce() to sum up all values in the array. Something like this:
$('select.ticket-qty').on('change', function(e) {
var arr = $('select.ticket-qty').map(function() {
var cost = $(this).data('ticketprice');
var qty = $(this).val();
return cost * qty;
}).get();
var total = arr.reduce((a, b) => a + b, 0);
console.log(total);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="ticket-qty" data-ticketprice="280.88" name="34">
<option value="0">0 Tickets</option>
<option value="1">1 Ticket</option>
<option value="2">2 Tickets</option>
<option value="3">3 Tickets</option>
<option value="4">4 Tickets</option>
<option value="5">5 Tickets</option>
</select>
<select class="ticket-qty" data-ticketprice="390" name="39">
<option value="0">0 Tickets</option>
<option value="1">1 Ticket</option>
<option value="2">2 Tickets</option>
<option value="3">3 Tickets</option>
<option value="4">4 Tickets</option>
<option value="5">5 Tickets</option>
</select>
You should note that this can all be done in a single loop, however I am assuming you're building the array of individual totals for use elsewhere in your UI.
9 Comments
So how far I understand is, you want to multiply the selected value with the given data attribute on Select?
Here is sample code for getting Array of All selected values. And how to calculate the value you posted.
var array = [];
var i =0;
$('select.ticket-qty').on('change', function (e) {
// Get value of all selects in array.
$('select.ticket-qty').each(function(){
array[i] = $(this).val();
i++;
});
//calculate Sum ?
var data_attribute = $(this).data("ticketprice");
SelectedOptionValue = = $(this).val();
Sum = parseFloat(data_attribute)* parseInt(SelectedOptionValue);
});
Comments
Vanilla JS
const SELECTS = document.querySelectorAll('select.ticket-qty')
const LOG_SUM = e => {
const ticketPrice = e.target.getAttribute('data-ticketPrice')
const multiplier = e.target.value
const SUM = (+ticketPrice * +multiplier)
console.log(SUM)
}
SELECTS.forEach(select => {
select.addEventListener('change', e => {
LOG_SUM(e)
})
})
jQuery
$('select.ticket-qty').on('change', e => {
const ticketPrice = $(e.target).attr('data-ticketPrice')
const multiplier = e.target.value
const SUM = (+ticketPrice * +multiplier)
console.log(SUM)
});
Notice how i prepend the + operator to the ticketPrice & multiplier constants... this is because attr && value are returning Strings and the + operator converts numbers of type String into numbers of type Number
Comments
You can use some jQuery plugins to populate and reduce the select boxes.
(function($) {
$.reduce = function(arr, fn, initial) {
initial = typeof initial === 'undefined' ? 0 : initial;
$.each(arr, function(i, v) {
initial = fn(initial, v, i);
});
return initial;
};
$.fn.reduce = function(fn, initial) {
return $.reduce(this, fn, initial);
};
$.fn.populateCombo = function(opts) {
let data = opts.data || Array.apply(null, {length: opts.range || 0}).map(Number.call, Number);
return this.append(data.map(x => $('<option>')
.text(opts.textFn ? opts.textFn(x) : x)
.val(opts.valFn ? opts.valFn(x) : x)));
};
})(jQuery);
$('.ticket-qty').each((i, combo) => $(combo).populateCombo({
range : 6, textFn: v => v + ' Tickets'
}));
$('select.ticket-qty').on('change', function(e) {
var total = $('select.ticket-qty').reduce(function(result, item) {
return result + $(item).data('ticketprice') * $(item).val();
}, 0);
console.log('$' + total.toFixed(2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="ticket-qty" data-ticketprice="280.88" name="34"></select>
<select class="ticket-qty" data-ticketprice="390" name="39"></select>