I have some divs that have values. I want to sum in one <h3>
The probem in my code is that I get the last div value and cannot sum the other.
Html code:
<div class="cart-footer">
<div class="order-tools">
<h3 id="total">
</h3>
</div>
<div class="cash-out">
</div>
</div>
Jquery:
var sum = 0;
$('#item-total').each(function(){
var val = $.trim($(this).text());
if (val) {
val = parseFloat(val.replace(/^\$/, ""));
sum += !isNaN(val) ? val : 0;
}
});
$("#total").html(sum + "$");
You can see #item-total in this code:
$(".cart-body").append(function(){
return "<div id='cart-list'><div class='product-name'>"+personObject.name+"</div><div class='product-tools'><input type='number' data-id='1' value='1' min='1'></input><label id='price'>Price: "+personObject.price+"</label><label data-value='"+personObject.count * personObject.price+"' id='item-total'>"+personObject.count * personObject.price+"</label></div></div>";
});
You are dealing with a logic error in your code. What you are doing incorrectly is looping through $('#item-total'). This is wrong because #item-total is selecting a single unique HTML element.
What you want to do is loop through all the elements using a different selector. For example by replacing in your HTML: <h3 id="total"> into <h3 class="total">.
Now in your JQuery, selecting $('.total') would then select all instances of .total tagged HTML elements.
var items = $('.item'),
cashOut = $('#cash-out'),
sum = 0;
$.each(items, function(value) {
// items[value] will contain an HTML element, representing an 'item'.
var itemValue = parseFloat(items[value].innerHTML);
sum += !isNaN(itemValue) ? itemValue : 0;
});
cashOut.html('Total: $' + sum);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cart-footer">
<div class="order-tools">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
</div>
<div id="cash-out">0</div>
Related
This question already has answers here:
How can I assign a unique ID to all div's that have a specific class using JQuery
(4 answers)
Closed 3 years ago.
I was wondering if there's simple JS/JQuery to change the div ids inside the container from 'one' to unique ids (like 'one_1', 'one_2', 'one_3')
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
Desired Output
<div id="container">
<div id="one_1">ONE</div>
<div id="one_2">ONE</div>
<div id="one_3">ONE</div>
</div>
I've gotten so far as to extract the three divs, but now need to replace the text:
document.getElementById("container").querySelectorAll("#one")
You could just loop over the container's children and update their IDs:
var children = document.getElementById('container').children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
child.id = child.id + "_" + (i + 1);
}
You may use the version of .attr() which takes a function as its second parameter:
jQuery(($) => {
$('#container > div').attr('id', (index, id) => `${id}_${index + 1}`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
Or, if you can't use ES6+ Javascript:
jQuery(function ($) {
$('#container > div').attr('id', function (index, id) {
return id + '_' + (index + 1);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
jQuery solution:
$("#container div").each(function( index ) {
this.id = this.id+"_"+(index+1);
});
Single line (thanks to Andreas's comment)
$("#container div").attr("id", (index, oldId) => oldId + "_" + (index + 1))
$(".changer").on("click",function(){
var i = 1;
$("#container").children().each(function(){
var id = this.id;
$(this).attr("id",(id + "_" + i));
i++;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
<button class="changer">
Change IDs
</button>
I have a tag like below:
<section id="sec">
<div id="item1">item1</div>
<div id="item2">item2</div>
<div id="item3">item3</div>
<div id="abcitem1">abcitem1</div>
</section>
I want to check how many div tags contextText start with item. May I know is there any easier way that writes for condition and count them one by one(like Jquery)?
Use .filter() to filtering selected elements and use regex in .match() to check existence of item in element text.
var count = $("#sec div").filter(function(){
return $(this).text().match(/^item/);
}).length;
console.log(count);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="sec">
<div id="item1">item1</div>
<div id="item2">item2</div>
<div id="item3">item3</div>
<div id="abcitem1">abcitem1</div>
</section>
var res=0;
$( "#sec div" ).each(function( index ) {
var str= $(this).text() ;
if(str.startsWith("item")==true){
res++;
}
});
console.log(res); //returns 3
You could use reduce function to get the occurrence of elements which start with 'item'.
This is a native javascript solution, which uses startsWith, so you do not have to mess around with regular expressions.
var childDivs = document.getElementById('sec')
.getElementsByTagName('div');
var counter = Array.from(childDivs)
.reduce((accumulator, currentValue) => {
if (currentValue.innerHTML.startsWith('item')) {
return accumulator = accumulator + 1;
}
return accumulator;
}, 0);
console.log( counter );
<section id="sec">
<div id="item1">item1</div>
<div id="item2">item2</div>
<div id="item3">item3</div>
<div id="abcitem1">abcitem1</div>
</section>
Without any jQuery or regex
var nodes = document.querySelectorAll('#sec div')
var count = 0
nodes.forEach(node => count += node.innerText.startsWith('item'))
console.log(count)
<section id="sec">
<div id="item1">item1</div>
<div id="item2">item2</div>
<div id="item3">item3</div>
<div id="abcitem1">abcitem1</div>
</section>
it's possible to add booleans to a number, true means 1 and false means 0
Here is a pure JS way to count it.
function checkItemsCount(section) {
if (!section) return 0;
const sec = document.querySelector(section);
const items = sec.querySelectorAll('div');
let count = 0;
for (let i = 0; i < items.length; i++) {
if (/^item/.test(items[i].innerText)) count++;
}
return count;
}
console.log(checkItemsCount('#sec'));
<section id="sec">
<div id="item1">item1</div>
<div id="item2">item2</div>
<div id="item3">item3</div>
<div id="abcitem1">abcitem1</div>
</section>
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-->
I have the following list of divs and I'd like to be able to sort them using Javascript / JQuery.
<div class="item">
<div class="genre">Classical</div>
<div class="name">Alpha</div>
<div class="location">London</div>
</div>
<div class="item">
<div class="genre">Blues</div>
<div class="name">Bravo</div>
<div class="location">New York</div>
</div>
<div class="item">
<div class="genre">Pop</div>
<div class="name">Charlie</div>
<div class="location">Paris</div>
</div>
<div class="buttons">
Sort by Genre
Sort by Name
Sort by Location
</div>
I'd like to be able to sort the items by their Genre/Name/Location alphabetically.
Example: If Sort by Genre was clicked, it would sort the items in 0-9 A-Z by Genre.
If any of you have any tips it would greatly be appreciated.
Cheers :)
You have to make a little change to html like following:
<div id="container">
<div class="item">
<div class="genre">Classical</div>
<div class="name">Alpha</div>
<div class="location">London</div>
</div>
<div class="item">
<div class="genre">Blues</div>
<div class="name">Bravo</div>
<div class="location">New York</div>
</div>
<div class="item">
<div class="genre">Pop</div>
<div class="name">Charlie</div>
<div class="location">Paris</div>
</div>
</div>
<div class="buttons">
Sort by Genre
Sort by Name
Sort by Location
</div>
jQuery
function sorting(tag) {
var items = $('div.item').sort(function(a, b) {
var txt1 = $.trim($('div.' + tag, a).text()),
txt2 = $.trim($('div.' + tag, b).text());
if (txt1 > txt2) return 1;
else return -1;
});
return items;
}
$('.buttons a').on('click', function(e) {
e.preventDefault();
$('div#container').html(sorting(this.id));
});
Working Sample
Ok, this would be my pure JS solution.
First, we should wrap your <div>s into a larger container.
<div id = "wrapper">
<div id = "item">...</div>
<div id = "item">...</div>
<div id = "item">...</div>
</div>
Now, let's define a constant - which property do you want to sort it by? (this will probably be a function parameter later in your code).
var propName = "genre";
Let's get all the <div>s and put them in an array.
var items = document.getElementsByClassName("item");
var itemsArray = new Array();
Let us sort them lexicographically according to the text of the selected property.
for (var i = 0; i < items.length; i++)
itemsArray.push(items[i]);
itemsArray.sort(function(a, b) {
var aProp = a.getElementsByClassName(propName)[0].firstChild.nodeValue;
var bProp = b.getElementsByClassName(propName)[0] .firstChild.nodeValue;
if (aProp < bProp)
return -1;
else if (aProp > bProp)
return 1;
else
return 0;
});
Let us construct a document fragment consisting of the sorted <div>s.
var fragment = document.createDocumentFragment();
for (var i = 0; i < itemsArray.length; i++)
fragment.appendChild(itemsArray[i].clone());
Finally, let us clear the contents of the <div id = "wrapper"> and replace it with the document fragment.
document.getElementById('wrapper').innerHTML = '';
document.getElementById('wrapper').appendChild(fragment);
Also, note that document.getElementsByClassName does not work in IE<9, but I was now really lazy to cope with that issue.
A fiddle: http://jsfiddle.net/nNXr4/
Check this beast:
function sortByCreatedOnAsc(a,b){
return $(a).find('.created_on').text() > $(b).find('.created_on').text();
}
function sortByCreatedOnDesc(a,b){
return $(a).find('.created_on').text() < $(b).find('.created_on').text();
}
function reorderEl(el){
var container = $('#tasks');
container.html('');
el.each(function(){
$(this).appendTo(container);
});
}
$('#created_on').click(function(){
if($(this).hasClass("asc")){
reorderEl($('.task').sort(sortByCreatedOnDesc));
$(this).removeClass("asc");
$(this).addClass("desc");
} else {
reorderEl($('.task').sort(sortByCreatedOnAsc));
$(this).removeClass("desc");
$(this).addClass("asc");
}
return false;
});
jsfiddle: http://jsfiddle.net/jKJc3/116/