convert repetitive variables and functions into loops - javascript

can anyone help me how to convert this into loops :) hi newbie here in javaScript:) the output of this is a input form, i want all the value that typed into the form to be appear instantly by using keyup event thanks in advance :)
let textarea = document.querySelectorAll('span')
let bns = document.querySelector('#bns');
let id = document.querySelector('#id');
let img = document.querySelector('#img');
let lg = document.querySelector('#lg');
textarea.forEach(function (item, index) {
item.classList.add('t'+ `${index}`)
//console.log(item)
})
let input = addEventListener('keyup', function(){
let strbns = bns.value;
let strid = id.value;
let strimg = img.value;
let strblg = lg.value;
document.querySelector('.t0').innerText = strbns
document.querySelector('.t1').innerText = strid
document.querySelector('.t2').innerText = strimg
document.querySelector('.t3').innerText = strblg
});
output
i create variables to each input field and used the keyup event to print the out put to individual span. yes it works but its so repetitive and i thinks it is much better if it's convert it into for loops but i dont know how

You can make it more optimal by give a try like this.
const formData = {
bns: document.querySelector('#bns'),
id: document.querySelector('#id'),
img: document.querySelector('#img'),
lg: document.querySelector('#lg')
};
document.addEventListener('keyup', function() {
Object.keys(formData).forEach((key, index) => {
document.querySelector(`.t${index}`).innerText = formData[key].value
})
});
<input type="text" id="bns"/>
<input type="text" id="id"/>
<input type="text" id="img"/>
<input type="text" id="lg"/>
<div class="t0"></div>
<div class="t1"></div>
<div class="t2"></div>
<div class="t3"></div>

Use two arrays which are the same length. Then you can loop over one of them with the index to get the corresponding element:
const elements = [bns, id, img, lg];
const selectors = [".t0", ".t1", ".t2", ".t3"].map((s) => document.querySelector(s));
addEventListener('keyup', function() {
elements.forEach((el, index) => {
selectors[index].innerText = el.value;
});
});

Related

Javascript adding li element value to the empty list if it is not existing

I have a problem in Javascript.I am adding new list items to the 'ul' elements and this list is empty at first and I do not want to add same values twice. When I write the if statement I get the exception because my list is empty so the result return null.
How can I fix this this problem?
Thank you in advance...
Html Codes
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
Javascript Codes
let newlist = document.querySelector("#myList");
const li = document.getElementsByClassName('list-group-item');
const button = document.getElementById("button");
const button.addEventListener('click' , listName);
const input = document.getElementById("the-filter");
function listName()
const inputVal = input.value;
for (i = 0; i < li.length; i++) {
if ((li[i].innerHTML.toLocaleLowerCase().includes(inputVal) && inputVal!="") ||
(li[i].innerHTML.toUpperCase().includes(inputVal) && inputVal!="")) {
let newItem = document.createElement("li");
li[i].classList.add("list-group-item");
let textnode = document.createTextNode(li[i].innerHTML.toLocaleLowerCase());
newItem.appendChild(textnode);
if((newlist.children[0].innerHTML.toLocaleLowerCase().includes(inputVal))){
newlist.insertBefore(newItem, newlist.childNodes[0]);
}
}
}
}
If I understood the task correct, you need to add items to the list by button click.
If same item exists (case insensitive), then nothing happens.
const list = document.querySelector("#myList");
const button = document.getElementById("button");
button.addEventListener("click", listName);
const input = document.getElementById("the-filter");
function listName() {
const inputVal = input.value;
const [...lis] = document.getElementsByClassName("list-group-item");
const same = lis.find((el) => el.textContent.toLowerCase() === inputVal.toLowerCase());
if (same) {
return;
}
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.textContent = inputVal;
list.appendChild(newItem)
}
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
</div>
You're on the right track with event listeners and element creation, but your original code didn't quite seem to match your stated goal.
Here's a solution you might find useful, with some explanatory comments:
// Identifies some DOM elements
const
input = document.getElementById("my-input"),
newList = document.getElementById("my-list"),
items = document.getElementsByClassName('list-group-item'),
button = document.getElementById("my-button");
// Focuses input, and calls addItem on button-click
input.focus();
button.addEventListener('click', addItem);
// Defines the listener function
function addItem(){
// Trims whitespace and sets string to lowerCase
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
// Clears and refocuses input
input.value = "";
input.focus();
// Ignores empty input
if (!inputTrimmedLower) { return; }
// Ignores value if a list item matches it
for (const li of items) {
const liTrimmedLower = li.textContent.trim().toLocaleLowerCase();
if (liTrimmedLower === inputTrimmedLower) {
console.log(`${inputTrimmedLower} is already listed`);
return;
}
}
// If we got this far, we want to add the new item
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.append(inputTrimmedLower); // Keeps lowerCase, as your original code
newList.prepend(newItem); // More modern method than `insertBefore()`
}
<input id="my-input" />
<ul id="my-list"></ul>
<button id="my-button">Click</button>

