I'm having a problem when trying to multiply the totalPallets by the price-per-pallet ($25) and then showing that in the productSubTotal box. With the code as it is right now, the quatity total shows but when I try to get the price result, it doesn't show the operation. Also, if I try changing anythung from the code, the whole thing breaks down. I'll be thankful if anyone could help me. Thanks
// UTILITY FUNCTIONS
function IsNumeric(n) {
return !isNaN(n);
}
function calcTotalPallets() {
var totalPallets = 0;
$(".num-pallets-input").each(function() {
var thisValue = parseInt($(this).val());
if ( (IsNumeric(thisValue)) && (thisValue != '') ) {
totalPallets += parseInt(thisValue);
};
});
$("#quantitytotal").val(totalPallets);
}
function calcProdSubTotal() {
var prodSubTotal = 0;
$(".totalprice").each(function() {
var valString = parseInt(totalPallets) * multiplier;
prodSubTotal += parseInt(valString);
});
$("#product-subtotal").val(CommaFormatted(prodSubTotal));
};
// "The Math" is performed pretty much whenever anything happens in the quanity inputs
$('.num-pallets-input').bind("focus blur change keyup", function(){
// Caching the selector for efficiency
var $el = $(this);
// Grab the new quantity the user entered
var numPallets = CleanNumber($el.val());
var totalPallets = CleanNumber($el.val());
var prodSubTotal = CleanNumber($el.val());
// Find the pricing
var multiplier = $el
.parent().parent()
.find("td.price-per-pallet span")
.text();
};
// Calcuate the overal totals
calcProdSubTotal();
calcTotalPallets();
});
function CommaFormatted(amount) {
var delimiter = ",";
var i = parseInt(amount);
if(isNaN(i)) { return ''; }
i = Math.abs(i);
var minus = '';
if (i < 0) { minus = '-'; }
var n = new String(i);
var a = [];
while(n.length > 3)
{
var nn = n.substr(n.length-3);
a.unshift(nn);
n = n.substr(0,n.length-3);
}
if (n.length > 0) { a.unshift(n); }
n = a.join(delimiter);
amount = "$" + minus + n;
return amount;
}
});
Related
my javascript isn't the best. I have some code here in the form of a calculator:
https://jsfiddle.net/yadL05aL/
my javascript:
// Get a list of your products and pop them into a dropdownlist
function GetProducts() {
var products = V12.getFinanceProducts();
var ddlProducts = document.getElementById('productsList');
for (var i = 0; i < products.length; i++) {
var newItem = new Option(products[i].name, products[i].productId);
ddlProducts.appendChild(newItem);
}
}
// Get details of repayments for the product selected
function CalculateRepayments() {
var productId = $('#productsList').val(); // selected product
var financeProduct = V12.getFinanceProduct(productId); // get the object
var cashPrice = $('#cashPrice').val();
var depositFactor = $('#deposit').val();
var deposit = cashPrice * (depositFactor / 100);
var payments = V12.calculate(financeProduct, cashPrice, deposit);
PopulateDescription(payments);
}
function UpdateLoanInfo() {
$('#cashPrice').val($('#cpRange').val());
$('#deposit').val($('#depRange').val());
CalculateRepayments();
}
// Show repayment plan details in the description
function PopulateDescription(payments) {
$('#lblFinalPayment').html('');
$('#lblDeposit').html('£' + payments.deposit);
$('#lblInitPayments').html('£' + payments.initialPayments);
$('#lblTotalRepayable').html('£' + payments.amountPayable);
$('#lblInterest').html(payments.apr + '%');
if (payments.initialPayments != payments.finalPayment && payments.finalPayment > 0) {
$('#lblMonths').html(payments.months - 1);
$('#lblFinalPayment').html(' and a final payment of £' + payments.finalPayment);
} else {
$('#lblMonths').html(payments.months);
}
}
// Firing this will loop through your V12 products and grab the product with the lowest
// possible monthly payments.
function GetLowestMonthlyPayments() {
var products = V12.getFinanceProducts();
var lowestMonthlyPayment = 0;
var lowestMonthlyPaymentProductId = 0;
for (var i = 0; i < products.length - 1; i++) {
var product = V12.getFinanceProduct(products[i].productId);
var cashPrice = $('#cashPrice').val();
var depositFactor = $('#deposit').val();
var deposit = cashPrice * (depositFactor / 100);
var payments = V12.calculate(product, cashPrice, deposit);
var monthlyPayment = payments.initialPayments;
if (parseFloat(lowestMonthlyPayment) > parseFloat(monthlyPayment) || lowestMonthlyPayment == 0) {
lowestMonthlyPayment = payments.initialPayments;
lowestMonthlyPaymentProductId = product.productId;
}
}
$("#productsList").val(lowestMonthlyPaymentProductId);
CalculateRepayments();
}
// Ready up our events
(function ($) {
GetProducts();
CalculateRepayments();
$('#productsList').on('change', function () {
CalculateRepayments();
});
$('#cpRange, #depRange').on("input", function () {
UpdateLoanInfo();
});
$('#lowestMonthlyPayments').click(function () {
GetLowestMonthlyPayments();
});
$('#cashPrice, #deposit').keyup(function () {
var cp = $('#cashPrice').val();
var dep = $('#deposit').val();
$('#cpRange').val(cp);
$('#depRange').val(dep);
CalculateRepayments();
});
//spinner//
$('<div class="quantity-nav"><div class="quantity-button quantity-up">+</div><div class="quantity-button quantity-down">-</div></div>').insertAfter('.quantity input');
$('.quantity').each(function() {
var spinner = jQuery(this),
input = spinner.find('input[type="number"]'),
btnUp = spinner.find('.quantity-up'),
btnDown = spinner.find('.quantity-down'),
min = input.attr('min'),
max = input.attr('max');
btnUp.click(function() {
var oldValue = parseFloat(input.val());
if (oldValue >= max) {
var newVal = oldValue;
} else {
var newVal = oldValue + 100;
}
spinner.find("input").val(newVal);
spinner.find("#cpRange").val(cp);
spinner.find("#depRange").val(dep);
spinner.find("input, #cashPrice").trigger("change");
});
btnDown.click(function() {
var oldValue = parseFloat(input.val());
if (oldValue <= min) {
var newVal = oldValue;
} else {
var newVal = oldValue - 100;
}
spinner.find("input").val(newVal);
spinner.find("input").trigger("change");
});
});
})(jQuery);
what I am trying to achieve is when you click on the plus and minus buttons in the cash price input, the bottom labels reflect the decrease or increment changes to the deposit / monthly repayments & APR.
Can anyone please point me in the right direction?
Kind regards
Robbie
Iam working on an application, in the Grand Total field, its showing the sum of all the margin fields totals. But when the page loads its showing NaN in the total field. How can i show the existing total to show up in the Grand Total field?
This is my script.
demo
js
function getIndexedElement(item, index) {
if (item.length) {
if (index < item.length) {
return item[index];
} else {
return false;
}
} else {
if (index === 0) {
return item;
}
}
return false;
}
function isNum(value) {
return 123;
}
function calcTotals() {
var grandTotal = 0;
var margin_total = 0;
var total_inr1 = 0;
var i = 0;
while (getIndexedElement(document.forms['cart'].elements['add_percentage[]'], i)) {
add_percentageObj = getIndexedElement(document.forms['cart'].elements['add_percentage[]'], i);
addon_valueObj = getIndexedElement(document.forms['cart'].elements['addon_value[]'], i);
total_inr_valueObj = getIndexedElement(document.forms['cart'].elements['total_inr[]'], i);
totalObj = getIndexedElement(document.forms['cart'].elements['add_value[]'], i);
priceunitObj = getIndexedElement(document.forms['cart'].elements['price_unit[]'], i);
qtyObj = getIndexedElement(document.forms['cart'].elements['qty[]'], i);
marginObj = getIndexedElement(document.forms['cart'].elements['margin_for[]'], i);
if (isNaN(add_percentageObj.value)) {
add_percentageObj = '';
}
if (isNaN(addon_valueObj.value)) {
addon_valueObj = '';
}
if (add_percentageObj.value != 0) {
totalObj.value = (((total_inr_valueObj.value * 1) * add_percentageObj.value / 100) + total_inr_valueObj.value * 1).toFixed(3);
grandTotal = grandTotal + parseFloat(totalObj.value);
marginObj.value = ((totalObj.value * 1) - (total_inr_valueObj.value * 1)).toFixed(3);
margin_total = ((margin_total * 1) + marginObj.value * 1);
//total_inr1 = total_inr1 + parseFloat(total_inr_valueObj.value);
//c.value=Math.round((b.value/100) *a.value ).toFixed(2);
} else if (addon_valueObj.value != 0) {
totalObj.value = ((addon_valueObj.value * 1) + total_inr_valueObj.value * 1).toFixed(3);
grandTotal = grandTotal + parseFloat(totalObj.value);
marginObj.value = ((totalObj.value * 1) - (total_inr_valueObj.value * 1)).toFixed(3);
margin_total = ((margin_total * 1) + marginObj.value * 1);
//total_inr1 = total_inr1 + parseFloat(total_inr_valueObj.value);
} else {
totalObj.value = ((addon_valueObj.value * 1) + total_inr_valueObj.value * 1).toFixed(3);
grandTotal = grandTotal + parseFloat(totalObj.value);
marginObj.value = ((totalObj.value * 1) - (total_inr_valueObj.value * 1)).toFixed(3);
margin_total = ((margin_total * 1) + marginObj.value * 1);
//total_inr1 = total_inr1 + parseFloat(total_inr_valueObj.value);
}
i++;
}
//document.getElementById('grand_total').value = grandTotal.toFixed(3);
//document.getElementById('margin_total').value = margin_total.toFixed(3);
//document.getElementById('total_inr1').value = total_inr1.toFixed(3);
//document.getElementById('margin_for').value = margin_for;
marginTotal();
return;
}
function marginTotal() {
var x = $('[name="gt[]"]:checked').length;
if (x != 0) return;
var sum = 0;
$('input[name="margin_for[]"]').each(function () {
sum += +this.value;
});
$("#total12").val(sum);
}
$(function () {
$("input[type='checkbox'").on("change", function () {
recalcTotal();
}).change();
function recalcTotal() {
var total12 = 0;
var checkedinput = $("input:checked");
var targetcheckboxes = checkedinput.length ? checkedinput : $("input:checkbox");
targetcheckboxes.each(function () {
total12 += parseFloat($(this).next("input").val(), 10) * 1;
});
$("#total12").val(total12.toFixed(3));
}
});
$(window).load(function () {
$(document).ready(function () {
$("select").on('change', function () {
var dept_number = $(this).val();
var price = $(this).find(':selected').data('price');
var selected = $(this).find('option:selected').text();
if (selected == "INR") {
$(this).closest('table').find('.total1').val($(this).closest('table').find('.total').val());
} else {
$(this).closest('table').find('.total1').val((($(this).closest('table').find('.total').val() * price) / $(this).closest('table').find('.inrvalue').val()).toFixed(3));
}
$(this).closest('table').find('.price_unit').val(($(this).closest('table').find('.total1').val() / $(this).closest('table').find('.qty').val()).toFixed(3));
});
});
}); //]]>
In the fiddle you can see the last field, that is margin field. And extreme down you can see the Grand Total. Page Load its showing NaN..
you simply need to check input value next to checkbox whether its isNaN() or notDEMO There are many bugs like if you enter Text in Total colum you get NaN in textbox beside checkbox as well in Grandtotal since your updating it after change in input you need to validate the textbox on change
targetcheckboxes.each(function () {
var temp=$(this).next("input").val();
if(temp){
total12 += parseFloat(temp, 10) * 1;
}
});
$("#total12").val(total12.toFixed(3));
UPDATED ANSWER
So I was wrong, after some more testing its just that your first 3 readonly checkboxes don't have value=0.000 as an attribute.
As they are text inputs, javascript doesn't automatically assume that an empty input is equal to 0.
just add value=0.000 to the first three checkboxes
INCORRECT OLD ANSWER
In your targetcheckboxes.each() loop, your expression:
total12 += parseFloat($(this).next("input").val(), 10) * 1;
is causing the problem.
next("input") will match any type of input including text inputs. somewhere along the line you are concatenating a string to your total12 variable and hence the final value of total12 can not be parsed to a float.
I think you should use
parseInt(yourvalue);
parseFloat(yourvalue).toFixed(2);
whenever you are calculating something using js
I tried the following:
HTML:
<div contenteditable="true" id="editable"></div>
JS:
$('#editable').keyup(function() {
addID();
});
function addID()
{
$('#editable *').each(function() {
var t = GenerateID();
$(this).attr('id','id-' + t);
});
}
function GenerateID()
{
var str = 'abcdefghijklmnopqrstuvwxyz0123456789';
var alphabet = '',
genID = '';
while(genID.length < 5)
{
alphabet = str.charAt(Math.floor(Math.random() * str.length));
genID += alphabet;
}
return genID;
}
But on every keyup it keeps on changing the ID.
How can I just set the id once for all the elements while typing, and still keep it unique throughout the div ?
JSFiddle
LAST UPDATE:
Now I checked the code in your fiddle and I'm sure it works. The checking for uniqueness can probably be made into a function, but i'll leave that to you:
$('#editable').on( 'keyup', addID );
var count = 0; // this will absolutely ensure that ID will be unique
function addID(){
var previousIDs = [];
$('#editable *').each(function() {
count++;
var thisID = $(this).attr( 'id' );
// let's check if we have duplicates:
var index = 0, len = previousIDs.length, isDuplicate = false;
for( index = 0; index < len; index++ ){
if ( thisID === previousIDs[index] ) {
isDuplicate = true;
break;
}
}
// now change the ID if needed:
if ( isDuplicate || ! thisID ){
var t = GenerateID();
var newID = 'id-' + t + '-' + count;
$(this).attr('id', newID);
previousIDs.push( newID );
}else{
previousIDs.push( thisID );
}
});
}
Working Fiddle
Try this:
$('#editable').keyup(addID);
function addID() {
$('#editable *').each(function () {
var t = GenerateID();
var elem = $(this);
var attr = elem.attr('id');
if (!attr) {
elem.attr('id', 'id-' + t);
}
});
}
/**
* #return {string}
*/
function GenerateID() {
var str = 'abcdefghijklmnopqrstuvwxyz0123456789';
var alphabet = '',
genID = '';
while (genID.length < 5) {
alphabet = str.charAt(Math.floor(Math.random() * str.length));
genID += alphabet;
}
return genID;
}
Also consider that your random string generator may generate same string again.
Replace your code with following :
$('#editable *').each(function() {
if(!$(this).hasClass("idgenerated")){
console.log( $(this).attr('id') );
var t = GenerateID();
$(this).attr('id','id-' + t);
$(this).addClass("idgenerated");
console.log($(this).prop("tagName") + ' = ' + t);
}
});
Working fiddle
I meet a trouble with a function. actually I need to make this function to perform a calculation on some text fields. When I worked on a single line no problems. But recently, someone asked to make a table with multiple lines (one line can be added dynamically) so, I do the following function so that it can not only duplicate line but id change all the fields concerned, so I add class to these fields. therefore I proceed as follows:
function clone(line) {
newLine = line.cloneNode(true);
line.parentNode.appendChild(newLine);
var tab = document.getElementsByClassName('libelle_debours')
var i = -1;
while (tab[++i]) {
tab[i].setAttribute("id", "_" + i);
};
var cab = document.getElementsByClassName('ht_no_tva')
var j = -1;
while (cab[++j]) {
cab[j].setAttribute("id", "_" + j);
};
var dab = document.getElementsByClassName('ht_tva')
var k = -1;
while (dab[++k]) {
dab[k].setAttribute("id", "_" + k);
};
var eab = document.getElementsByClassName('taux')
var l = -1;
while (eab[++l]) {
eab[l].setAttribute("id", "_" + l);
};
var fab = document.getElementsByClassName('tva')
var m = -1;
while (fab[++m]) {
fab[m].setAttribute("id", "_" + m);
};
}
function delRow() {
var current = window.event.srcElement;
//here we will delete the line
while ((current = current.parentElement) && current.tagName != "TR");
current.parentElement.removeChild(current);
}
The problem in fact is the second function that is used to make the calculation:
function calcdebours() {
var taux = document.getElementById('debours_taux_tva').value;
var ht_no_tva = document.getElementById('debours_montant_ht_no_tva').value;
var ht_tva = document.getElementById('debours_montant_ht_tva').value;
var tva = Math.round((((ht_tva) * (taux)) / 100) * 100) / 100;;
if (taux == '') {
taux = 0;
}
if (ht_no_tva == '') {
ht_no_tva = 0;
}
if (ht_tva == '') {
ht_tva = 0;
}
document.getElementById('debours_montant_tva').value = tva;
document.getElementById('debours_montant_ttc').value = (tva) + parseFloat(ht_tva) + parseFloat(ht_no_tva)
}
function
montant_debours() {
var ttc = document.getElementById('debours_montant_ttc').value;
var ttc2 = document.getElementById('debours_montant_ttc2').value;
if (ttc == '') {
var ttc = 0;
} else {
var ttc = document.getElementById('debours_montant_ttc').value;
}
if (ttc2 == '') {
var ttc2 = 0;
} else {
var ttc2 = document.getElementById('debours_montant_ttc2').value;
}
tx = parseFloat(ttc) + parseFloat(ttc2);
document.getElementById('ttc_cheque').value = Math.round(tx * 100) / 100;
}
As Id are not the same, do I have to create as many functions
there are lines?
Is it possible to fit a single function to process each line?
If so can you tell me how?
If I'm not mistaken you can use for loop and append increment to the end of element's id. Like this:
trs = document.getElementById('container Id').getElementsByTagName('tr');
For (var i = 1, i <= trs.length; i++)
{
var el = document.getElementById('debours_montant_ttc' + i);
}
I have a little Problem. I have seven <select>'s. The go from left to right counting up.
<select id="sel_1" onchange="evalonsubmit('sel_1',1);">
<select id="sel_2" onchange="evalonsubmit('sel_2',2);">
That goes from 1 to 7 in this way.
The logic is easy. On click check if the value is -1 if it is disable everything on the right and set it to -1. if it is not -1 then enable the the right of the clicked one (+1 so to say)
And that's the code:
function evalonsubmit(ID, n)
{
var ElementID = document.getElementById(ID);
if(ElementID.value = -1) {
for (var i = n + 1; i <= 7; i++){
var newID = "sel_" + i;
var newValue = document.getElementById();
newValue.disable = true;
newValue.value = -1
}
} else {
var newID = "sel_"+(n+1)
var newValue = document.getElementById();
newValue.disable = false;
}
}
Can somebody kind JS hacker help me?
I just fixed some simple mistakes in your code ..
function evalonsubmit(ID, n)
{
var ElementID = document.getElementById(ID);
if (ElementID.value == -1){
for (var i=n+1; i <= 7; i++){
var newID = "sel_" + i;
var newValue = document.getElementById(newID);
newValue.disable = true;
newValue.value = -1
}
} else {
var newID = "sel_"+(n+1)
var newValue = document.getElementById(newID);
newValue.disable = false;
}
}
Not quite sure what you want, but it probably should be:
if (ElementID.value == -1){
// ^--- two = , otherwise you assign the value
and
var newID = "sel_" + i;
var newValue = document.getElementById(newID);
// pass parameter ---^
Same in the else branch.
Besides that, I would give your variables more meaningful names. E.g. ElementID lets you assume that the value is an ID. But it is not. It is a DOM element. Same for newValue.
You're missing the parameter in a couple of your calls to document.getElementById, and the property for disabling a <select> is disabled, not disable. You also have = where you need ==.
function evalonsubmit(ID, n)
{
var ElementID = document.getElementById(ID);
if (ElementID.value == -1){
for (var i=n+1; i <= 7; i++){
var newID = "sel_" + i;
var newValue = document.getElementById(newID);
newValue.disabled = true;
newValue.value = -1;
}
} else {
var newID = "sel_"+(n+1);
var newValue = document.getElementById(newID);
newValue.disabled = false;
}
}
Why not do this:
HTML:
<div class="wrapper">
<select onchange="evalonsubmit(this);" />
<select onchange="evalonsubmit(this);" />
<select onchange="evalonsubmit(this);" />
</div>
JS:
function nextElement(current)
{
do
current = current.nextSibling;
while (current && current.nodeType != 1);
return current;
}
function evalonsubmit(elem)
{
if(elem.value == -1)
while(elem = nextElement(elem)) {
elem.disabled = true;
elem.value = -1
}
else if(elem = nextElement(elem))
elem.disabled = false;
}
That removes the need for ids on the <select> elements, as following elements can be grabbed with .nextSibling. The nextElement() function is to avoid grabbing text nodes.