I have select boxes, and they have data attribute (data-price). I want to sum selected option "data-price" as "total" . but I have one problem. If I select only value="bmw" or I have not selected anything it gives me NaN$.
$('#mark, #series').on('change', function() {
var $selected = $('#mark, #series').children(":selected");
var sum = 0;
$selected.each(function() {
sum += $(this).data('price');
});
$('#total').html(sum + '$');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mark" name="mark">
<option value="">--</option>
<option value="bmw" data-price="200">bmw</option>
<option value="audi" data-price="400">audi</option>
</select>
<select id="series" name="series">
<option value="">--</option>
<option value="series-1" data-price="2000" >3 series</option>
<option value="series-1" data-price="3000" >5 series</option>
</select>
<div id="total"> </div>
This code will fix your problem:
$('#mark, #series').on('change', function() {
var $selected = $('#mark, #series').children(":selected");
var sum = 0;
$selected.each(function() {
var price = $(this).data('price');
if(price){
sum += $(this).data('price');
}
});
$('#total').html(sum + '$');
});
If you log the pricevariable into the forEach loop, you can see that it returns an integer and then an undefined. That should be fixed! :)
When you select only one option the selected option of the other does not have a 'data-price' attribute:
<option value="">--</option> <!-- data-price === "undefined" -->
You could set a default of "0" to the initially selected option:
<option value="" data-price="0">--</option>
Example:
$('#mark, #series').on('change', function() {
var $selected = $('#mark, #series').children(":selected");
var sum = 0;
$selected.each(function() {
sum += $(this).data('price');
});
$('#total').html(sum + '$');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mark" name="mark">
<option value="" data-price="0">--</option>
<option value="bmw" data-price="200">bmw</option>
<option value="audi" data-price="400">audi</option>
</select>
<select id="series" name="series">
<option value="" data-price="0">--</option>
<option value="series-1" data-price="2000">3 series</option>
<option value="series-1" data-price="3000">5 series</option>
</select>
<div id="total"> </div>
When you change one dropdown, let's say Make, $selected will include two elements:
<option value="bmw" data-price="200">bmw</option> and <option value="">--</option>
When you are now calculating the sum, you are adding two values 200 and and empty string as strings. You should try to parse all values to integers with parseInt("string", 10) (Note the 10 parameter which specifies the base to be used, it's good practice to be explicit, see parseInt documentation here).
Also, as other answers here state, you should always try to default to an integer value (in the case of the empty string). So your code could now be like this:
$('#mark, #series').on('change', function() {
var $selected = $('#mark, #series').children(":selected");
var sum = 0;
$selected.each(function() {
var optionPrice = parseInt($(this).data('price'), 10) || 0;
sum += optionPrice;
});
$('#total').html((sum) ? (sum + '$') : '');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mark" name="mark">
<option value="">--</option>
<option value="bmw" data-price="200">bmw</option>
<option value="audi" data-price="400">audi</option>
</select>
<select id="series" name="series">
<option value="">--</option>
<option value="series-1" data-price="2000" >3 series</option>
<option value="series-1" data-price="3000" >5 series</option>
</select>
<div id="total"> </div>
You must to parse your data which is seen as a string
$selected.each(function() {
var data = $(this).data('price');
if(data != undefined){
sum += parseFloat(data);
}
});
Please use a fallback value of 0 if the returned value is undefined.
using the line.
sum += $(this).data('price') || 0;
Note: You also need to run this validation function at the beginning to ensure, the result is calculated at the beginning before the change() event.
function validate(){
var $selected = $('#mark, #series').children(":selected");
var sum = 0;
$selected.each(function() {
sum += $(this).data('price') || 0;
});
$('#total').html(sum === 0 ? '' : sum + '$');
}
validate();
$('#mark, #series').on('change', function() {
validate();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mark" name="mark">
<option value="">--</option>
<option value="bmw" data-price="200">bmw</option>
<option value="audi" data-price="400">audi</option>
</select>
<select id="series" name="series">
<option value="">--</option>
<option value="series-1" data-price="2000" >3 series</option>
<option value="series-1" data-price="3000" >5 series</option>
</select>
<div id="total"> </div>
Related
if I have html like this.
<select multiple="" class="form-control" id="catalogsearch_specification2">
<option value="B-3-7">aaa</option>
<option value="B-3-7">bbb</option>
<option value="B-3-7">ccc</option>
<option value="B-3-7">ddd</option>
</select>
How to check if all value in select option are the same with javascript ?
Use Set object to check if each of the option elements has the same value property. If so - use Array#forEach to apply selected prop on each of them.
let parent = document.getElementById('catalogsearch_specification2'),
values = Array.from(parent.children).map(v => v.value);
[...new Set(values)].length == 1 ? Array.from(parent.children).forEach(v => v.selected = true) : null;
<select multiple="" class="form-control" id="catalogsearch_specification2">
<option value="B-3-7">aaa</option>
<option value="B-3-7">bbb</option>
<option value="B-3-7">ccc</option>
<option value="B-3-7">ddd</option>
</select>
You can do:
var isSame = true,
prev = '';
$('#catalogsearch_specification2 > option').each(function() {
if (prev && prev !== this.value) {
isSame = false;
return;
}
prev = this.value;
});
console.log(isSame);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select multiple="" class="form-control" id="catalogsearch_specification2">
<option value="B-3-7">aaa</option>
<option value="B-3-7">bbb</option>
<option value="B-3-7">ccc</option>
<option value="B-3-7">ddd</option>
</select>
This snippet will help you understand how to retrieve values from child nodes.
var obj = {};
var i = 0
$("#catalogsearch_specification2 option").each(function() {
//You can write you logic here.
if(!obj.hasOwnProperty(this.value)) {
obj[this.value] = {"value" : this.value, "duplicate" : 1};
} else {
obj[this.value].duplicate = (obj[this.value].duplicate) + 1;
}
});
console.log(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select multiple="" class="form-control" id="catalogsearch_specification2">
<option value="B-3-7">aaa</option>
<option value="B-3-7">bbb</option>
<option value="B-3-7">ccc</option>
<option value="B-3-7">ddd</option>
</select>
Here I'm taking all the child option element of id "catalogsearch_specification2".
There are a numerous way you can check. Here is a solution. Take the first option value and count total no of option with that value. And again count the total option value. If the count are same then all option values are same otherwise not.
$(function(){
var firstValue = $('#catalogsearch_specification2').find("option:first-child").val();
if($('#catalogsearch_specification2 option[value="'+firstValue+'"]').length == $('#catalogsearch_specification2 option').length){
console.log("All values are same");
}else{
console.log("All values are not same");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<select multiple="" class="form-control" id="catalogsearch_specification2">
<option value="B-3-7">aaa</option>
<option value="B-3-7">bbb</option>
<option value="B-3-7">ccc</option>
<option value="B-3-1">ddd</option>
</select>
I have 3 dropdown with values N/A, 3, 5, 6. On change event if I change value of first drop down the count should be 1 always but whenever I change again value is keep increasing. I know my counter is wrong but not getting idea to fix it.
$count = 0;
$maxcount = 3;
$arrOfLevel2ElementId.each(function () {
arrOfLevel2ElementId = $(this).attr('id');
$("#" + arrOfLevel2ElementId).on('change', function () {
level2ElementVal = $(this).val();
if (level2ElementVal == "N/A") {
if ($count > 0) {
$count--;
} else {
$count;
}
showOutput($sum);
return false;
} else {
if ($count <= $maxcount) {
$count++;
} else {
$count;
}
alert($count);
$sum = parseInt(level2ElementVal);
showOutput($sum);
}
This is the case because as soon as you change the dropdown, you call the function.
Here you state that if(level2ElementVal == "N/A") you decrease the count.
But in the else statement, meaning you select either 3, 5 or 6, you check if the count isn't at the maxcount. Which is not the case if $count = 1. Then you increase it. Which explains that it increases when you change the value.
I'm not sure why you have a $maxcount, but if you were to change it to 1, my assumption is that your count should not exceed 1.
EDIT:
If what I've understand correctly from your comments you want to device the three numbers, unless its on N/A.
Try this fiddle:
https://jsfiddle.net/7b21b699/1/
It sets the value field when the last field is changed and checks the values at that point. Then sums them up when needed and divides them correctly.
$("#box3").on('change', function(){
var val1 = $("#box1").val();
var val2 = $("#box2").val();
var val3 = $("#box3").val();
var sum = 0;
var count = 0;
if(val1 != "N/A"){
sum += parseInt(val1);
count++;
}
if(val2 != "N/A"){
sum += parseInt(val2);
count++;
}
if(val3 != "N/A"){
sum += parseInt(val3);
count++;
}
var result = sum / count;
$("#value").text(result);
});
<select class="form-control" id="box1" name="a">
<option value="" selected="selected">Select a value</option>
<option value="N/A">N/A</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="7">7</option>
<option value="10">10</option>
</select>
<select class="form-control" id="box2" name="a">
<option value="" selected="selected">Select a value</option>
<option value="N/A">N/A</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="7">7</option>
<option value="10">10</option>
</select>
<select class="form-control" id="box3" name="a">
<option value="" selected="selected">Select a value</option>
<option value="N/A">N/A</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="7">7</option>
<option value="10">10</option>
</select>
<div id ="value">value comes here</div>
How to make that the all selected options, not the values, but the actual text, would be displayed somewhere?
Html:
<h1>Made your PC:</h1>
<div>
<label>Processeor: </label><select id="processor" name="processor">
<option class="label" value>Select Processor</option>
<!-- Home Ware -->
<option value="P1">Processor 1</option>
<option value="P2">Processor 2</option>
<option value="P3">Processor 3</option>
<option value="P4">Processor 4</option>
</select>
</div>
<p><strong>Only compatible components will show.</strong></p>
<div>
<label>Select motherboard: </label><select id="motherboard" name="motherboard" class="subcat" disabled="disabled">
<option class="label" value>Select Motherboard</option>
<!-- Home Ware -->
<option rel="P1 P2" value="AS1">ASUS RAMPAGE V EXTREME</option>
<option rel="P2 P3" value="AS2">ASUS ATX DDR3 2600 LGA</option>
<option rel="P1 P3 P4" value="GB1">Gigabyte AM3+</option>
<option rel="P2 P4" value="MSI1">MSI ATX DDR3 2600 LGA 1150</option>
</select>
</div>
<div>
<label>Select RAM: </label> <select disabled="disabled" class="subcat" id="RAM" name="RAM">
<option class="label" value>RAM Memory</option>
<option rel="AS1 AS2 GB1" value="KI1">Kingston Value RAM</option>
<option rel="AS1 AS2 MSI1" value="P5KPL">P5KPL-AM SE</option>
<option rel="MSI1 GB1" value="960GM">960GM-VGS3 FX </option>
</select>
</div>
<div>
<label>Select Video Board: </label> <select disabled="disabled" class="subcat" id="video-card" name="video-card">
<option class="label" value>Video Card</option>
<option rel="MSI1 AS2" value="EVGA8400">EVGA GeForce 8400 GS</option>
<option rel="AS1" value="XFXAMD">XFX AMD Radeon HD 5450</option>
<option rel="MSI1 GB1" value="GTX750Ti">EVGA GeForce GTX 750Ti SC</option>
</select>
</div>
Javascript:
$(function(){
var $supcat = $("#processor"),
$cat = $("#motherboard"),
$subcat = $(".subcat");
$supcat.on("change",function(){
var _rel = $(this).val();
$cat.find("option").attr("style","");
$cat.val("");
if(!_rel) return $cat.prop("disabled",true);
$cat.find("[rel~='"+_rel+"']").show();
$cat.prop("disabled",false);
});
$cat.on("change",function(){
var _rel = $(this).val();
$subcat.find("option").attr("style","");
$subcat.val("");
if(!_rel) return $subcat.prop("disabled",true);
$subcat.find("[rel~='"+_rel+"']").show();
$subcat.prop("disabled",false);
});
});
I tried this one code that was posted earlier, but it only display one selection, right after picking, is there any way it could display all the selections and with my random text, like "Your selections"?:
<script>
function myNewFunction(sel)
{
alert(sel.options[sel.selectedIndex].text);
}
</script>
<select id="box1" onChange="myNewFunction(this);" >
<option value="98">dog</option>
<option value="7122">cat</option>
<option value="142">bird</option>
</select>
This should give the actual label text, not the value, for a given select-element.
$(selector).find(":checked").html()
So if you want to show all of them, you could do something like this:
$("#video-card").on("change", function () {
var choices = [];
$("select").each(function() {
choices.push($(this).find(":checked").html());
});
alert("You selected: " + choices.join(', '));
})
And here's a codepen for demo purposes
http://codepen.io/anon/pen/XbjKYQ
function myNewFunction(sel) {
alert($(sel).val());
}
This should actually be working.
If that doesn't work, try to place a window.setTimeout(function() { ... }, 10); around your alert. It's possible that the browser calls the myNewFunction() method before it updates the selection value when the user clicks on one option.
EDIT: If you want the text instead of the value, use
alert($(sel).find("option:selected").text());
You need to loop through each of the selects, not just the first one:
function updateOutput() {
var selects = document.getElementsByTagName('SELECT');
var output = document.getElementById('output');
var arr = [];
for (i=0; i < selects.length; i++) {
arr.push(selects[i].options[selects[i].selectedIndex].text);
}
output.innerHTML = arr.join('; ');
return arr;
}
In this case, I push all the values into an array and then join the array values at the end to create the final string.
I updated a codepen provided earlier: http://codepen.io/anon/pen/WvGxgz
I need some help in javascript PHP to solve my problem. Please look at my code below:
<?PHP
$arrear_per_month = 15000;
?>
<select name="cur_month" id="id_cur_month" multiple="multiple">
<option value="">Month</option>
<option value="jan">January</option>
<option value="feb">February</option>
<option value="mar">March</option>
<option value="apr">April</option>
<option value="may">May</option>
<option value="jun">June</option>
<option value="jul">July</option>
<option value="aug">August</option>
<option value="sep">September</option>
<option value="oct">october</option>
<option value="nov">November</option>
<option value="dec">december</option>
</select>
Your current arrear: <input id="id_cur_arrear" type="text" name="arrear" value="" readonly="readonly" />
What i want to do is:
count how many option is being selected
Multiply the number of selected option with $arrear_per_month
Display the result in field input as shown above (in arrear)
Example:
Let say that February, march and april are selected.
So the number of selected option is 3.
And then 3 * $arrear_per_month = 45000.
So i need to display 45000 as value in arrear
[edited] i need to display it without any click (something like onChange)
I think that is what i need, please give me some help.
Thank you in advance
var numbersChecked = $('#id_cur_month').find(":selected").length;
$("#id_cur_arrear").val(numbersChecked * <?= $arrear_per_mnth; ?>);
You can easily do this via jQuery (with less code). However, if you are specifically looking for JavaScript code, you can try this -
<script type="text/javascript">
function update(){
var apm = Number("<?php echo $arrear_per_month;?>");
var cm = document.getElementById("id_cur_month").selectedOptions.length;
var sel_cnt = (apm * cm);
document.getElementById("id_cur_arrear").value = sel_cnt;
}
</script>
Add onchange event to your select box -
<select name="cur_month" id="id_cur_month" onchange="update()" multiple="multiple">
This will work either you select the options through click or keyboard arrow keys.
In javascript this is how you do it
var sel = document.getElementById('id_cur_month');
alert(sel.selectedOptions.length);
Code above should alert the number of selected options.
However you do need to do some additional coding as you cannot pass a javascript variable to the php code.
You can instead declare that php variable as a javascript variable.
<script>
var arrear_per_month = <?php echo $arrear_per_month ?>;
var sel = document.getElementById('id_cur_month');
var total = arrear_permonth * sel.selectedOptions.length;
alert(total);
</script>
As suggested by Andrex, i've tried to modify the script like this, but it doesn't work.
<?PHP
$arrear_per_month = 15000;
?>
<script type="text/javascript" language="javascript">
var sel = document.getElementById('id_cur_month');
alert(sel.selectedOptions.length);
var arrear_per_month = <?php echo $arrear_per_month ?>;
var sel = document.getElementById('id_cur_month');
var total = arrear_permonth * sel.selectedOptions.length;
alert(total);
document.chk_arrear.arrear.value = total;
</script>
<form name="chk_arrear">
<select name="cur_month" id="id_cur_month" multiple="multiple">
<option value="">Month</option>
<option value="jan">January</option>
<option value="feb">February</option>
<option value="mar">March</option>
<option value="apr">April</option>
<option value="may">May</option>
<option value="jun">June</option>
<option value="jul">July</option>
<option value="aug">August</option>
<option value="sep">September</option>
<option value="oct">october</option>
<option value="nov">November</option>
<option value="dec">december</option>
</select>
Your current arrear: <input type="text" name="arrear" value="" readonly="readonly" />
</form>
the Alert doesnt work and also the input text. Can you please correct this script
JQuery
$("#id_cur_month").click(function () {
var len = 0;
$("#id_cur_month").children(":selected").each(function () {
len += ($(this).val() ? 1 : 0);
});
var res = len * (parseInt($("#id_cur_arrear").val() || 0));
$("#id_cur_arrear_res").val(res);
});
DEMO
Javascript
var select = document.getElementById("id_cur_month");
console.log(select);
select.onclick = function () {
var opts = select.options;
var len = 0;
for (i = 0; i < opts.length; i++) {
if (opts[i].selected && opts[i].value) len++;
}
document.getElementById("id_cur_arrear_res").value = len * (parseInt(document.getElementById("id_cur_arrear").value || 0))
};
Use <?= $arrear_per_mnth; ?> instance of (parseInt(document.getElementById("id_cur_arrear").value || 0))
DEMO
Thank you to all of you. it's running.
<?PHP
$arrear_per_month = 15000;
?>
<script type="text/javascript" language="javascript">
function update(){
var apm = Number("<?php echo $arrear_per_month;?>");
var cm = document.getElementById("id_cur_month").selectedOptions.length;
var sel_cnt = (apm * cm);
document.getElementById("id_cur_arrear").value = sel_cnt;
}
</script>
<form name="chk_arrear">
<select name="cur_month" id="id_cur_month" multiple="multiple" onchange="update()">
<option value="">Month</option>
<option value="jan">January</option>
<option value="feb">February</option>
<option value="mar">March</option>
<option value="apr">April</option>
<option value="may">May</option>
<option value="jun">June</option>
<option value="jul">July</option>
<option value="aug">August</option>
<option value="sep">September</option>
<option value="oct">october</option>
<option value="nov">November</option>
<option value="dec">december</option>
</select>
Your current arrear: <input type="text" id="id_cur_arrear" name="arrear" readonly="readonly" />
</form>
I've three select-box here to choose Format, Amount & Shipping type. After selection, it will calculate price automatically.
here, how those select-box look like:
<p>Format: <select class="calculate" name="format">
<option value="0">Please Select</option>
<option value="0">Format 1</option>
<option value="0">Format 2</option>
</select></p>
<p>Amount: <select class="calculate" name="amount">
<option value="0">Select amount</option>
<option value="247">250pcs</option>
<option value="279">1,000pcs</option>
<option value="389">2,500pcs</option>
</select></p>
<p>Shipping type: <select id="surcharge" name="shipping">
<option value="0">Select Shipping</option>
<option value="10%">Standard</option>
<option value="15%">Express</option>
</select></p>
currently, the Amount for the both Format (Format 1/Format 2) are same.
what i'm trying to do is like: for the Format 1, the current Amount will remain same, but if user select Format 2 then the Amount will something like this:
<option value="0">Select amount</option>
<option value="300">250pcs</option>
<option value="350">1,000pcs</option>
<option value="400">2,500pcs</option>
where the value is different! how can i achive this?
here goes the JSfiddle
Thanks in advance for any help!
You should first set the new values in an array. So you can loop through them while changing the first select.
Then you can easily get the options from the 2nd select, and update them with the correct new values:
$(".calculate, #surcharge").on("change", function(){
if($(this).val() == 1)
{
var amountValues = new Array(0,250,400,500);
$("#menge option").each(function(key,value)
{
$(this).val(amountValues[key]);
});
} else if($(this).val() == 2)
{
var amount Values = new Array();
// .....
}
});
http://jsfiddle.net/7Bfk5/15/
You can do this by checking the text() in the options you are selecting
if ($('#sel option:selected').text() === 'Format 2') {
$('#amt option').each(function () {
alert($(this).text());
if ($(this).text() == "250pcs") $(this).val("300");
else if ($(this).text() == "1,000pcs") $(this).val("350");
else $(this).val("400");
});
}
working fiddle
You can create a function that does values/options replacement and call it on your select changes.
I did an example for you but used static html options to replace old ones, this might not be the best way but tried to keep it as simple as possible.
HTML
<p>Format: <select class="calculate format" name="format">
<option value="0">Please Select</option>
<option value="1">Format 1</option>
<option value="2">Format 2</option>
</select></p>
<p>Amount: <select class="calculate amount" name="menge">
<option value="0">Select Menge</option>
<option value="247">250pcs</option>
<option value="279">1,000pcs</option>
<option value="389">2,500pcs</option>
</select></p>
<p>Shipping type: <select id="surcharge" name="shipping">
<option value="0">Select Shipping</option>
<option value="10%">Standard</option>
<option value="15%">Express</option>
</select></p>
<p>Price: <span id="total">0 €</span></p>
Javascript
var updateValues = function (){
if($('.format').val() == 1) {
html = '<option value="300">300pcs</option>';
html += '<option value="400">400pcs</option>';
html += '<option value="500">500pcs</option>';
$('.amount').html(html);
} else if( $('.format').val() == 2) {
html = '<option value="600">600pcs</option>';
html += '<option value="900">900pcs</option>';
html += '<option value="1200">1200pcs</option>';
$('.amount').html(html);
}
};
$('.format').change(function(){updateValues()});
$(".calculate, #surcharge").on("change", function(){
var total = 0;
$('.calculate').each(function() {
if($(this).val() != 0) {
total += parseFloat($(this).val());
}
});
if($('#surcharge').val() != 0) {
total = total * ((100 + parseFloat($('#surcharge').val())) / 100);
}
$('#total').text(total.toFixed(2) + ' €');
});
Fiddle link
http://jsfiddle.net/7Bfk5/23/