Selecting multiple elements with querySelectorAll and applying event in JavaScript - javascript

there is an onchange event on the input and want it to change the value of the spans with the class of "number" whenever it changes so there here is the HTML :
function myFunction() {
var x = document.getElementById("myText").value
document.querySelectorAll(".number").innerText = x
}
<div class="uper-container">
<p>Metric/Imperial unit conversion</p>
<!-- *********************************************************************************************** -->
<!-- this input will change the value of 6's span below with the class of "number" -->
<!-- ********************************************************************************************** -->
<input type="text" id="myText" placeholder="number here" value="20" onchange="myFunction()">
</div>
<div class="lower-container">
<p>Length(Meter/Feet)</p>
<p>
<span class="number"></span> meters = <span class="d"></span>feet |
<span class="number"></span> feet = <span class="d"></span>meters
</p>
<p>Volume(Liters/Gallons)
<</p>
<p>
<span class="number"></span> liter = <span class="d"></span>gallon |
<span class="number"></span> gallon = <span class="d"></span>liter
</p>
<p>Mass(Kilograms/Pounds)</p>
<p>
<span class="number"></span> kilogram = <span class="d"></span>pound |
<span class="number"></span> pound = <span class="d"></span>kilogram
</p>
</div>
so how to make spans with the class="number" have the same value as input id="myText"?
and one thing to mention is that I use scrimba editor.

Unlike jQuery, Vanilla JS will not execute innerText to every node returned by querySelectorAll with an inline call. You would need to loop through them.
The code below should work:
function myFunction() {
var x = document.getElementById("myText").value;
var spans = document.querySelectorAll(".number");
for (let i = 0; i < spans.length; i++) {
spans[i].innerText = x;
}
}

You can also use the for-of loop.
function myFunction() {
const x = document.getElementById("myText").value;
const numberElements = document.querySelectorAll(".number");
for (let element of numberElements) {
element.innerText = x;
}
}

Related

Display show/hide depending on the combinaion of classes - Javascript Vanilla