How to turn a list of strings to an array in javascript

I am trying to code a program which when a user inputs some numbers it will reverse it it and display it on the page. I have to tried to use 'Object.assign', but it doesn't work for me. I have also tried '.toArray', but it still doesn't work(maybe my formatting is wrong?). I am just a beginner so go easy on me. Thanks for t. This is what i have so far:
not working code but what i wanted
This works though:
Working code but not what i wanted
edit: when I reread the question, I realized you wanted the array in reverse. Updated answer at the bottom.
press enter to add the input. If you don't want only numbers delete type='number'.
var arr = [];
const input = document.getElementById('inpt');
input.addEventListener("keydown", event => {
if (event.keyCode === 13) {
arr[arr.length]=input.value;
input.value="";
console.log(arr);
}
});
<input placeholder="Enter a number" type='number' id ='inpt'/>
var arr = [];
const input = document.getElementById('inpt');
const output = document.getElementById('output');
input.addEventListener("keydown", event => {
if (event.keyCode === 13) {
arr[arr.length]=input.value;
input.value="";
var arr2= [...arr].reverse();
output.innerHTML='';
arr2.forEach(element => output.innerHTML+= element+' ');
console.log(arr);
}
});
<input placeholder="Enter a number" type='number' id ='inpt'/>
<div id = 'output'>
</div>

How to query multiple elements that start with the same ID and then check whether the input has changed

I have a list of text inputs which all start with the same id but are slightly different at the end. When text is entered by the user in any of these input fields I want to execute a function. At the moment this is working with the following code:
var heightInches = document.querySelector("#Height_Inches");
var heightFeet = document.querySelector("#Height_Feet");
var heightCentimeters = document.querySelector("#Height_Centimeters");
heightInches.oninput = function (e) {
console.log("Edited");
}
heightFeet.oninput = function (e) {
console.log("Edited");
}
heightCentimeters.oninput = function (e) {
console.log("Edited")
}
The issue is that I don't like the repetition and would rather query all of the ids that begin with "Height_" and do something (as what is excuted inside each function will be the same.
Here is what I have tried but does not work:
var allHeight = document.querySelector('[id*="Height_"]');
allHeight.oninput = function (e) {
console.log("edited");
}
I have also tried the same with querySelectorAll
Please could someone help with where I am going wrong here? Every other Stack Overflow answer and article I see seems to suggest that id* is the correct way to select? Thank you
If I understand correctly, this is what you are looking for.
The only thing you were missing is looping through your elements.
const inputs = document.querySelectorAll('[id*="Height_"]');
inputs.forEach( input => {
input.oninput = function (e) {
console.log("edited");
}
})
<input type="text" id="Height_1">
<input type="text" id="Height_2">
<input type="text" id="Height_3">
Rather than use an ID, which is intended to be unique, why not add a class like .height-input to each input and then you can select them all?
// Get elements
const inputs = document.querySelectorAll('.height-input');
const outputEl = document.querySelector('.output');
// Attach event handlers
for (let i = 0; i < inputs.length; i++) {
inputs[i].oninput = function(e) {
// Handle input
outputEl.innerHTML = `Input received on #${e.target.id}`;
}
}
.output {
margin-top: 10px;
}
<input type="text" class="height-input" id="HeightInches">
<input type="text" class="height-input" id="HeightFeet">
<input type="text" class="height-input" id="HeightCentimeters">
<div class="output">Waiting for input...</div>

