I have a variable that is supposed to hold a running total. On each pass of this loop, and amount should be added to the running total. I must be missing something, since I get either undefined or NaN.
$('#btnSubmit').click(function(e) {
var totalSqft;
$('.fieldset').each(function() {
var sqft;
var width = $(this).find('input:eq(0)').val();
var height = $(this).find('input:eq(1)').val();
var type = $(this).find('select').val();
if (type == 'tri') {
sqft = (width * height) / 2;
} else {
sqft = (width * height);
};
totalSqft += sqft;
alert('this ' + type + ' is ' + width + ' wide and ' + height + ' high, for a total of ' + sqft + ' square feet');
});
alert('Done. Total Sq Ft is ' + totalSqft);
})
You need to initialize the value to 0:
var totalSqft = 0;
Otherwise, it gets initialized to undefined, and undefined + a number is NaN.
Related
I'm working on a leaflet js map atm.
There are some items that I want to apply a class to, depending on their inner text. Seems as though two circles at a certain size just overlap. Adding some CSS in that case so they're no longer overlapping.
//function searches for all <text> elements within svg tags for the queryText
// and then appends them with the appendText
function addClasserino() {
let elements = document.querySelectorAll('map-marker marker-bg-condition'); // get all circle elements as a NodeList
elements.forEach(el => { // go through each text element
if (el.innerText < 10) { // if the innerHTML matches the query HTML then
elements.addClass('updated'); // add the class
}
})
}
document.addEventListener("DOMContentLoaded", function(){
//pass in the search text and the appending text as arguments
addClasserino();
});
This is what I got so far. Doesn't seem to be working.
.map-marker.marker-bg-condition needs to be moved across a bit. Got the CSS here:
.map-marker.marker-bg-condition.updated{
margin-top: -19px;
margin-left: -19px;
}
With Leaflet JS, the zoom level changes and items are updated accordingly. This of my map showing all details at the world view, and then breaking down to state as you zoom in.
The unexpected behavior is that the css isn't applying and where bubbles are overlapping is because of this. This is the original code but I can't change it and get it to work even with an if statement.
getMarkerHtml: function(count, color) {
var size = this.getMarkerSize(count);
var hsize = (size / 2) - 6;
var font = count < 1000 ? Math.ceil(size / 3) : Math.ceil(size / 4);
if(count < 100) {
font = font + 3;
}
var cluster_classes = [
'map-marker',
'marker-bg-' + (Filters.colors.profile === color ? 'profile' : 'condition')
];
if(this.zoomLevel !== 'zip') {
size = size * 1.5;
if(petMapFilters.colors.profile !== color) {
hsize = size / 2;
}
}
if(this.zoomLevel === 'zip') {
var cluster_styles = [
'margin-left: -' + hsize + 80 + 'px;', NOTE: I tried this to offset on zip zoom bit it's not working END OF NOTE
'margin-top: -' + hsize + 80 +'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];
} else {
var cluster_styles = [
'margin-left: -' + hsize + 'px;',
'margin-top: -' + hsize + 'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];};
var div_style = [
'line-height: ' + (size - (size * 0.3)) + 'px;'
];
count = this.formatCount(count);
return '<div class="' + cluster_classes.join(' ') + '" tabindex="0" style="' + cluster_styles.join(' ') + '"><div style="' + div_style.join(' ') + '">' + count + '</div></div>';
},
Please let me know what I am doing wrong here as I am not able to identify this myself.
The issue at hand:
Thanks.
This works tell I hit the tax function. Then I start getting
nan and undefined errors. Cant figure out why the tax function is not picking up the code from the other functions.
/ Saturday May 27 2017
{
// Global variables
var orderCount = 0;
var takeOrder = function (topping, crustType) {
// add one to order count
orderCount = orderCount + 1
return('Order: ' + crustType + ' pizza topped with ' + topping );
}
var getSubTotal = function(itemCount){
var subTatal = (itemCount * 7.5);
return (subTatal + ' subtotal of ' + ' itemCount ' + (itemCount));
}
var getTax = function (){
var subTatal = subTatal * 0.06;
// getTheTax = (subTatal * 0.06)
return subTatal + ' with tax of ' + (subTatal)
}
var getTotal = function (){
var myTotal = getSubTotal + getTax;
return ' tax ' + getTax + 'plus subtotal ' + getSubTotal() + ' is ' + (myTotal);
}
console.log(takeOrder('bacon', 'thin crust'));
console.log(takeOrder('cheese', 'thick crust'));
console.log(takeOrder('pepperoni', 'medium crust'));
console.log(getSubTotal(10));
console.log(' getTax ' + getTax());
console.log(getTotal());
}
This is the corrected version of your code.
var takeOrder = function(topping, crustType) {
console.log('Order: ' + crustType + ' pizza topped with ' + topping);
return 1;
}
var getSubTotal = function(orderCount) {
var subTotal = (orderCount * 7.5);
console.log('Subtotal of ' + subTotal.toFixed(2) + ' with item count ' + orderCount);
return subTotal;
}
var getTax = function(subTotal) {
var tax = subTotal * 0.06;
console.log('Tax is ' + tax.toFixed(2));
return tax;
}
var getTotal = function(subTotal, tax) {
var total = subTotal + tax;
console.log('Total is ' + total.toFixed(2));
return total;
}
var orderCount = 0;
orderCount += takeOrder(orderCount, 'bacon', 'thin crust');
orderCount += takeOrder('cheese', 'thick crust');
orderCount += takeOrder('pepperoni', 'medium crust');
var subTotal = getSubTotal(orderCount);
var tax = getTax(subTotal);
var total = getTotal(subTotal, tax);
Summary of corrections
Made functions return Number rather than String
Now all functions are almost pure functions (don't cause side-effects other than logging)
Formatted numbers prior to printing them by rounding them to the second decimal
Fixed typographic errors (tatal rather than total).
Added parenthesis to function invocations (e.g: getTax() rather than getTax
Removed redundant invocations
More
you are defining a variable, and assigning into it it's value times something.
var subTatal = subTatal * 0.06;
In this case, subTatal does not have a value.
I think you should read about variables and scopes.
Read the link below:
https://www.w3schools.com/js/js_scope.asp
Your both function is returning the string :
....
return subTatal + ' with tax of ' + (subTatal)
...
return ' tax ' + getTax + 'plus subtotal ' + getSubTotal() + ' is ' + (myTotal);
You can go through this blog for converting strings to number:
https://coderwall.com/p/5tlhmw/converting-strings-to-number-in-javascript-pitfalls
Please make sure the what is the type of value you want to be returned form the function to use it.
var subTatal = subTatal * 0.06;
is equivalent of
var subTatal = undefined;
subTatal = subTatal * 0.06;
note, this subTatal is not the same as the one defined outside the function (learn scope)
If you create a variable inside a function it will exists only inside that function, so if you call that variable from inside another it will be undefined.
There are two ways:
declare these variables as global at the top of your code just like orderCount
functions can have inputs and output, so you can pass to a function the variable you need and ask it to return the result, which can be saved into a variable and later used.
For example:
function getSubtotal(orderCount) {
var subtotal = //do something
return subtotal }
function getTax(subtotal) {
var tax = //calculate tax
return tax }
var subtotal = getSubtotal(orderCount)
var tax = getTax(subtotal)
I'm having trouble updating the total when I change the "Complete E-Book" product quantity. When I first set the quantity and add it to basket it shows the correct total within the basket but when I change the quantity it adds on to the previous total. Overall I want to be able to add multiple products to the basket total (reason for x += p2Total (x var is what holds the total - Line 86) but while allowing for the Quantity of the product to be changed and then updated in the total.
Codepen Here >
Products in question are the top 2
JS:
// JQuery Functions for NavBar - Class Toggle
(function() {
$('.hamburger-menu').on('click', function() {
$('.bar').toggleClass('animate');
})
})();
(function() {
$('.hamburger-menu').on('click', function() {
$('.bar2').toggleClass('ApprDown');
})
})();
/*
START OF BASKET
START OF BASKET
*/
// Get access to add to basket basket button
var addToBasket = document.querySelector('.atbb');
addToBasket.addEventListener('click', P1);
// Formatter simply formats the output into a currceny format istead of a general number format. This is using the ECMAScript Internationalization API
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'GBP',
minimumFractionDigits: 2,
});
var totalBasket
var discountLimit = 10
var discount = 3.50
var x = 0.00
// One big function with different condtions based on the differnt products and then simply concatinate the values where needed
function P1() {
var y = document.getElementById("p1Quant").value;
if (+y > discountLimit) {
var z = 15.000
x = parseFloat(+y) * parseFloat(+z); // + will convert the vars into Numbers etc
document.getElementById("BasketSumData").innerHTML = ("Sub Total: ") + formatter.format(x) + ("<br/>") + ("<hr />") + ("<div class='strike'>Plus £3.50 Delivery</div>") + ("<br/>") + ("<hr />") + ("Total: ") + formatter.format(x)
// Jquery Notificaiton
var truckVar = document.getElementById("truck");
truckVar.setAttribute("class", "animateTruck");
} else if (+y <= 0) {
document.getElementById("BasketSumData").innerHTML = ("Sub Total: ") + formatter.format(0) + ("<br/>") + ("Total: ") + formatter.format(0)
} else {
var z = 15.000
var s = 15.000
x = parseFloat(+y) * parseFloat(+z) + 3.50
var sub = parseFloat(+y) * parseFloat(+s)
document.getElementById("BasketSumData").innerHTML = ("Sub Total: ") + formatter.format(sub) + ("<br/>") + ("<hr />") + ("Plus £3.50 Delivery") + ("<br/>") + ("<hr />") + ("Total: ") + formatter.format(x)
}
}
var addToBasket2 = document.querySelector('.atbb2');
addToBasket2.addEventListener('click', P2);
function P2() {
p2Total = 0.00
var y = document.getElementById("p2Quant").value;
var p2 = 8.00
var p2Total = parseFloat(+y) * parseFloat(+p2); // + will convert the vars into Numbers etc
// var totalBasket = + x + x // javascript add value onto set var
x += p2Total // Append the amount to the basket
document.getElementById("BasketSumData").innerHTML = ("Sub Total: ") + formatter.format(x) + ("<br/>") + ("<hr />") + ("<div class='strike'>Plus £3.50 Delivery</div>") + ("<br/>") + ("<hr />") + ("Total: ") + formatter.format(x)
if (+y <= 0) {
p2Total = 0.00
}
}
Don't add the value to x, add x and p2Total into a new temporary value that is scoped to the function itself and use that.
var tmp_total = x + p2Total;
document.getElementById("BasketSumData").innerHTML = ("Sub Total: ") + formatter.format(tmp_total) + ("<br/>") + ("<hr />") + ("<div class='strike'>Plus £3.50 Delivery</div>") + ("<br/>") + ("<hr />") + ("Total: ") + formatter.format(tmp_total)
EDIT - I don't think I explained it very well the first time.
I have a lot of data - it's in an Array, with each item in the array being an object. In the system I am working in (a control system for A/V devices, which uses JavaScript as the programming language), I am generating buttons based on the length of the array. I want to be able to position a button, and essentially know the X and Y coordinates for each button in the array - with X and Y being Row/Column. (which I then translate to a X/Y pixel position on my UI.
My initial code, which is below, is within a for loop, and I manually calculated the button position. But this is tedious, as I use this same function to show off different groups/sizes of buttons.
Anywhere there is mirage.log = console.log.
The code below is part of a For Loop
button.element.style.position = 'absolute'; //Do to all Buttons.
if (i == 0) //First Item
{
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = btn_Info.startTop + 'px';
}
else if (i <= btn_Info.numRow-1) //First Column.
{
mirage.log('Setting Position of First Column');
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * i + btn_Info.startTop + 'px';
}
else if (i > btn_Info.numRow - 1 && i <= btn_Info.numRow * 2 - 1)
{
mirage.log('Setting Second column ' + i);
button.element.style.left = btn_Info.startLeft + btn_Info.width + btn_Info.hOffset + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i-btn_Info.numRow) + btn_Info.startTop + 'px';
}
else
{
mirage.log('Setting Third column ' + i);
button.element.style.left = btn_Info.startLeft + ((btn_Info.width + btn_Info.hOffset)*2) + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i - (btn_Info.numRow*2)) + btn_Info.startTop + 'px';
}
Thanks in advance for the help - I have grabbed so many answers from this forum over the last year, you guys are awesome!
EDIT -
I was able to get some adjustment if I generate rows first then columns:
I was able to get a little close with the help of a friend, and be able to adjust for a 2 column layout by doing the following:
encoder = {
'buttonVals':{'width':125,'height':50,'numCols':2,'numRows':null;'vOffset':10,'hOffset':10}
var posLeft;
var posTop;
posLeft = (i % encoder.buttonVals.numCols) * (encoder.buttonVals.width + encoder.buttonVals.hOffset) + encoder.buttonVals.startLeft;
posTop = Math.floor(i / encoder.buttonVals.numCols) * (encoder.buttonVals.height + encoder.buttonVals.vOffset) + encoder.buttonVals.startTop;
After working on this for a bit - here is the code that I got to work. This prints out both the row position, and the column position.
testFunction = function(incRow, incCol){
var myFunc = {
'testLength':0,
'numRows':incRow,
'numCols':incCol,
'array':[],
};
myFunc.testLength = incRow * incCol;
for(var c=0, posCol = 0, posRow = 0; c < myFunc.testLength; c++)
{
var whichRow;
posRow = Math.floor(c/myFunc.numRows);
whichRow = Math.floor(c/myFunc.numRows) + c;
if (whichRow > myFunc.numRows)
{
whichRow = whichRow - (myFunc.numRows * posRow) - posRow;
if (whichRow === 0)
{
posCol = posCol + 1;
}
}
console.log(c + ' : ' + whichRow + ' : ' + posCol);
}
};
testFunction(6,4);
Everything runs correctly, but I want to add a few things. At the very end of the function I want to change the height of the canvas by comparing how many you got correct out of the amount that you wanted to answer, but with a percentage. Sorry if this is difficult to understand.
JavaScript:
<script type="text/javascript">
function myFunction() {
score = 0;
questionAmount = prompt('How many question would you like to solve?');
for(i = 0; i < questionAmount; i++) {
var x = Math.floor(Math.random() * 13);
var y = Math.floor(Math.random() * 13);
question = prompt('What is ' + x + ' * ' + y + ' = ?');
if(question == null || isNaN(question)) {
break;
}
if(question == x * y) {
score++;
}
}
alert('You got ' + score + ' out of ' + questionAmount + ' correct.');
}
</script>
HTML:
<canvas id="content"></canvas>
<br />
<button onclick="myFunction()">CLICK</button>
Just create the percentage and apply it:
var correctPercent = (parseDouble(score) / parseDouble(questionAmount)) * 100;
//change the target elements style, apply above variable
document.getElementById("content").style.height = correctPercent + "%";