I'm making a multi-language registration site. I need to detect if an element has a class="lng" which indicates that it will be displayed or hidden, depending on the language selected. (this part already works).
Additionally I need to detect which other class the element with the lng class has. So if the combination of classes is lng and en it will display the content in english language and hide all the other elements with the lng class which do not have an en class next to it (`class="lng" class="ru").
I can refactor the html elements so that it has class="lng en" if that would have make it easier...
HTML - language selection
<input type="image" id="slo" onclick="setLanguage('sl')">
<input type="image" id="ang" onclick="setLanguage('en')">
<input type="image" id="hrv" onclick="setLanguage('hr')">
<input type="image" id="rus" onclick="setLanguage('ru')">
HTML example - only one should be displayed, depending on the language selected:
<span class="lng" class="sl" class="radioS">Spol: </span>
<span class="lng" class="en" class="radioS">Gender: </span>
<span class="lng" class="hr" class="radioS">Spolov: </span>
<span class="lng" class="ru" class="radioS">секс: </span>
Javascript
function setLanguage(language) {
var lngs;
var i;
lngs = document.getElementsByClassName("lng");
console.log(lngs);
for (var i=0;i<lngs.length;i++){
if (lngs[i].classList.contains(language) !== language) {
lngs[i].style.display="none";
} else {
lngs[i].style.display="inline-block";
}
}
}
At the begining make them all invisible then iterate through all inputs and check if the class includes your language:
const lngs = document.getElementsByClassName("lng");
function init() {
for (var i = 0; i < lngs.length; i++) {
lngs[i].style.display = "none";
}
}
init();
function setLanguage(language) {
debugger
for (var i = 0; i < lngs.length; i++) {
if (lngs[i].className.includes(language)) {
lngs[i].style.display = "block";
} else {
lngs[i].style.display = "none";
}
}
}
<input type="image" id="slo" onclick="setLanguage('sl')">
<input type="image" id="ang" onclick="setLanguage('en')">
<input type="image" id="hrv" onclick="setLanguage('hr')">
<input type="image" id="rus" onclick="setLanguage('ru')">
<span class="lng sl radioS">Spol: </span>
<span class="lng en radioS">Gender: </span>
<span class="lng hr radioS">Spolov: </span>
<span class="lng ru radioS">секс: </span>
function setLanguage(language) {
// var 1
document
.getElementsByClassName("lng")
.forEach(lang => lang.classList.remove('visible'));
// var 2
document
.getElementByClassName('visible')
.forEach(el => el.classList.remove('visible'));
// show target lang
document.getElementById(language).classList.add('visible');
}
.lng {
display: none;
}
.visible {
display: block;
}
simply u can use radio buttons if it is checked that particular matching language will be displayed and others will be hidden.
$(document).ready(function() {
$("input").change(function() {
var len = document.getElementsByTagName("input");
for (var i = 0; i < len.length; i++) {
if (len[i].checked == 1) {
$(".lng." + len[i].id).show();
} else {
$(".lng." + len[i].id).hide();
}
}
});
});
.lng {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<input type="radio" id="sl" value="sl" name="lang"> sl
<input type="radio" id="en" value="sl" name="lang"> en
<input type="radio" id="hr" value="sl" name="lang"> hr
<input type="radio" id="ru" value="sl" name="lang"> ru
<br>
<span class="lng sl">Spol: </span>
<span class="lng en" class="en">Gender: </span>
<span class="lng hr" class="hr">Spolov: </span>
<span class="lng ru" class="ru">секс: </span>

Trouble looping through the inputs and adding them

Having an issue with peoplePaid() looping through all the inputs with the .persons class on a page through an add button. I believe this issue is that #paidTotal is trying to add contents from an array in .persons but can't access them (gives me an undefined error in console).
This variable works but only if there's one .persons class with a variable...
var personsCheck = parseFloat(document.getElementsByClassName('persons')[0].value);
However I need it to dynamically loop the values of the array that is created through .persons elements. What am I missing?
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = document.getElementById('paidTotal');
for (var i = 1; i < personsCheck.length; i += 1) {
paidTotal += personsCheck[i];
}
paidTotal.innerHTML = checkTotal - personsCheck;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>
paidTotal is an element. I believe you do not want to use += on the element itself. You should add the total to a variable.
Also, as the index of collections are 0 based, you have to start the value of i from 0. You have to take the value property from each element.
Please Note: It is good practice to use textContent instead of innerHTML when dealing with text only content.
Try the following way:
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = document.getElementById('paidTotal');
var pCheck = 0;
for (var i = 0; i < personsCheck.length; i += 1) {
pCheck += personsCheck[i].value;
}
paidTotal.textContent = checkTotal - pCheck;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>
Some mistakes exists in your code:
paidTotal is an element but in paidTotal += personsCheck[i]; you have used it some a numeric variable.
in your loop, index must starts from zero not one.
in this line: paidTotal += personsCheck[i]; you have added personsCheck[i] element to paidTotal instead of its value.
the corrected code is like this:
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = 0;
for (var i = 0; i < personsCheck.length; i += 1) {
paidTotal += personsCheck[i].value * 1;
}
document.getElementById('paidTotal').innerHTML = checkTotal - paidTotal;
}
$ <input type="text" id="check" value="" />
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person">
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>

Button Changes the Final Cost/Value

I've created few buttons, and when clicked I want to affect the final cost, working but not as it should be. The button has a value and the final value of cost doesn't work, can someone let me know what I'm doing wrong?
function totalIt() {
var input = document.getElementsByName("product");
var total = 0;
for (var i = 0; i < input.length; i++) {
if (input[i].click) {
total += parseFloat(input[i].value);
}
}
document.querySelector(".priceText1").innerText = "$" + total.toFixed(2);
}
<div class="priceWrapper">
<h3 class="priceText1" id="total">$0.00</h3>
<h3 class="priceText2">Final Cost</h3>
</div>
<div class="item">
<div class="itemProduct">
<h4 class="itemText">
<span class="no_selection">Logos</span>
</h4>
</div>
<div class="itemHidden">
<form action="" id="theForm">
<label>
<button class="buttonBg" name="product" value="25.00" type="button">Producto 3</button>
</label>
<label>
<button class="buttonBg" name="product" value="10.00" type="button">Producto 4</button>
</label>
</form>
</div>
But when I pick one, the final price won't work perfectly. is displaying a different number! can some help me?
Attach the click event to all the buttons and add the cost on every click like the snippet below shows.
NOTE : If you want to add the cost just one time by button you could disable the button immediately after the click using :
this.setAttribute('disabled','disabled');
Hope this helps.
var products = document.querySelectorAll(".buttonBg");
for (var i = 0; i < products.length; i++) {
products[i].addEventListener("click", totalIt);
}
function totalIt() {
var total = document.querySelector("#total");
var currentVal = parseInt( total.innerText );
var new_val = parseInt( this.value );
if( this.classList.contains('clicked') ){
total.innerText = ( currentVal - new_val ).toFixed(2);
}else{
total.innerText = ( currentVal + new_val ).toFixed(2);
}
document.querySelector("#total2").innerText = total.innerText;
this.classList.toggle('clicked');
}
.clicked{
color: green;
}
<div class="priceWrapper">
<h3 class="priceText1">$<span id="total">0.00</span></h3>
<h3 class="priceText2">Final Cost</h3>
</div>
<div class="item">
<div class="itemProduct">
<h4 class="itemText">
<span class="no_selection">Logos</span>
</h4>
</div>
<div class="itemHidden">
<form action="" id="theForm">
<label>
<button class="buttonBg" name="product" value="25.00" type="button">Producto 3</button>
</label>
<label>
<button class="buttonBg" name="product" value="10.00" type="button">Producto 4</button>
</label>
</form>
</div>
<h3 class="priceText1">$<span id="total2">0.00</span></h3>
I have adapted your code to make this work see below
Note below i have added id's to the product buttons.
<div class="priceWrapper">
<h3 class="priceText1" id="total">$0.00</h3>
<h3 class="priceText2">Final Cost</h3>
</div>
<div class="item">
<div class="itemProduct">
<h4 class="itemText">
<span class="no_selection">Logos</span>
</h4>
</div>
<div class="itemHidden">
<form action="" id="theForm">
<label>
<button class="buttonBg" id="product1" name="product" value="25.00" type="button">
Producto 3
</button>
</label>
<label>
<button class="buttonBg" id="product2" name="product" value="10.00" type="button">
Producto 4
</button>
</label>
</form>
</div>
Then i have modified your code
//
// this will be the element clicked so just add it, as below
//
function addProduct() {
el = this;
total += parseFloat(el.value);
total_el.innerText = "$" + total.toFixed(2);
};
//
// Cache your total get a reference to the total element (faster!)
// when you write your code don't keep doing stuff when it can be done
// once - speed is everything and as you write more complex stuff
// doing it write from day one will pay off in your work (toptip)
//
var total = 0;
var total_el = document.querySelector(".priceText1");
//
// Bind up the click event
//
document.getElementById('product1').onclick = addProduct;
document.getElementById('product2').onclick = addProduct;
And here you can see the end result
https://jsfiddle.net/64v3n1se/
To scale this you would add the click handler using a class and a loop but for simpleness i have... kept it simple.
Because during your calculation you are getting all button's values and add them up so whenever the button is clicked you calculate the sum of the values of the buttons.
Your way of thinking right now, as far as I can tell, is wrong.
You can change your html code and script code like this.
With this way we are passing object of button to the function and we increase the global total variable within the function. Later on you change the dom.
var total = 0;
function totalIt(obj) {
total = total + parseFloat(obj.value);
document.querySelector(".priceText1").innerText = "$" + total.toFixed();
}
And pass the object of button in the html with
<button class="buttonBg" name="product" value="10.00" type="button" onclick="totalIt(this)">

get different inner html from same class [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 5 years ago.
Can anyone help with how do you get the different innerhtml from the same class into an input text? This is the code. Thanks.
function myFunction() {
var a = document.getElementsByClassName("name");
var b = document.getElementById("whispering");
a.innerHTML = b.value;
}
<span onclick="myFunction();" class="name" id="username1"> Username 1 </span>
<span onclick="myFunction();" class="name" id="username2"> Username 2 </span>
<input type="text" id="whispering">
The issue with your code is that getElementsByClassName returns a collection, so you need to loop through that and set the innerHTML of each individual element:
function myFunction() {
var a = document.getElementsByClassName("name");
var b = document.getElementById("whispering");
for (var i = 0; i < a.length; i++) {
a[i].innerHTML = b.value;
}
}
<span onclick="myFunction();" class="name" id="1"> HAHA1 </span>
<span onclick="myFunction();" class="name" id="2"> Haha2 </span>
<input type="text" id="whispering">
Something like this will do the trick:
a[2].innerHTML = b.value;
Or if you want the specific item clicked, you could do:
HTML:
<span id="1" class="name">Content</span>
<span id="2" class="name">Content</span>
JS:
var spans = document.getElementsByClassName("name");
for(var i = 0; i < spans.length; i++){
spans[i].onclick = function(){
this.innerHTML = b.value;
}
}
NOTE: this also stops the use of inline JS :)
Fiddle: https://jsfiddle.net/yn9wauyk/
You would be better to pass a reference to the clicked element into your method - this solves all problems of referencing the correct element by id or by class.
function myFunction(elem) {
var b = document.getElementById("whispering");
elem.innerHTML = b.value;
}
<span onclick="myFunction(this);"> HAHA1 </span>
<span onclick="myFunction(this);"> Haha2 </span>
<input type="text" id="whispering">

jQuery set value of an element from an object

How can I set a value of an element with JQuery from an object $this?
I have some divs of class "A"
<div class="A">
<span name='B'>some text</span>
<div>
<input name='value_1' value='15'/>
<input name='value_2' value='9'/>
</div>
</div>
<div class="A">
<span name='B'>some other text</span>
<div>
<input name='value_1' value='7'/>
<input name='value_2' value='12'/>
</div>
</div>
...more divs like those
I'm trying to set the text of the spans of name B with the greater value of their inputs (inputs 'value_1' and 'value_2').
But what I'm trying seems to fail, this is the js (using jquery):
function setSpans(){
var value1=0;
var value2=0;
var setting_value = 0;
$('.A').each(function(){
value1 = $(this).find("input[name='value_1']").val();
value2 = $(this).find("input[name='value_2']").val();
if(value1 > value2)
setting_value = value1;
else
setting_value = value2;
//here comes what I can't accomplish
$(this).find("span[name='B']").text(setting_value);
});
}
All you need to do is to cast string values to numbers before you compare them:
var value1 = Number($(this).find("input[name='value_1']").val());
var value2 = Number($(this).find("input[name='value_2']").val());
Remember that value of the input field is always a string and of course string "9" is greater then "15".
Demo: http://jsfiddle.net/ck64v16t/
Two problems that I see:
time of setSpans call. It has to be after used elements are already in DOM - either by using document.ready or by placing script after these elements in page.
values of inputs are Strings, so you can use, for example, parseInt to compare values as Numbers.
Workable example:
Fiddle.
HTML:
<div class="A">
<span name='B'>some text</span>
<div>
<input name='value_1' value='15'>
<input name='value_2' value='9'>
</div>
</div>
<div class="A">
<span name='B'>some other text</span>
<div>
<input name='value_1' value='7'>
<input name='value_2' value='12'>
</div>
</div>
JS:
$(document).ready(setSpans);
function setSpans()
{
var value1 = 0;
var value2 = 0;
var setting_value = 0;
$('.A').each(function()
{
value1 = parseInt($(this).find("input[name='value_1']").val());
value2 = parseInt($(this).find("input[name='value_2']").val());
if (value1 > value2)
{
setting_value = value1;
}
else
{
setting_value = value2;
}
$(this).find("span[name='B']").text(setting_value);
});
}

Categories