I have the following structure in my page:
Fieldset:
Size
Options
That shows Was, Now and You Save Price
Then I have JQuery in place that convert the above into float and shows the Save Price in percentage. It all works as intended until I change for instance the Size and the Options. To overcome this I've tried to use .change(function(). However when I change the value from the selected menu and it returns NaN.
Can you please help?
Here is my JS Code:
$(".product-options").change(function() {
var oldPrice = parseFloat(jQuery('.old-price-item .price .price').text().replace('£', ''), 10);
var savePrice = parseFloat(jQuery('.special-price .price .price').text().replace('£', ''), 10);
var youSave = savePrice / (oldPrice / 100);
var n = parseFloat(youSave).toFixed(2);
$('div.ratio-div').html('<p>' + n + ' % OFF</p>');
$('div.save-price-div').html('<p>£' + savePrice + ' OFF</p>');
}).trigger('change');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="options-container-big">
<fieldset class="product-options" id="product-options-wrapper">
<dl class="attribute-list">
<dt id="attribute122_row" style="position: relative;"><label class=
"required product-options__label" for=
"attribute122">Size</label></dt>
<dd>
<div class="input-select input-select--alternate">
<select class="validate-select super-attribute-select validation-passed" data-attribute="item-size" data-choosetxt="Size" data-role="none" id="attribute122" name="super_attribute[122]">
<option value="">
Size
</option>
<option value="235">
Single
</option>
<option value="238">
Double
</option>
<option value="239">
King
</option>
</select>
</div><span class="item-size-warning" id="attribute122-warning" style="display:none;"></span>
</dd>
<dt id="attribute129_row" style="position: relative;"><label class=
"required product-options__label" for=
"attribute129">Storage</label></dt>
<dd class="last">
<div class="input-select input-select--alternate">
<select class="validate-select super-attribute-select" data-attribute="storage" data-choosetxt="Storage" data-role="none" id="attribute129" name="super_attribute[129]">
<option value="">
Storage
</option>
<option value="310">
No Drawers
</option>
<option value="312">
2 Drawers
</option>
<option value="313">
4 Drawers
</option>
</select>
</div>
</dd>
</dl>
</fieldset>
<div class="product-options-bottom">
<div class="add-to-cart">
<div class="price-box">
<div class="old-price">
<ul id="old-price-15511">
<li class="old-price-item">
<div class="line-through">
</div><span class="price-label">Was</span>
<span class="price"><span class=
"currency">£</span></span>
</li>
<li class="old-price-item">
<div class="line-through">
</div><span class="price-label">Was</span>
<span class="price"><span class=
"currency">£</span></span>
</li>
</ul>
</div>
<p class="special-price"><span class="price-label">You
Save</span> <span class="currency-special-price">£</span>
<span class="price" id="price-excluding-tax-15511"></span>
</p><span class="regular-price" itemprop="offers" itemscope itemtype="http://schema.org/Offer"></span>
<meta content="GBP">
</div>
<div class="product-stock-status">
<div class="product-stock-status__wrapper">
<span class="title">In Stock</span>
</div>
</div>
</div>
</div>
</div>
Please note The fieldset provide different price for Size only or Size + different option.
Based on the HTML provided, it looks like you have incorrectly doubled up the class selector called "price" in the jQuery selectors.
Try these instead:
var oldPrice = parseFloat(jQuery('.old-price-item .price .currency').last().text().replace('£', ''), 10);
var savePrice = parseFloat(jQuery('.special-price .price').text().replace('£', ''), 10);
It is difficult to know for certain because the html is missing the numbers. I guess you either edited the price out, or it is generated dynamically by some other script not shown.
Here is a cut down version of the html to illustrate what your selectors are choosing:
http://jsbin.com/heduju/5/edit?html,js,console,output
Update
Just noticed that there are multiple matches to the first selector so I added .last() to the selector as well (assuming that the last was price is used for the calculation).
http://jsbin.com/jegeqe/17/edit?html,js,console,output
jQuery('.old-price-item .price .price').text() returns "" (empty string), so parseFloat() is NaN.
Related
I have some problem with displaying a select option after i add a new one in dynamic select box. So the one i have here display the result of first row select box. While i change the qty and click order it will change the price result but after changing the option it will display result under the first one. For the result i need to change this code so when i click order button the result will display like this: if i have 3 rows of select boxes, the result will display each of it into 3 rows. Any help would be appreciated!
example
This is the example when i click order the first select box row, it display name=price*qty (this is the result i need for each select box)
This is the example when i change the first select box row option, it display a new result under the first result instead changing it
code
$(document).ready(function () {
var selectMenu = {};
$('.order').click(function () {
var itemName = $("#type_select option:selected").attr('label');
var price = Number($("#type_select option:selected").data('price'));
var count = Number($("#num").val());
var total = price * count;
selectMenu[itemName] = total
var result = JSON.stringify(selectMenu).replace(/,/g, '<br>').replace(/\{|\}|"/g, "")
//the result in the first row change price based on qty, but when option is changed the result display under the first one
$('.result').html(result);
Here is the link for full code: jsbin
I've done a bit of refactoring, because you were using same ids on multiple elements, so I changed them to classes. Full code: jsbin
$(document).ready(function () {
var selectMenu = {};
$('.order').click(function () {
selectMenu = {};
$('.menu-position').each(function (i) {
var category = $(this).find('.category-select').val()
var $selectedItem = $(this).find('.type-select :selected')
var name = $selectedItem.attr('label')
var price = $selectedItem.data('price')
var qty = +$(this).find('.qty').val()
var total = price * qty
selectMenu[name] = total
})
var result = JSON.stringify(selectMenu).replace(/,/g, '<br>').replace(/\{|\}|"/g, "")
$('.result').html(result);
});
});
Your order function had two errors:
You were processing only the first menu row.
You you were using the same "selectMenu" object instead of creating a new one.
You can use each loop because you might be having mutliple select-boxes for each row . Then , get price & quantity from each row and add save same inside JSON Object . Now, to show them use .each loop again and append new rows inside some divs.
I have created JSON structure like this :
{
//here 0 is first row
"0": {
"total": 0, //this is total for first row
"itemname": "Fried Rice" //this is price for first row
}
//same for other rows as well only changing 1 ,2..etc
}
Demo Code :
$(document).ready(function() {
$('.order').click(function() {
var selectMenu = {};
//loop through type select
$("select.type").each(function(i) {
selectMenu[i] = {} //create array
//get label value
var text = $(this).find("option:selected").attr('label');
//get price
var price = Number($(this).find("option:selected").data('price'));
//get qty
var qty = Number($(this).closest(".row").find(".qty").val())
//push same in array
selectMenu[i] = {
"total": price * qty,
"itemname": text
}
})
$('.result tbody').html(""); //clear tbody
$.each(selectMenu, function(index, data) {
//add tr inside tbody
$('.result tbody').append("<tr class='orders'><td>" + data.itemname + '</td><td>' + data.total + "</td></tr>");
})
});
});
.orders {
color: green;
font-weight: bold;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="container">
<div class="container-fluid text-center">
<h2 style="font-size:70px; font-family:Lucida Console;">MENU</h2>
<br>
<div class="row">
<div class="col-md-3">
<button type="button" class="btn btn-primary btn-lg addRow">Add</button>
</div>
<div class="col-md-3">
<!--added class cat -->
<select class="form-select form-select-lg mb-3 cat" id="category_select" onChange='handleChange(this)'>
<option value="Food">Food</option>
<option value="Drink">Drink</option>
</select>
</div>
<br>
<div class="col-md-3">
<!--added class type -->
<select class="form-select form-select-lg mb-3 type" id="type_select">
<option value="1" label="Fried Rice" data-price="10000"></option>
<option value="2" label="Fried Noodle" data-price="9000"></option>
<option value="3" label="Pancake" data-price="8500"></option>
<option value="4" label="French Fries" data-price="7500"></option>
</select>
</div>
<div class="col-md-3">
<input type="number" class="form-control form-control-lg mb-3 qty" id="num" placeholder="Qty" min="0">
</div>
</div>
<div class="row">
<div class="col-md-3">
<button type="button" class="btn btn-danger btn-lg ">Delete</button>
</div>
<div class="col-md-3">
<select class="form-select form-select-lg mb-3 cat" onChange='handleChange(this)'>
<option value="Food">Food</option>
<option value="Drink">Drink</option>
</select>
</div>
<br>
<div class="col-md-3">
<select class="form-select form-select-lg mb-3 type">
<option value="1" label="Fried Rice" data-price="10000"></option>
<option value="2" label="Fried Noodle" data-price="9000"></option>
<option value="3" label="Pancake" data-price="8500"></option>
<option value="4" label="French Fries" data-price="7500"></option>
</select>
</div>
<div class="col-md-3">
<input type="number" class="form-control form-control-lg mb-3 qty" id="num" placeholder="Qty" min="0">
</div>
</div>
</div>
</div>
<br>
<button type="button" class="btn btn-secondary order">Order</button>
<br>
<br>
<div class="result text-center">
<table class="table table-bordered">
<thead>
<tr>
<th>Item name </th>
<th>Price</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
I'm trying to remove and sort dates in multiple dropdowns using JQuery
basically we have course dates and I dont want to show any courses that have passed. So I decided to:
remove any date before today
sort in date order the remaining dates left
I tried to do it in one function but failed. I'm able to do it for one date, but can't work out how to loop over multiple dropdowns. (I guess I need to loop over them somehow)
This is the HTML (in this example there are only 2 dates with the ID tag pa_date_11 and pa_date_12 (the numbers change by product adn there may be more than 2))
<div class="summary entry-summary">
<h1 class="product_title entry-title">
Nail Technician Package</h1>
<p class="price"></p>
<div class="woocommerce-product-details__short-description">
<p>Save £25 by booking these 2 popular courses together. This package covers the two most popular methods of nail extensions. You’ll learn UV Gel extensions, UV Gel polish and also Acrylic Nail Extensions in this 2 day course.</p>
</div>
<p class="loud-link">
<a class="smooth-scroll" href="#tab-title-description">Full description →</a>
</p>
<form method="post" enctype="multipart/form-data" class="cart cart_group bundle_form layout_default group_mode_parent bundle_out_of_stock bundle_insufficient_stock initialized">
<div class="bundled_item_11 bundled_product bundled_product_summary product">
<div class="details">
<h4 class="bundled_product_title product_title"><span class="bundled_product_title_inner"><span class="item_title">UV Gel Polish Course | 1/2 Day Course</span><span class="item_qty"></span><span class="item_suffix"></span></span> <span class="bundled_product_title_link"><a class="bundled_product_permalink" href="#" target="_blank" aria-label="View product"></a></span></h4>
<div class="bundled_product_excerpt product_excerpt">
<p>The perfect way to apply a silky smooth and long-lasting UV Gel polish to nails. Gel polish is the ideal salon treatment as it takes only 30 minutes to apply and gives a gloss lacquer finish which lasts up to three weeks.</p>
</div>
<div class="cart bundled_item_cart_content variations_form" data-title="UV Gel Polish Course | 1/2 Day Course" data-product_title="UV Gel Polish Course | 1/2 Day Course" data-visible="yes" data-optional_suffix="" data-optional="no" data-type="variable" data-product_variations="" data-bundled_item_id="11" data-custom_data="{"bundle_id":4984,"bundled_item_id":11}" data-product_id="4888" data-bundle_id="4984" current-image="">
<table class="variations" cellspacing="0">
<tbody>
<tr class="attribute_options attribute_value_configurable" data-attribute_label="Course Location">
<td class="label">
<label for="pa_location_11">Course Location <abbr class="required" title="Required option">*</abbr></label>
</td>
<td class="value"><span class="sfblocks-select-wrap"><select id="pa_location_11" class="" name="bundle_attribute_pa_location_11" data-attribute_name="attribute_pa_location" data-show_option_none="yes">
<option value="">Choose an option</option>
<option value="newark" class="attached enabled">Newark</option>
</select></span></td>
</tr>
<tr class="attribute_options attribute_value_configurable" data-attribute_label="Course Date">
<td class="label">
<label for="pa_date_11">Course Date <abbr class="required" title="Required option">*</abbr></label>
</td>
<td class="value"><span class="sfblocks-select-wrap"><select id="pa_date_11" class="" name="bundle_attribute_pa_date_11" data-attribute_name="attribute_pa_date" data-show_option_none="yes">
<option value="">Choose an option</option>
<option value="24-09-2020" class="attached enabled">24/09/2020</option>
<option value="24-12-2020" class="attached enabled">24/12/2020</option>
<option value="12-12-2020" class="attached enabled">12/12/2020</option>
</select></span>
<div class="reset_bundled_variations" style="display: none;"><a class="reset_variations" href="#" style="visibility: hidden;">Clear</a></div>
</td>
</tr>
</tbody>
</table>
<div class="single_variation_wrap bundled_item_wrap">
<div class="woocommerce-variation single_variation bundled_item_cart_details" style="display: none;"></div>
<div class="woocommerce-variation-add-to-cart variations_button bundled_item_after_cart_details bundled_item_button woocommerce-variation-add-to-cart-disabled">
<input type="hidden" class="variation_id" name="bundle_variation_id_11" value="">
<div class="quantity quantity_hidden">
<input class="qty bundled_qty" type="hidden" name="bundle_quantity_11" value="1"></div>
</div>
</div>
</div>
</div>
</div>
<div class="bundled_item_12 bundled_product bundled_product_summary product">
<div class="details">
<h4 class="bundled_product_title product_title"><span class="bundled_product_title_inner"><span class="item_title">Nail Extension Acrylic | 1 Day Course</span><span class="item_qty"></span><span class="item_suffix"></span></span> <span class="bundled_product_title_link"><a class="bundled_product_permalink" href="#" target="_blank" aria-label="View product"></a></span></h4>
<div class="bundled_product_excerpt product_excerpt">
<p>This is an exclusive one day course covering all aspects of acrylic extension nail application. You will apply natural-looking tips and learn how to blend them into the natural nail to create a perfect extension.</p>
</div>
<div class="cart bundled_item_cart_content variations_form" data-title="Nail Extension Acrylic | 1 Day Course" data-product_title="Nail Extension Acrylic | 1 Day Course" data-visible="yes" data-optional_suffix="" data-optional="no" data-type="variable" data-product_variations="" data-product_id="4881" data-bundle_id="4984" current-image="">
<table class="variations" cellspacing="0">
<tbody>
<tr class="attribute_options attribute_value_configurable" data-attribute_label="Course Location">
<td class="label">
<label for="pa_location_12">Course Location <abbr class="required" title="Required option">*</abbr></label>
</td>
<td class="value"><span class="sfblocks-select-wrap"><select id="pa_location_12" class="" name="bundle_attribute_pa_location_12" data-attribute_name="attribute_pa_location" data-show_option_none="yes">
<option value="">Choose an option</option>
<option value="newark" class="attached enabled">Newark</option>
</select></span></td>
</tr>
<tr class="attribute_options attribute_value_configurable" data-attribute_label="Course Date">
<td class="label">
<label for="pa_date_12">Course Date <abbr class="required" title="Required option">*</abbr></label>
</td>
<td class="value"><span class="sfblocks-select-wrap"><select id="pa_date_12" class="" name="bundle_attribute_pa_date_12" data-attribute_name="attribute_pa_date" data-show_option_none="yes">
<option value="">Choose an option</option>
<option value="03-10-2020" class="attached enabled">03/10/2020</option>
<option value="13-10-2020" class="attached enabled">13/10/2020</option>
<option value="23-09-2020" class="attached enabled">23/09/2020</option>
<option value="14-12-2020" class="attached enabled">14/12/2020</option>
<option value="02-12-2020" class="attached enabled">02/12/2020</option>
<option value="01-12-2020" class="attached enabled">01/12/2020</option>
</select></span>
<div class="reset_bundled_variations" style="display: none;"><a class="reset_variations" href="#" style="visibility: hidden;">Clear</a></div>
</td>
</tr>
</tbody>
</table>
<div class="single_variation_wrap bundled_item_wrap">
<div class="woocommerce-variation single_variation bundled_item_cart_details" style="display: none;"></div>
<div class="woocommerce-variation-add-to-cart variations_button bundled_item_after_cart_details bundled_item_button woocommerce-variation-add-to-cart-disabled">
<input type="hidden" class="variation_id" name="bundle_variation_id_12" value="">
<div class="quantity quantity_hidden">
<input class="qty bundled_qty" type="hidden" name="bundle_quantity_12" value="1"></div>
</div>
</div>
</div>
</div>
</div>
<div class="bundled_item_13 bundled_product bundled_product_summary product">
<div class="details">
<h4 class="bundled_product_title product_title"><span class="bundled_product_title_inner"><span class="item_title">Nail Extension UV Gel | 1 Day Course</span><span class="item_qty"></span><span class="item_suffix"></span></span></h4>
<div class="bundled_product_excerpt product_excerpt">
<p>This is an exclusive one day course covering all aspects of UV Gel extension nail application. You will apply natural looking tips and learn how to blend them into the natural nail to create a perfect extension.</p>
</div>
<div class="cart unavailable_item variations_form" data-title="Nail Extension UV Gel | 1 Day Course" data-product_variations="[]" data-product_title="Nail Extension UV Gel | 1 Day Course" data-visible="yes" data-optional_suffix="" data-optional="no" data-type="variable" data-bundled_item_id="13" data-custom_data="" data-product_id="4879" data-bundle_id="4984" current-image="">
<div class="bundled_item_wrap">
<div class="bundled_item_cart_content">
<div class="bundled_item_cart_details">
<p class="bundled_item_unavailable ">Please call to arrange a date</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cart bundle_data bundle_data_4984" data-bundle_price_data="" data-bundle_id="4984">
<div class="bundle_unavailable woocommerce-info">This product is currently unavailable, please call us to arrange a date.</div>
</div>
</form>
</div>
And this is my JQuery so far
// remove any dates older than today function
(function ($) {
$.fn.removeOldDates = function () {
$("select[id^='pa_date_'] > option").each(function () {
//console.log(this.text + ' ' + this.value);
const now = new Date().getTime();
const time = this.text.split(/[\s/-]+/); // split the time, by / or -
const day = time[0];
const month = time[1] - 1;
const year = time[2];
//console.log(time);
const row_date = new Date();
const test = row_date.setFullYear(year, month, day);
// now we have both times, we can compare them
if (now > row_date.getTime() || this.text == "") {
// if the date is less that today or empty remove it from the dropdown
$("select[id^='pa_date_'] > option[value=" + this.value + "]").remove();
}
});
};
})(jQuery);
// re-order the dates function
(function ($) {
$.fn.orderDates = function () {
$(this)
.find("option:not(:first)")
.each(function (index, value) {
const t = this.textContent.split(/[\s/-]+/);
$(this).data("_ts", new Date(t[2], t[1] - 1, t[0]).getTime());
console.log(t);
$(this)
.sort(function (a, b) {
return $(a).data("_ts") - $(b).data("_ts");
})
.appendTo("#pa_date_12");
//$(this).html("select[id^=pa_date_]" + index);
//$(this).html( $('<option value="Loo">Loo' + index + '</option>') );
});
return this;
};
})(jQuery);
// Map the date drop downs
$("select[id^=pa_date_]").each(function (index) {
console.log(index);
// $(this) refers to one specific <select> element
// $(this).append('<option value="foo">Bar ' + index + '</option>');
$(this).removeOldDates();
$(this).orderDates();
});
I also have it in a Codepen if you wanted to fork and ammend https://codepen.io/xgstq/pen/jOrZwKq
Im getting stuck on the .sort method within the orderDates function as its returning NAN and then appending it to the relevent dropdown.
Any help appreciated
I got there in the end, I was closing the each (function()) too late.
This is my final jQuery:
// remove any dates older than today function
(function ($) {
$.fn.removeOldDates = function () {
$("select[id^='pa_date_'] > option").each(function () {
const now = new Date().getTime();
const time = this.text.split(/[\s/-]+/); // split the time, by / or -
const day = time[0];
const month = time[1] - 1;
const year = time[2];
const row_date = new Date();
const test = row_date.setFullYear(year, month, day);
// now we have both times, we can compare them
if (now > row_date.getTime() || this.text == "") {
// if the date is less that today or empty remove it from the dropdown
$("select[id^='pa_date_'] > option[value=" + this.value + "]").remove();
}
});
};
})(jQuery);
// re-order the dates function
(function ($) {
$.fn.orderDates = function () {
$(this).find("option:not(:first)")
.each(function (index, value) {
const t = this.textContent.split(/[\s/-]+/);
$(this).data( "_ts", new Date(t[2], t[1] - 1, t[0]).getTime() );
}).sort(function (a, b) {
return $(a).data("_ts") - $(b).data("_ts");
}).appendTo($(this));
return this;
};
})(jQuery);
// Map the date drop downs
$("select[id^=pa_date_]").each(function (index) {
$(this).removeOldDates();
$(this).orderDates();
});
I'll definitely revisit the woocommerce and take another look before implementing it
Thanks
I'm a pretty noob in javascript. I'm trying to duplicate a list which has input field for each option. So far it's working, though, the duplicated list don't show the associated input fields. Also I would want to make a sum of every field that has a data.
$(document).ready(function() {
$("#btn-copy").click(function() {
var target = $(this).closest(".revenus");
target.clone(true, true).appendTo(target.parent());
});
});
$(document).ready(function() {
toggleFields();
$("#revenu-type").change(function() {
toggleFields();
toggleFields2();
});
});
function toggleFields() {
if ($("#revenu-type").val() === "option-1")
$("#option-a").show();
else
$("#option-a").hide();
if ($("#revenu-type").val() === "option-2")
$("#option-b").show();
else
$("#option-b").hide();
if ($("#revenu-type").val() === "option-3")
$("#option-c").show();
else
$("#option-c").hide();
if ($("#revenu-type").val() === "option-4")
$("#option-d").show();
else
$("#option-d").hide();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="revenus">
<p>Choose type</p>
<p>revenue:
<select id="revenu-type" name="dbType">
<option>Ajouter un autre revenu</option>
<option value="option-1">Revenu 1</option>
<option value="option-2">Revenu 2</option>
<option value="option-3">Revenu 3</option>
<option value="option-4">Revenu 4</option>
</select>
</p>
<div id="option-a" style="display: flex;">
<p>Option 1 - a
<input type="text" name="num-child" />
</p>
<p>Option 1 - b
<input type="text" name="price-1" />
</p>
</div>
<div id="option-b">
<p>Option 2
<input type="text" name="price-2" />
</p>
</div>
<div id="option-c">
<p>Option 3
<input type="text" name="price-3" />
</p>
</div>
<div id="option-d">
<p>Option 4
<input type="text" name="price-4" />
</p>
</div>
<p align="left">
<input type="button" value="add" id="btn-copy" />
</p>
</div>
This issue is in your toggleFields - when you use
$("#option-a")...
it will only find the first one as IDs must be unique.
So the first thing to do is change all the id= to class= (and change corresponding selectors).
You need to find the one that's related to the current revenu-type inside the current .revenus. You can do that by passing this to toggleFields - with a slight change from this to $(this).closest(".revenus") to pass in the outer wrapper.
From there, you can use:
wrapper.find(".option-a")...
to get the item within the wrapper.
The btn-copy click events gets cloned, so while this should use a class and event delegation $("document").on("click", ".btn-copy" ... it will still work with the clone including events.
Without changing too much of your existing code (eg using .toggle(bool) instead of if (bool) ..show else ..hide), this gives:
$(document).ready(function() {
$("#btn-copy").click(function() {
var target = $(this).closest(".revenus");
target.clone(true, true).appendTo(target.parent());
});
});
$(document).ready(function() {
toggleFields($(".revenus").first());
$(".revenu-type").change(function() {
toggleFields($(this).closest(".revenus"));
//toggleFields2();
});
});
function toggleFields(wrapper) {
if (wrapper.find(".revenu-type").val() === "option-1")
wrapper.find(".option-a").show();
else
wrapper.find(".option-a").hide();
if (wrapper.find(".revenu-type").val() === "option-2")
wrapper.find(".option-b").show();
else
wrapper.find(".option-b").hide();
if (wrapper.find(".revenu-type").val() === "option-3")
wrapper.find(".option-c").show();
else
wrapper.find(".option-c").hide();
if (wrapper.find(".revenu-type").val() === "option-4")
wrapper.find(".option-d").show();
else
wrapper.find(".option-d").hide();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="revenus">
<p>Choose type</p>
<p>revenue:
<select class="revenu-type" name="dbType">
<option>Ajouter un autre revenu</option>
<option value="option-1">Revenu 1</option>
<option value="option-2">Revenu 2</option>
<option value="option-3">Revenu 3</option>
<option value="option-4">Revenu 4</option>
</select>
</p>
<div class="option-a" style="display: flex;">
<p>
Option 1 - a
<input type="text" name="num-child" />
</p>
<p>
Option 1 - b
<input type="text" name="price-1" />
</p>
</div>
<div class="option-b">
<p>
Option 2
<input type="text" name="price-2" />
</p>
</div>
<div class="option-c">
<p>
Option 3
<input type="text" name="price-3" />
</p>
</div>
<div class="option-d">
<p>
Option 4
<input type="text" name="price-4" />
</p>
</div>
<p align="left">
<input type="button" value="add" id="btn-copy" />
</p>
</div>
So I'm trying to calculate sales tax for a project and I can't get it to work. Needless to say, I'm still learning javascript. Here's how it works: If the buyer selects New Jersey, I want to apply a 7% sales tax to the order. Everywhere else goes to zero.
Here's a link to the jsFiddle project: https://jsfiddle.net/JohnOHFS/hpdnmjfL/
Here's my basic form HTML (skipping the opening and closing tags, etc.)
<div id="public">
<div class="row">
<div class="col-xs-7 col-md-7">
<div class="form-group">
<label for="city">CITY</label>
<input type="text" size="20" autocomplete="off" class="city input-small form-control" placeholder="CITY"/>
</div>
</div>
<div class="col-xs-4 col-md-4">
<div class="form-group">
<label for="state">STATE</label>
<select class="form-control" id="state" onChange="taxRate()">
<option value="">N/A</option>
<option value="AK">Alaska</option>
<option value="AL">Alabama</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-5 col-md-5">
<div class="form-group">
<label for="zipCode">ZIP CODE</label>
<input id="zip" type="text" size="6" autocomplete="off" class="zipcode form-control" placeholder="ZIP CODE"/>
</div>
</div>
</div>
</div> <!-- Closes Public -->
<div class="row">
<div class="col-xs-7 col-md-7">
<label>ORDER INFORMATION</label>
</div>
</div>
<div class="row">
<div class="col-xs-7 col-md-7 col-md-offset-1">
<label>SUBTOTAL: <b>$<span id="order_subtotal">100</span></b></label>
</div>
</div>
<div class="row">
<div class="col-xs-7 col-md-7 col-md-offset-1">
<label>TAXES: <b><span id="order_tax" type="text" value=""></span></b></label>
</div>
</div>
<div class="row">
<div class="col-xs-7 col-md-7 col-md-offset-1">
<label>ORDER TOTAL: <b><span id="order_total" type="text" value=""></span></b></label>
</div>
</div>
Here's the Javascript:
function taxRate() {
var tax_rate = .07;
var order_taxes = 0;
var subtotal = document.getElementById("order_subtotal").value;
subtotal = parseInt(subtotal);
var total = 0;
var state = document.getElementById("state").value;
var selection = state.options[state.selectedIndex].value;
if (selection == 'New Jersey') {
order_taxes += tax_rate * subtotal;
}
if (selection == 'else') {
order_taxes = 0;
}
if (selection == 'New Jersey') {
tax_percent = tax_rate * 100;
}
if (selection == 'else') {
tax_percent = 0;
}
var el = document.getElementById('order_tax');
el.textContent = order_taxes;
var total = subtotal + order_taxes;
var el1 = document.getElementById('order_total');
el1.textContent = total;
}
Here are my questions.
1. What am i doing wrong?
2. How do I pass tax_percent from this javascript into the html for submittal to Stripe?
Thanks!
The first problem with your fiddle is that the taxRate() function is not a global function and so it can't be called from an inline html attribute event handler. This is because by default JSFiddle wraps the JS in an onload handler. Use the JS settings menu (from top-right corner of the JS window) to change the "load type" to one of the "no wrap" options.
Then you've got a problem getting the order total value, because you try to get the element .value when it is a span, so you need to use .innerHTML.
The next thing is that your state variable is set equal to the value of the current selection of the select element. So it will be 'NJ', or 'AK', etc. (Or an empty string if nothing is selected.) So when you try to set the selection variable to state.options[state.selectedIndex].value that won't work because state is a string. Test your existing state variable against 'NJ':
if (state == 'NJ')
You also have a test if (selection == 'else') which won't do anything because even if your selection variable worked its value would never be the string 'else'. I think you just want an else statement there, except that what that block actually does is just set order_taxes = 0 and order_taxes has already been set to a default of 0 at the point of declaration. So you don't need that part at all.
Then you've got another if testing for New Jersey that could be combined with the first one. It's setting a tax_percent variable that isn't declared, so add a declaration for that with var at the top of your function.
Also, because of the way JS does floating point maths, 100 * 0.07 comes out to be 7.000000000000001. You probably want to round that off to two decimal places for the cents amount (which in this case would be no cents, but obviously if the order total wasn't such a round number you might get some number of cents in the taxes).
How do I pass tax_percent from this javascript into the html for submittal to Stripe?
One way is to add a hidden input to your form and set its value from JS:
<input type="hidden" id="tax_percent" name="tax_percent">
document.getElementById('tax_percent').value = tax_percent;
Putting that all together:
function taxRate() {
var tax_rate = .07;
var order_taxes = 0;
var tax_percent = 0;
var subtotal = document.getElementById("order_subtotal").innerHTML;
subtotal = parseInt(subtotal);
var total = 0;
var state = document.getElementById("state").value;
if (state === 'NJ') {
order_taxes += +(tax_rate * subtotal).toFixed(2);
tax_percent = +(tax_rate * 100).toFixed(2);
}
var el = document.getElementById('order_tax');
el.textContent = order_taxes;
var total = subtotal + order_taxes;
var el1 = document.getElementById('order_total');
el1.textContent = total;
document.getElementById('tax_percent').value = tax_percent;
}
Demo: https://jsfiddle.net/hpdnmjfL/5/
I've got this set up on JsFiddle: http://jsfiddle.net/melissal/FmEcw/
Now when I change the selection of the 'Quantity' dropdown, it changes the price of the paper (above). I want this to show in the 2nd drop down. So when you select the 'Paper' dropdown you see two options, 'Regular' and 'Premium (+ $XXX)', but I can't figure out how to get the new price to show up. Is that possible?
Here's the HTML:
Paper: $<span id="paper_div"></span><br />
<div id="product-options">
<form action="/cart/add" id="ProjectProductForm" method="post" accept-charset="utf-8">
<div style="display:none;">
<input type="hidden" name="_method" value="POST"/>
</div>
<div id="product-options-qty">
<span class="text">Quantity: </span>
<span class="form">
<div class="input select">
<select name="field_6" class="text_select" id="field_6">
<option value="225">15 # $225.00</option>
<option value="240">20 # $240.00</option>
<option value="250">30 # $250.00</option>
<option value="270">40 # $270.00</option>
</select>
</div>
</span>
</div>
<div id="product-options-paper">
<span class="text">Paper: </span>
<span class="form">
<div class="input select">
<select name="field_6" class="text_select">
<option value="1">Regular</option>
<option value="2">Premium (+ $<span id="paper_div"></span>)</option>
</select>
</div>
</span>
</div>
</form>
And the JS:
$(document).ready(function() {
$("#field_6").change(function() {
var id = $(this).val();
$('#price_div').html($(this).val());
var premium_paper = id * .25;
var premium_paper = parseFloat(Math.round(premium_paper * 100) / 100).toFixed(2);
$('#paper_div').html(premium_paper);
}).change();
});
Try using $('#field_7 option:eq(1)').html('Premium (+ $'+premium_paper+')'):
Note that I added an ID to the second select. You may also want to give your drop downs different name attributes.
$(document).ready(function () {
$("#field_6").change(function () {
var id = $(this).val();
$('#price_div').html($(this).val());
var premium_paper = id * .25;
var premium_paper = parseFloat(Math.round(premium_paper * 100) / 100).toFixed(2);
$('#paper_div').html(premium_paper);
$('#field_7 option:eq(1)').html('Premium (+ $'+premium_paper+')')
}).change();
});
jsFiddle example