This question already has answers here:
How to put all elements' content in array using jQuery ?
(2 answers)
Closed 6 years ago.
I have the problem that I'm trying to get the content of all span's with the same class.
Thats the relevant html:
#foreach($products as $product
<div class="media-body">
<h4 class="media-heading">{{ $product->title }}</h4>
<p>{{ $product->short_description }}</p>
<div class="pull-right">
<span class="priceCell">{{$product->sales_price}}</span>€
<span>Quantities: </span><span class="quantitie">{{ $product->quantity }} </span>
<br>
</div>
</div>
#endforeach
The $products variable have 6 different products. So 6 different quantities.
I need the different quantities as a array that looks like this:
var quantities = [25,20,15,10,5,1];
current js:
var quantities = document.getElementsByClassName("quantities");
alert(quantities) -- gives : html collection
I need the quantities array like this : [10,5,3,1]
Cause I want to use it with this code:
for (var q = 0; q < quantitys.length; q++) {
endPrice += (parseInt(quantities[q]) * parseFloat(prices[q]));
}
prices variable also looks like this: [15.00, 20.00, ...]
and other things.. but nothing have worked for me. Can someone help me there? Thanks!
Try use simple things
var spans = document.getElementsByClassName("quantities");
for(i=0;i<spans.length;i++)
{
alert(spans[i].innerHTML);
}
<span class="quantities">A</span>
<span class="quantities">B</span>
<span class="quantities">C</span>
<span class="quantities">D</span>
<span class="quantities">E</span>
Simple example with array
function getSpanDataByClass(className){
var spans = document.getElementsByClassName(className),
result = [];
if(!spans){
//no data
}
for(var i = 0; i < spans.length; i++){
result.push(spans[i].innerHTML);
}
return result;
};
function runDebug(){
var spanInnerData = getSpanDataByClass("quantities");
alert(spanInnerData);
};
runDebug();
<span class="quantities">A</span>
<span class="other">B</span>
<span class="quantities">C</span>
<span class="other">X</span>
<span class="quantities">Y</span>
<span class="quantities">Z</span>
Related
I'm trying to build a cart page for an e-commerce website. I'm having trouble figuring out the JS for calculating.. below I'm getting a file through AJAX call called products.json which has products information like id, name, imp, prices etc and an array called productsArray which has product ids saved of products I've clicked on their respective cart icons. Now the logic is if the products.json file contains the id of products present in the array I want it to display on the cart page. So when I click the products add to cart button, for whichever product I click it gets added to local storage and from there I get it and compare it with each of the products present in the JSON file. Now this is printing my product with all furnished information. Now I want to change the price when the quantity of product is changed. I've also added a code fo that below and that too works. When I click on 2 then the price gets multiplied by 2 and showcases it in HTML. similarly for other values. The problem is this works only for the first product. I'm unable to get the functionality working for all products even though the IDs are all same.. How do I tackle this issue? Also I need to be able to access all the product prices as you can see in the second image below, sum them up then update the total on the top and the right containers under various descriptions.. How do I do these as well? Pls help! Have been trying to crack this for past 3-4 days..
let products = new Set();
let counter = 0;
// adding click events to cart icon
document.body.addEventListener('click', e => {
if (e.target.closest('.shopping')) {
products.add(e.target.closest('.prod-card').id);
// adding number of products in cart icon
counter = Number(document.querySelector('#cart-badge').innerHTML) + 1;
document.querySelector('#cart-badge').innerHTML = String(counter);
};
// storing product ids in local storage
localStorage.setItem('Products_IDs', JSON.stringify(Array.from(products)))
});
// parsing JSON List for cart page
let RetrievedData = localStorage.getItem("Products_IDs");
let productsArray = JSON.parse(RetrievedData);
// for (i = 0; i < productsArray.length; i++){
// console.log(productsArray);
// }
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let myProducts = JSON.parse(this.responseText);
for (i = 0; i < productsArray.length; i++) {
for (j = 0; j < myProducts.products.length; j++) {
if (productsArray[i] == myProducts.products[j].id) {
let ReturnedHTML2 = " ";
ReturnedHTML2 = `<div class="cart-items-holder" id='pdt-box'>
<div class='pdt-container' id='pdt-single'>
<img class='img-sweater' src="Images/${myProducts.products[j].imageName}.png" alt="Sweater Image">
<div class="pdt-text w-100">
<div class="text1">
<h6>${myProducts.products[j].name}</h6>
<p class="mb-0 text-secondary">Color : Multicolor</p>
<p class="mb-0 text-secondary">Seller : Indus Valley & Co</p>
<div class="forms mt-xl-3 mt-lg-3 mt-md-2 mt-sm-2 d-flex justify-content-start align-items-start">
<div class="form-group">
<label class='mr-2' for="exampleFormControlSelectSize"></label>
<select class="form-control" id="exampleFormControlSelectSize">
<option>Size : Onesize</option>
<option>S</option>
<option>M</option>
<option>L</option>
<option>XL</option>
<option>XXL</option>
</select>
</div>
<div class="form-group2 ml-3">
<label class='mr-2' for="exampleFormControlSelectQuantity"></label>
<select class="form-control" id="exampleFormControlSelectQuantity">
<option>QTY : 1</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
</div>
</div>
</div>
<div class="text2">
<p class='pricing mb-0'>Rs.<strong id='final-price'>${myProducts.products[j].priceAfterDiscount}</strong> <del id='initial-price'>Rs.${myProducts.products[j].price}</del><span
class="offer font-weight-bold ml-1">(60%Off)</span></p>
<small class="text-secondary">Delivery in 4 - 6 days</small>
</div>
</div>
</div>
<div class="options">
<a class="ml-3 mr-3 text-dark font-weight-bold" id='remove-btn' href="">REMOVE</a> | <a class="ml-3 mr-3 text-dark font-weight-bold" id='wishlist-btn' href="">ADD TO WISHLIST</a>
</div>
</div>
<br>`
document.querySelector('#cart-items-area').innerHTML += ReturnedHTML2;
sessionStorage.setItem("discounted_price", Number(document.getElementById('final-price').innerHTML))
document.getElementById('exampleFormControlSelectQuantity').onchange = function() {
if (document.getElementById('exampleFormControlSelectQuantity').selectedIndex == 1) {
price_1 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_1 * 1;
} else if (document.getElementById('exampleFormControlSelectQuantity').selectedIndex == 2) {
price_2 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_2 * 2;
} else if (document.getElementById('exampleFormControlSelectQuantity').selectedIndex == 3) {
price_3 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_3 * 3;
} else if (document.getElementById('exampleFormControlSelectQuantity').selectedIndex == 4) {
price_4 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_4 * 4;
} else {
price_default = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_default;
}
}
}
}
}
}
};
xmlhttp.open("GET", "products.json", true);
xmlhttp.send();
[
Seeing that you've spent a few days on this already. I would consider it worth spending some time to refactor the existing code to be a bit more organized! :)
I see a lot of nested ifs and fors => extract them to separate functions
I see a big template containing an HTML document string => separate function taking 2 arguments & returns the fully rendered html document.
If you end up looking at this code for yet another day, at least it would help if you extracted every part into its own simpler function. you can also then run each function individually to test that it does what you expect this way! :) It helps a tonne to split things up!
Right now it's all one "big monster function" in the XMLHTTPRequest handler.
Also, there is a fair bit of repeated code in the bottom, Whenever you see this it should help guide you to where to reduce and simplify your code a bit!:
if (document.getElementById('exampleFormControlSelectQuantity').selectedIndex == 1) {
price_1 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_1 * 1;
} else if (/*repeated code*/) {
/* repeated code, with a single number changing 2, 3, 4... */
}
the conditional code is (almost) exactly the same, so you don't have to make the same document query for the same element in every case.
const selected_number = document.getElementById('exampleFormControlSelectQuantity').selectedIndex;
and you can re-use this like this:
if (selected_number == 1) {
price_1 = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price_1 * 1;
} else if (selected_number == 2) {
/* repeated code, with a single number changing 2, 3, 4... */
}
but now you can also just assume the number is... the number you need inside the conditional... so you can shorten the individual number checks to a single snippet of code like this:
price = sessionStorage.getItem("discounted_price");
document.getElementById('final-price').innerHTML = price * selected_number;
I want to use the jQuery function .each() to apply a possible change to a value.
I have a bunch of labels in tags with a class="temp". If I have a switch to switch between Celsius and Fahrenheit I would like to update all html elements with the temp class. I will retrieve the value from the span, then update the span to have the new temperature.
Span tags look like
<span class="temp" id="holder_1443531366" style="text-align:center; display:inline-block;"><span style>86.1</span>
<span style="padding-left:3px;">°F</span>
</span>
Im sure this isnt the best looking html element, i didnt make it, im using a website to build a web dashboard and cannot actually change these directly.
There is other parts to this code, but I just need the main part working.
//Find all elements with span class="temp"
var temps = [];
var html;
var pHtml;
temps = jQuery('.temp').toArray();
html = jQuery('.temp').html();
//pHtml = jQuery('.temp').parseHTML();
if(temps != null){
console.log("Temps -> "+temps.length);
console.log("html -> "+html);
for(var i = 0; i < temps.length; i++){
console.log(temps[i]);
}
}else {
console.log("No temps found");
}
I have currently two elements to find and this is the output so far
Attempting to find temp classes
Temps -> 2
html -> <span style="">86.0</span><span style="padding-left:3px;">°F</span>
<span class="temp" id="holder_1443531366" style="text-align:center; display:inline-block;"><span style>86.1</span><span style="padding-left:3px;">°F</span></span>
<span class="temp" id="holder_1443531376" style="text-align:center; display:inline-block;"><span style>85.38</span><span style="padding-left:3px;">°F</span></span>
I save each element with the ".temp" class, find the temp (86.1) and then use that value to execute my temp converter function (or just some math right there).
With the new value, I will update the element from 86.1 -> the Celsius temp i just calculated.
what this code does, is that on click of the link, it cycles through each element with class .temp and gets the .degrees, converts that to Celsius, and then changes the F to a C.
i added classes on both spans to accomplish this (.degrees and .degType)
$(document).ready(function() {
$('.toC').on('click', function() {
$('.temp').each(function() {
var degrees = $(this).find('.degrees').html();
var cTemp = (parseFloat(degrees - 32) * (parseFloat(5/9))).toFixed(1);
$(this).find('.degrees').html(cTemp);
$(this).find('.degType').html('°C');
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="temp" id="holder_1443531366" style="text-align:center; display:inline-block;"><span class="degrees">86.1</span>
<span class="degType" style="padding-left:3px;">°F</span>
</span>
<br/><br/>
<span class="temp" id="holder_1443531366" style="text-align:center; display:inline-block;"><span class="degrees">212</span>
<span class="degType" style="padding-left:3px;">°F</span>
</span>
<br/><br/>
<a class="toC" href="#">to Celcius<a/>
Here's a way to toggle back and forth
$('a').click(function () {
$('span.temp').each(function () {
if ($(this).find('span:last').text() == '°F') {
$(this).find('span:last').text('°C');
$(this).find('span:first').text(parseFloat((($(this).find('span:first').text() - 32) * 5) / 9).toFixed(2))
} else {
$(this).find('span:last').text('°F');
$(this).find('span:first').text(parseFloat((($(this).find('span:first').text() * 9) / 5) + 32).toFixed(2))
}
})
$(this).text($(this).text() == 'switch to Fahrenheit' ? 'switch to Celsius' : 'switch to Fahrenheit')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="temp" id="holder_1443531366" style="text-align:center; display:inline-block;">
<span style>86.1</span>
<span style="padding-left:3px;">°F</span>
</span>
<span class="temp" id="holder_1443531367" style="text-align:center; display:inline-block;">
<span style>212</span>
<span style="padding-left:3px;">°F</span>
</span>
switch to Celsius
Try using .find() to filter first span , .html(function(index, html){}) to convert Fahrenheit to Celsius , select next span to change F to C
$(".temp").each(function(index, el) {
$(this).find("span:first").html(function(_, temp) {
return ((temp - 32) * 5/9).toFixed(2)
}).next("span").html(function(_, sym) {
return sym.slice(0,1) + "C"
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<span class="temp" id="holder_1443531366" style= "text-align:center;display:inline-block;"><span style>86.1</span><span style="padding-left:3px;">°F</span></span>
<span class="temp" id="holder_1443531376" style= "text-align:center;display:inline-block;"><span style>85.38</span><span style="padding-left:3px;">°F</span></span>
I've made a working example and tested it to be working
http://jsfiddle.net/a2dax16t/
I've created a sample set of spans as you did, but added a button to trigger the function:
<span class="temp" id="holder_1443531366" style="text-align:center;display:inline-block;">86.1</span>
<br/>
<span class="temp" id="holder_1443531366" style="text-align:center;display:inline-block;">99</span>
<br/>
<span class="temp" id="holder_1443531366" style="text-align:center;display:inline-block;">102</span>
</span>
<br/>
<button id="btnCelsius">Convert</button>
and here is my function:
$(function () {
$("#btnCelsius").click(function () {
$(".temp").each(function () {
var newValue = $(this).html();
$(this).html(toCelsius(newValue));
});
});
});
function toCelsius(f) {
return (5 / 9) * (f - 32);
}
as you can see, I've created a function to convert to celsius, and used it inside the each() function, and tested it and it's working.
please give it a try and let me know if this is what you want or that you need any extra modifications.
I am trying to have 4 boxes always show up. The boxes are filled by an image,but if there is no image available I want the boxes to be gray. The images variable holds an unknown amount of images, it could be 2 it could be 30.
<div class="container">
<div class="picture" ng-repeat="image in images | limitTo: 4"></div>
// PSEUDO CODE BELOW
<div class="empty" ng-repeat="i in 4 - images.length"></div>
// PSEUDO CODE ABOVE
</div>
"4 - images.length" is pseudo code, This is what I want to achieve, thinking if I only have 3 images available the result will be 1 gray box. But this syntax obviously does not work since ng-repeat require a collection.
Which made me try to provide it said collection through a function:
$scope.getNumber = function(num) {
return new Array(num);
}
and use in the following way:
<div class="empty" ng-repeat="n in getNumber(4 - cookbook.images.length)"></div>
But with no success.
<div class="picture" ng-repeat="image in images | limitTo: 4">hi</div>
<div class="empty" ng-repeat="n in [] | range:images.length:4">hey</div>
I've created a custom filter for it:
app.filter('range', function() {
return function(input, min, max) {
min = parseInt(min);
max = parseInt(max);
for (var i=min; i<max; i++) {
input.push(i);
}
return input;
};
});
DEMO
Possible repeat question
By using this updated syntax you can iterate with a specific index defined
HTML
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<ul>
<li ng-repeat="i in getNumber(4) track by $index"><span>{{$index+1}}</span></li>
</ul>
</div>
Controllers
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.getNumber = function(num) {
return new Array(num);
}
});
Way to ng-repeat defined number of times instead of repeating over array?
I would probably handle this in whatever populates $scope.images. For example, something like:
$http.get('api/some/images?skip=10&take=4')
.success(function(response){
$scope.images = response;
for(var i = $scope.images.length; i<4; i++){
$scope.images.push('empty');
}
});
Then my template would just handle that:
<div class="container>
<div ng-repeat="image in images" ng-class="{empty:image=='empty',picture:image!='empty'}"></div>
</div>
wouldnt be easier to make operation modulo in controller?
function equal_number_of_images(){
for(var i = 0, add = 4 - $scope.some_files%4; i < add; i++ ){
$scope.some_files.push('');
}}
This question already has answers here:
How to add a class to a given element?
(28 answers)
Closed 9 years ago.
I need to change the class of each href item depending on its value.
I have this code.
<body onload="myFunction()">
<div class="indi-download">
<div class="pull-left">
<h6 class="file" id="file-display-id">%file_display_name%</h6>
</div>
<div class="pull-right">
<a class="download-link" id="download_link" href="%file_url%">Download</a>
</div>
</div>
</body>
In getting the href item on class download-link, I used this javascript code.
function myFunction()
{
var anchors = document.querySelectorAll('a.download-link');
for (var i = 0; i < anchors.length; i++) {
var url = anchors[i].href;
var splitfile = url.split('.').pop();
if(splitfile=='pdf'){
//class="file" would be class="pdf-file"
}else if(splitfile=="docx"){
//class="file" would be class="docx-file"
}else{
//other file format...
}
}
}
on Inspect Element, Something this kind of output.
Element 1 ---
<div class="indi-download">
<div class="pull-left">
//Changed into pdf-file
<h6 class="pdf-file" id="file-display-id">Sample PDF 1</h6>
</div>
<div class="pull-right">
<a class="download-link" id="download_link" href="http://mysite-
info/download/files/file1.pdf">Download</a>
</div>
</div>
Element 2 ---
<div class="indi-download">
<div class="pull-left">
//Changed into docx-file
<h6 class="docx-file" id="file-display-id">Sample docx 1</h6>
</div>
<div class="pull-right">
<a class="download-link" id="download_link" href="http://mysite-
info/download/files/file2.docx">Download</a>
</div>
</div>
How to achieve this kind of output? Changing the classes that depends on the values on href. Any Idea?
If you can use jQuery, I think something like this should work:
function myFunction()
{
var anchors = document.querySelectorAll('a.download-link');
for (var i = 0; i < anchors.length; i++) {
var url = anchors[i].href;
var splitfile = url.split('.').pop();
if(splitfile=='pdf'){
$(anchors[i]).removeClass('file');
$(anchors[i].addClass('pdf-file');
}else if(splitfile=="docx"){
$(anchors[i]).removeClass('file');
$(anchors[i]).addClass('docx-file');
}else{
//other file format...
}
}
}
The class attribute is mapped to the className property so as not to clash with the ECMCAScript future reserved word class, so you want something like:
anchors[i].className = 'docx-file';.
Applied to your example, you can do something like:
var classNames = {pdf:'pdf-file', docx:'docx-file'};
...
anchors[i].className = classNames[splitfile];
and to accommodate a default:
anchors[i].className = classNames[splitfile] || 'default-class';
just in case splitfile doesn't match one of the expected values. And the entire function is:
function myFunction() {
var anchors = document.querySelectorAll('a.download-link');
var classNames = {pdf:'pdf-file', docx:'docx-file'};
for (var i = 0; i < anchors.length; i++) {
var url = anchors[i].href;
var splitfile = url.split('.').pop();
anchors[i].className = classNames[splitfile] || 'default-class';
}
}
There's a page with some HTML as follows:
<dd id="fc-gtag-VARIABLENAMEONE" class="fc-content-panel fc-friend">
Then further down the page, the code will repeat with, for example:
<dd id="fc-gtag-VARIABLENAMETWO" class="fc-content-panel fc-friend">
How do I access these elements using an external script?
I can't seem to use document.getElementByID correctly in this instance. Basically, I want to search the whole page using oIE (InternetExplorer.Application Object) created with VBScript and pull through every line (specifically VARIABLENAME(one/two/etc)) that looks like the above two into an array.
I've researched the Javascript and through trial and error haven't gotten anywhere with this specific page, mainly because there's no tag name, and the tag ID always changes at the end. Can someone help? :)
EDIT: I've attempted to use the Javascript provided as an answer to get results, however nothing seems to happen when applied to my page. I think the tag is ALSO in a tag so it's getting complicated - here's a major part of the code from the webpage I will be scanning.
<dd id="fc-gtag-INDIAN701" class="fc-content-panel fc-friend">
<div class="fc-pic">
<img src="http://image.xboxlive.com/global/t.58570942/tile/0/20400" alt="INDIAN701"/>
</div>
<div class="fc-stats">
<div class="fc-gtag">
<a class="fc-gtag-link" href='/en-US/MyXbox/Profile?gamertag=INDIAN701'>INDIAN701</a>
<div class="fc-gscore-icon">3690</div>
</div>
<div class="fc-presence-text">Last seen 9 hours ago playing Halo 3</div>
</div>
<div class="fc-actions">
<div class="fc-icon-actions">
<div class="fc-block">
<span class="fc-buttonlabel">Block User</span>
</div>
</div>
<div class="fc-text-actions">
<div class="fc-action"> </div>
<span class="fc-action">
View Profile
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Compare Games
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Send Message
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Send Friend Request
</span>
</div>
</div>
</dd>
This then REPEATS, with a different username (the above username is INDIAN701).
I tried the following but clicking the button doesn't yield any results:
<script language="vbscript">
Sub window_onLoad
Set oIE = CreateObject("InternetExplorer.Application")
oIE.visible = True
oIE.navigate "http://live.xbox.com/en-US/friendcenter/RecentPlayers?Length=12"
End Sub
</script>
<script type="text/javascript">
var getem = function () {
var nodes = oIE.document.getElementsByTagName('dd'),
a = [];
for (i in nodes) {
(nodes[i].id) && (nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i]));
}
alert(a[0].id);
alert(a[1].id);
}
</script>
<body>
<input type="BUTTON" value="Try" onClick="getem()">
</body>
Basically I'm trying to get a list of usernames from the recent players list (I was hoping I wouldn't have to explain this though :) ).
var getem = function () {
var nodes = document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i].id.split('-')[2]));
}
alert(a[0]);
};
please try it by clicking here!
var getem = function () {
var nodes = document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i]));
}
alert(a[0].id);
alert(a[1].id);
};
try it out on jsbin
<body>
<script type="text/javascript">
window.onload = function () {
var outputSpan = document.getElementById('outputSpan'),
iFrame = frames['subjectIFrame'];
iFrame.document.location.href = 'http://live.xbox.com/en-US/friendcenter/RecentPlayers?Length=1';
(function () {
var nodes = iFrame.document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i].id.split('-')[2]));
}
for (var j in a) if (a.hasOwnProperty(j)) {
outputSpan.innerHTML += (a[j] + '<br />');
}
})();
};
</script>
<span id="outputSpan"></span>
<iframe id="subjectIFrame" frameborder="0" height="100" width="100" />
</body>
What does "I can't seem to use document.getElementsByID correctly in this instance" mean? Are you referring to the fact that you are misspelling getElementByID?
So...something like this (jQuery)?
var els = [];
$('.fc-content-panel.fc-friend').each(function() {
els.push(this));
});
Now you have an array of all the elements that have both of those classes.