Why wont this addEventListener work when I assign elements to a class?

I have two text inputs, and two date inputs. I created a variable and selected them all with a class using QuerySelectorAll, and put an click listener on it. The function on the listener changes the textContent of a div element to "", or blank.
However no matter what, I cant seem to get this to work with QuerySelectorAll. It works if i run this logic and select one of the inputs with an ID, but not if i try to create a class which selects all 4 input elements. What am i doing wrong?
const getSum = () => {
const inputs = ['dateInput1', 'dateInput2'];
const outputs = ['result1', 'result2'];
const arr = inputs.map(input => {
return document.getElementById(input).value;
});
if(arr.every(element => !!element)){
inputs.forEach((input, index) => {
const inputValue = document.getElementById(input).value;
if (inputValue.match(dateRegEx)) {
var sum = 0;
for (var i = 0; i < inputValue.length; i++) {
const num = parseInt(inputValue.charAt(i));
if (!isNaN(num)) {
sum += num;
}
}
const total = (sum - 1) % 9 + 1;
document.getElementById(outputs[index]).textContent = "Your number is: " + total;
}
});
} else {
document.getElementById("errorMsg").textContent = "*error* please enter two dates and two names";
}
}
const sumButton = document.querySelector(".sumNumbers");
sumButton.addEventListener("click", getSum);
const dateRegEx = /^(19|20)\d{2}-(0\d{1}|1[0-2])-([0-2]\d{1}|3[0-1])$/;
function clearErrorMsg(){
document.getElementById("errorMsg").textContent = "";
}
const cLickDeletesError = document.querySelectorAll(".clickClear");
Array.from(clickDeletesError).forEach(function(cde){
cde.addEventListener("click", clearErrorMsg);
}
const dateRegEx = /^(19|20)\d{2}-(0\d{1}|1[0-2])-([0-2]\d{1}|3[0-1])$/;
function clearErrorMsg(){
document.getElementById("errorMsg").textContent = "";
}
const cLickDeletesError = document.querySelectorAll(".clickClear");
Array.from(clickDeletesError).forEach(function(cde){
cde.addEventListener("click", clearErrorMsg);
}
querySelectorAll returns a collection, So you cannot directly add event listener to it. So use spread syntax to get an array from it. Then use forEach to iterate and add event listener
function clearErrorMsg() {
document.getElementById("errorMsg").textContent = "";
}
[...document.querySelectorAll(".clickClear")].forEach((e) => {
e.addEventListener("click", clearErrorMsg)
});
<div class="cell-1" id="centerElement">
<div id="cell-1-nest-l"></div>
<div id="cell-2-nest-l"></div>
<div id="cell-3-nest-l"></div>
<div id="cell-4-nest-l"></div>
<div id="cell-5-nest-l"></div>
<div id="cell-6-nest-l">
<input type="text" class="nameStyle1 clickClear" id="nameInput1" placeholder="Your Name"></div>
</div>
<div id='errorMsg'> Here is Error</div>
Another alternative is use of querySelector instead of querySelectorAll. This is because there is only one relevant element with that class. So using querySelectorAll is an overhead in this case
function clearErrorMsg() {
document.getElementById("errorMsg").textContent = "";
}
document.querySelector(".clickClear").addEventListener("click", clearErrorMsg)
<div class="cell-1" id="centerElement">
<div id="cell-1-nest-l"></div>
<div id="cell-2-nest-l"></div>
<div id="cell-3-nest-l"></div>
<div id="cell-4-nest-l"></div>
<div id="cell-5-nest-l"></div>
<div id="cell-6-nest-l">
<input type="text" class="nameStyle1 clickClear" id="nameInput1" placeholder="Your Name"></div>
</div>
<div id='errorMsg'> Here is Error</div>

How can i add or update products and prices in my list?

Pretty new to javascript, i want to add and update my list but it doesn't work.
I tried adding following code but it didn't work
Product.prototype.addProduct = function() {
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent= this.naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent= this.prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function() {
return this.naam + "(€ " + this.prijs +")";
}
This is the document i want wish would work propperly
<!DOCTYPE html>
<html>
<head>
<script src="oefwinkel.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10);
VulLijst();
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VulLijst() {
var elol = document.getElementById("lijst");
var producten = winkel.getProducten("</li><li>");
if (producten.length > 0) {
elol.innerHTML = "<li>" + producten + "</li>";
} else {
elol.innerHTML = "";
}
}
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
VulLijst();
}
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
</script>
</head>
<body>
<div><label for="txtNaam">Naam:</label>
<input type="text" id="txtNaam" /></div>
<div><label for="txtPrijs">Prijs:</label>
<input type="number" id="txtPrijs" /></div>
<input type="button" id="btn" value="Toevoegen/Updaten" />
<ol id="lijst">
</ol>
</body>
</html>
There is no list output how do i correct this?..
I really can't find the solution, what did i miss.. huh?
You had a few things missing,
The HTML code.
The winkel object was undefined.
The VulLijst function was doing nothing... because addProduct was taking care of this already.
You are relying on the instance fields (this.naam and this.prijs), but what you want to do is pass in method parameters (external variables).
As for updating, you will need to store a list of Products, clear the child elements of lijst, and re-add the items that represent the list.
Note: One thing I am confused about is why you named your class—that represents a list—Product, when it should really be an Inventory that allows you to ADD Product objects.
Code
// Uncaught ReferenceError: winkel is not defined
var winkel = new Product();
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
Product.prototype.addProduct = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
console.log(naam, prijs);
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent = naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent = prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
return naam + " (€ " + prijs + ")";
}
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10); // Why are you adding a product to a product?
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
}
label { font-weight: bold; }
<label>Product</label>
<input id="txtNaam" value="Something" />
<input id="txtPrijs"value="1.99" />
<button id="btn">Add</button>
<br/>
<ul id="lijst"></ul>
Explained
I will openly admit, I'm not 100% sure what you're trying to do, I assume that's due to a language barrier my side though, I'm not sure of the natural language that you use on a daily basis, i.e. some of the variable names seem unclear to me, but that's my problem, not yours! :)
Anyway, I used some guess work to figure out what you're trying to achieve, and I assumed that you're simply trying to have some sort of product list where each product has a name and a price attached to it?
You want to be able to add a product to the list, based on two input fields, then some button to add to/update that product list.
I've broken up the code into a couple of simple functions, with this solution you can add/remove as many functions, classes or whatever you want. In this answer you can clearly see that there's some render function, and some onUpdate function, I just went with these generic names for the sake of simplicity.
If you have any issues with this solution, please provide as much feedback as possible! I hope that it's been of some help one way or another.
// A simple product list.
const ProductList = () => {
const products = [];
let el = null;
// What you wish to return, aka an object...
return {
addProduct: (name, price) => {
products.push({
name: name,
price: price
});
onUpdate();
render(el, products);
},
setRoot: root => {
el = root;
},
// removeFromList, etc...
};
};
// A simple on update function.
const onUpdate = () => {
console.clear();
console.log('Update!');
};
// A 'simple' render function.
const render = (el, products) => {
if (el == null) return;
const template = obj => `<li>${obj.name} €${obj.price}</li>`;
let html = '';
products.forEach(product => html += template(product));
el.innerHTML = html;
};
// A function to dispatch some event(s).
const dispatchEvents = products => {
const btn = document.getElementById("btn");
const price = document.getElementById("price");
const name = document.getElementById("name");
// Just an example.
const isValid = () => {
if (price.value != '' && name.value != '') return true;
return false;
};
// Handle the on click event.
btn.onclick = () => {
if (isValid()) {
products.addProduct(name.value, price.value);
name.value = '';
price.value = '';
}
};
};
// A simple dom ready function.
const ready = () => {
const products = ProductList();
products.setRoot(document.getElementById("productList"));
products.addProduct('Demo', 10);
products.addProduct('Other', 19.99);
dispatchEvents(products);
};
document.addEventListener("DOMContentLoaded", ready);
<div>
<label for="name">name:</label>
<input type="text" id="name" />
</div>
<div>
<label for="price">Prijs:</label>
<input type="number" id="price" />
</div>
<input type="button" id="btn" value="Update" />
<ol id="productList">
</ol>

Categories