I've the following code to calculate the percentage of each element (like poll voting system):
$(document).ready(function() {
$("#percentage").click(function() {
var number, sumNumbers = 0, newPercent;
$(".item").each(function() {
number = $(this).children(".itemNum").text();
number = +number;
sumNumbers += number;
if(sumNumbers != 0) {
newPercent = (number / sumNumbers) * 100;
} else {
newPercent = 0;
}
$(this).children(".percentage").text(newPercent+"%");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item">
<span class="itemNum">0</span> <span class="percentage"></span>
</div>
<div class="item">
<span class="itemNum">2</span> <span class="percentage"></span>
</div>
<div class="item">
<span class="itemNum">1</span> <span class="percentage"></span>
</div>
<button id="percentage">Calculate Percentage!</button>
But, the result is:
0 0%
2 100%
1 33.33333333333333%
So, how to calculate return the following result?
0 0%
2 66.66666666666667%
1 33.33333333333333%
I need these results to do a progress bar on my poll system, so, how to do this?
You need to parse the text to integer via parseInt() function.
And you need first to sum numbers and then you can calculate percentage.
For one loop question:
You can't count percentage in one loop. Explained here
$(document).ready(function() {
$("#percentage").click(function() {
var number, sumNumbers = 0, newPercent;
$(".item").each(function(){
number = $(this).children(".itemNum").text();
sumNumbers += parseInt(number);
});
$(".item").each(function() {
number = parseInt($(this).children(".itemNum").text());
if(sumNumbers != 0) {
newPercent = (number / sumNumbers) * 100;
} else {
newPercent = 0;
}
$(this).children(".percentage").text(newPercent+"%");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item">
<span class="itemNum">0</span> <span class="percentage"></span>
</div>
<div class="item">
<span class="itemNum">2</span> <span class="percentage"></span>
</div>
<div class="item">
<span class="itemNum">1</span> <span class="percentage"></span>
</div>
<button id="percentage">Calculate Percentage!</button>
Related
I have this short bit of code to sort / ascend div by number. But I want to add other conditions to sort by. Right now, it's only sorting it just based on points class. But I want it to also apply conditions on times and combine with points.
Generally these divs sort ascend from large number to low number. If the number is equal, it will show those whose time is less. If the number is equal, it will search to see which times is the lowest. And it will show it First.
$(function(){
var sortedList = $('.contest_entry').toArray().sort(function(lhs, rhs){
return parseInt($(rhs).children("span.points").text(),10) - parseInt($(lhs).children("span.points").text(),10);
});
$("#list").html(sortedList);
});
.contest_entry
{
padding:10px;
background: #eee;
margin:10px 0px;
}
.points
{
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<div id="list">
<div class="contest_entry">
<span class="points">14</span>
<span class="times"> 12:39 </span>
</div>
<div class="contest_entry">
<span class="points">16</span>
<span class="times"> 09:55 </span>
</div>
<div class="contest_entry">
<span class="points">19</span>
<span class="times"> 17:19 </span>
</div>
<div class="contest_entry">
<span class="points">19</span>
<span class="times"> 17:34 </span>
</div>
<div class="contest_entry">
<span class="points">19</span>
<span class="times"> 17:20 </span>
</div>
</div>
In summary, I want to add multiple conditions to filter or sort the divs.
Try this code please
$(function(){
var sortedList = $('.contest_entry').toArray().sort(function(lhs, rhs){
var lhsPoints = parseInt($(lhs).find(".child span.points").text(),10);
var rhsPoints = parseInt($(rhs).find(".child span.points").text(),10);
if (lhsPoints === rhsPoints) {
// Compare the "times" class if the "points" class is equal
return $(lhs).find(".child span.times").text() > $(rhs).find(".child span.times").text() ? 1 : -1;
} else {
return rhsPoints - lhsPoints;
}
});
$("#list").html(sortedList);
});
Try this script please
$(function(){
var sortedList = $('.contest_entry').toArray().sort(function(lhs, rhs){
var lhsPoints = parseInt($(lhs).children("span.points").text(),10);
var rhsPoints = parseInt($(rhs).children("span.points").text(),10);
if (lhsPoints === rhsPoints) {
// Compare the "times" class if the "points" class is equal
return $(lhs).children("span.times").text() > $(rhs).children("span.times").text() ? 1 : -1;
} else {
return rhsPoints - lhsPoints;
}
});
$("#list").html(sortedList);
});
I have been working on a counter for a webpage and I had been stuck with this function that I can't solve.
I have a counter for 4 divs and since two of them are small numbers and the other two are big numbers the first ones run soo fast that I can't see them to the function.
Someone knows how to set the js function so that they can run at a different speed, and finish at the same time?
let section_counter = document.querySelector('#section_counter');
let counters = document.querySelectorAll('.counter-item .counter');
// Scroll Animation
let CounterObserver = new IntersectionObserver(
(entries, observer) => {
let [entry] = entries;
if (!entry.isIntersecting) return;
let speed = 1000;
counters.forEach((counter, index) => {
function UpdateCounter() {
const targetNumber = +counter.dataset.target;
const initialNumber = +counter.innerText;
const incPerCount = targetNumber / speed;
if (initialNumber < targetNumber) {
counter.innerText = Math.ceil(initialNumber + incPerCount);
setTimeout(UpdateCounter, 50);
}
}
UpdateCounter();
if (counter.parentElement.style.animation) {
counter.parentElement.style.animation = '';
} else {
counter.parentElement.style.animation = `slide-up 0.3s ease forwards ${
index / counters.length + 0.5
}s`;
}
});
observer.unobserve(section_counter);
},
{
root: null,
threshold: window.innerWidth > 768 ? 0.4 : 0.3,
}
);
CounterObserver.observe(section_counter);
<section id="section_counter">
<div class="container">
<h1 class="section-heading">For every set, you purchase of our sustainable wear, you are helping the world save: </h1>
</div>
<div class="container">
<div class="counter-grid">
<div class="counter-item">
<h1 class="counter" data-target="15">0</h1>
<h2 class="counter-heading">Plastic bottles</h2>
<div class="counter-text">Which takes up to 150 years to decompose</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="22">0</h1>
<h2 class="counter-heading">KW of energy</h2>
<div class="counter-text">Equivalent to 1-day household consumption</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="5900">0</h1>
<h2 class="counter-heading">Liters of water</h2>
<div class="counter-text">Equivalent to the daily consumption of 16 persons (Mexico average)</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="9000">0</h1>
<h2 class="counter-heading">Grams of Co2 emissions</h2>
<div class="counter-text">Equivalent to a 90 km car consumption</div>
</div>
</div>
</div>
</section>
Try this solution with using additional attribute data-count. The logic is a simple: we store the calculation with the decimal value in data-count and put only an integer inside, remove data-count at the end.
let section_counter = document.querySelector('#section_counter');
let counters = document.querySelectorAll('.counter-item .counter');
// Scroll Animation
let CounterObserver = new IntersectionObserver(
(entries, observer) => {
let [entry] = entries;
if (!entry.isIntersecting) return;
let speed = 1000;
counters.forEach((counter, index) => {
const targetNumber = +counter.dataset.target;
// Find the unit for one counter step
const count = targetNumber / speed;
// Set data attribute for accurate calculation with decimal
counter.setAttribute('data-count', 0);
function UpdateCounter() {
const initialNumber = +counter.innerText;
// Get decimal number to calculate
const countNumber = +counter.dataset.count;
// Getting an integer value with Math.floor()
const integer = Math.floor(countNumber);
if (initialNumber < targetNumber) {
// Set decimal number / toFixed() with speed length, to increase accuracy
counter.setAttribute('data-count', (countNumber + count).toFixed(`${speed}`.length));
// Set integer number
counter.innerText = integer;
setTimeout(UpdateCounter, 50);
} else {
// remove additional data attribute
counter.removeAttribute('data-count');
}
}
UpdateCounter();
if (counter.parentElement.style.animation) {
counter.parentElement.style.animation = '';
} else {
counter.parentElement.style.animation = `slide-up 0.3s ease forwards ${
index / counters.length + 0.5
}s`;
}
});
observer.unobserve(section_counter);
}, {
root: null,
threshold: window.innerWidth > 768 ? 0.4 : 0.3,
}
);
CounterObserver.observe(section_counter);
<section id="section_counter">
<div class="container">
<h1 class="section-heading">
For every set, you purchase of our sustainable wear, you are helping the world save:
</h1>
</div>
<div class="container">
<div class="counter-grid">
<div class="counter-item">
<h1 class="counter" data-target="15">0</h1>
<h2 class="counter-heading">Plastic bottles</h2>
<div class="counter-text">Which takes up to 150 years to decompose</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="22">0</h1>
<h2 class="counter-heading">KW of energy</h2>
<div class="counter-text">Equivalent to 1-day household consumption</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="5900">0</h1>
<h2 class="counter-heading">Liters of water</h2>
<div class="counter-text">
Equivalent to the daily consumption of 16 persons (Mexico average)
</div>
</div>
<div class="counter-item">
<h1 class="counter" data-target="9000">0</h1>
<h2 class="counter-heading">Grams of Co2 emissions</h2>
<div class="counter-text">Equivalent to a 90 km car consumption</div>
</div>
</div>
</div>
</section>
I want to add class 'active' to next div 1 second before first is removed.
Practically, I want to have an 'active' class on 2 elements at the same time for that 1 second.
Can someone help me?
Thanks
<div class="map-inner">
<div class="map-location-outer">
<div class="map-location-inner location1 active">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon2.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location2">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon3.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location3">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon1.png">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
</div>
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
a.removeClass("active");
a = a.parent().next(".map-location-outer");
if (a.length == 0)
a = $(".map-location-outer").first();
a.find(".map-location-inner").addClass("active");
}
setInterval(function () {
updateClass();
}, x * 5500);
You can use setTimeout to wait before removing 1st .active class and add 2nd .active class before removing 1st one.
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
let b = a.parent().next(".map-location-outer");
if (b.length == 0)
b = $(".map-location-outer").first();
b.find(".map-location-inner").addClass("active");
setTimeout(function() {
a.removeClass("active");
}, 1000);
}
setInterval(function () {
updateClass();
}, x * 5500);
I'm looking to acquire a grand total of all product input field values that are dynamically generated when a user clicks on either the plus or minus button which, for that, adds the total price for each product.
Any help is greatly appreciated. This is what I have so far:
JS
$(function() {
$('.service_product-item').each(function() {
var thisEl = $(this),
btnPlus = thisEl.find('.service_btn-plus'),
btnMinus = thisEl.find('.service_btn-minus'),
fieldQtt = thisEl.find('input[name="service-qt1"],input[name="service-qt2"]'),
itemPriceEl = thisEl.find('.service_item-price'),
price = itemPriceEl.data('price');
// Add Products & Products Price
btnPlus.on('click', function() {
qttValue = parseInt(fieldQtt.val());
fieldQtt.val(qttValue + 1);
itemPriceEl.html('$' + (qttValue + 1) * price);
});
// Subtract Products & Products Price
btnMinus.on('click', function() {
qttValue = parseInt(fieldQtt.val()) - 1;
var newQTT = (qttValue <= 0) ? 0 : qttValue;
fieldQtt.val(newQTT);
itemPriceEl.html('$' + newQTT * price);
});
});
});
HTML
<div class="service_products_and_services_wrapper">
<div class="service_product-items">
<div class="service_product-item">
<div class="service_item-wrap">
<img src="http://www.kinyu-z.net/data/wallpapers/27/796765.png" alt="QT1" title="" />
<div class="service_wrap-qtt">
<div class="service_wrap-qtt-field-qtt">
<input class="service_field-qtt" name="service-qt1" value="0" readonly="" />
</div>
<div class="service_wrap-qtt-minus-plus">
<div class="service_btn-cart-qtt service_btn-plus">+</div>
<div class="service_btn-cart-qtt service_btn-minus">-</div>
</div>
</div>
</div>
<div class="service_item-info">
<div class="service_item-title">QT1<br>
<span style="font-size: .7em; text-transform: none;">($5 per item)</span>
</div>
<div class="service_item-price" data-price="5">$0</div>
</div>
</div>
<div class="service_product-item">
<div class="service_item-wrap">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIuVn6ZXHwQiFC0IlB1N_CxbXo6-5x1A4yqspYsxUUb0Xjmu8L" alt="QT2" title="" />
<div class="service_wrap-qtt">
<div class="service_wrap-qtt-field-qtt">
<input class="service_field-qtt" name="service-qt2" value="0" readonly="" />
</div>
<div class="service_wrap-qtt-minus-plus">
<div class="service_btn-cart-qtt service_btn-plus">+</div>
<div class="service_btn-cart-qtt service_btn-minus">-</div>
</div>
</div>
</div>
<div class="service_item-info">
<div class="service_item-title">QT2<br>
<span style="font-size: .7em; text-transform: none;">($10 per item)</span>
</div>
<div class="service_item-price" data-price="10">$0</div>
</div>
</div>
</div>
<p style="margin-top: 40px;">Grand Total: $0</p>
</div>
and here is a DEMO
There are some issues with the problem statement. Main one is that you don't really have any model defined for your application and your html acts as a data model as well, and important data is scoped to the event handlers. Also it is not clear what is the initial state of that application. So I just modify your code a bit.
One simple approach just to show how it could be done is following:
have a global total
with each minus and plus update the value accordingly
https://jsfiddle.net/Lyxceu3s/43/
var total = 0;
$(function() {
$('.service_product-item').each(function() {
var thisEl = $(this),
btnPlus = thisEl.find('.service_btn-plus'),
btnMinus = thisEl.find('.service_btn-minus'),
fieldQtt = thisEl.find('input[name="service-qt1"],input[name="service-qt2"]'),
itemPriceEl = thisEl.find('.service_item-price'),
price = itemPriceEl.data('price');
// Add Products & Products Price
btnPlus.on('click', function() {
qttValue = parseInt(fieldQtt.val());
fieldQtt.val(qttValue + 1);
total = total + price;
itemPriceEl.html('$' + (qttValue + 1) * price);
$('#idGT').html(total);
});
// Subtract Products & Products Price
btnMinus.on('click', function() {
qttValue = parseInt(fieldQtt.val()) - 1;
if(qttValue >= 0){
total = total - price;
}
var newQTT = (qttValue <= 0) ? 0 : qttValue;
fieldQtt.val(newQTT);
itemPriceEl.html('$' + newQTT * price);
$('#idGT').html(total);
});
});
});
And that would also require a little modification to your html:
<p style="margin-top: 40px;">Grand Total: $<span id="idGT">0</span></p>
Note: that in case of a minus, you have to check that quantity is above or 0 before you conditionally reset it to 0.
As a general note, you might want to separate your models from your views. Check the following SO thread for a digest: "Hello World" in MVC Pattern
Updated the fiddle. Made few changes to it
Please take a look at it and let me know if thats what you are looking for.
https://jsfiddle.net/Lyxceu3s/35/
var firstTotal = $('input[name="service-qt2"]').val() * 10 ;
var secondTotal = $('input[name="service-qt1"]').val() * 5;
$('#grandTotal').html(firstTotal + secondTotal)
I have the following html:
<div class="balance">
<div class="heading">
<p class="total"><span>00</span></p>
</div>
<div class="instance withdrawal">
<h3>Random</h3>
<p>desc</p>
<p class="amount">$350.<span>00</span></p>
</div>
<div class="instance deposit">
<h3>Added in</h3>
<p>desc</p>
<p class="amount">$1,250.<span>00</span></p>
</div>
<div class="instance withdrawal">
<h3>Bill</h3>
<p>desc</p>
<p class="amount">$50.<span>00</span></p>
</div>
</div>
<!--end wallet-container left-->
How can i use jQuery to add take total deposits, subtract the withdrawals and append it to the p.total?
Try this fiddle.
Edited to take floating points into account.
JS
$(function() {
var total = 0;
// Check each instance
$('.instance').each(function() {
var
$this = $(this),
clone = $this.find('.amount').clone(),
amount = 0,
floating = 0;
// Get floating point
floating = parseFloat('0.' + clone.find('span').text());
clone.find('span').remove();
// Get integer amount
amount = parseInt(clone.text().replace(/\D+/gim, ''), 10);
if (!isNaN(amount) && amount > 0) {
if ($this.is('.deposit')) total += (amount + floating); // Deposit
else if ($this.is('.withdrawal')) total -= (amount + floating); // Withdrawal
}
});
// Format total with commas
var formatted = ('' + parseInt(total, 10)).split('').reverse().join('');
formatted = formatted.replace(/(\d{3})/gim, '$1,');
formatted = formatted.split('').reverse();
if (formatted[0] == ',') formatted.shift();
formatted = formatted.join('');
$('.total').text('$' + parseInt(formatted, 10) + '.');
var decimal = (total - parseInt(total, 10)) * 100;
$('.total').append('<span>' + decimal + '</span>')
});
Try adjusting html slightly by placing $ character before first span element containing whole number including second sibling span element containing decimal number as descendants of .deposit , .withdrawal elements; utilizing data-* attribute to reference object containing withdrawal , deposit, total properties; Array.prototype.reduce() ; Number() ; String.prototype.replace() for comma , character ; .each()
var res = {
deposit: 0,
withdrawal: 0,
total: 0
};
function calculate(el) {
return el.get().reduce(function(a, b) {
return Number(a.textContent.replace(/,/g, "")) + Number(b.textContent)
})
}
$(".deposit, .withdrawal").each(function(i, el) {
res[$(el).data().type] += calculate($("span", el))
})
res.total = res.deposit - res.withdrawal;
$(".total span").html(res.total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div class="balance">
<div class="heading">
<p class="total" data-type="total"><span>00</span>
</p>
</div>
<div class="instance withdrawal" data-type="withdrawal">
<h3>Random</h3>
<p>desc</p>
<p class="amount">$<span>350</span><span>.00</span>
</p>
</div>
<div class="instance deposit" data-type="deposit">
<h3>Added in</h3>
<p>desc</p>
<p class="amount">$<span>1,250</span><span>.00</span>
</p>
</div>
<div class="instance withdrawal" data-type="withdrawal">
<h3>Bill</h3>
<p>desc</p>
<p class="amount">$<span>50</span><span>.00</span>
</p>
</div>
</div>
<!--end wallet-container left-->