How to populate multiple HTML DOM elements with local storage values - javascript

I want to display contents in the last <div> element when a click event occurs but now it only shows 1st 2 elements. Is there something I am not doing right somewhere?
Here is my code so far:
JS
const iname = document.getElementById("name");
const iemail = document.getElementById("email");
const iphone = document.getElementById("phone");
const submit = document.getElementById("submit");
const storage = document.getElementById("storage");
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
localStorage.setItem(name, "");
localStorage.setItem(email, "");
localStorage.setItem(phoneno, "");
location.reload();
}
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `Name : ${key}<br />Email : ${value}`;
}
localStorage.clear()
HTML
<p>Name</p>
<input id="name" autocomplete="off">
<p>Email</p>
<input id="email" autocomplete="off">
<p>Phone no</p>
<input id="phone" autocomplete="off">
<button id="submit">Let's go</button>
<div id="storage" class="box">
<h1>Is this correct?</h1></div>

I think you are setting the values in localstorage the wrong way.
The syntax for storing stuff in there is localstorage.setItem(keyName, keyValue).
And your code is setting the keyName argument to the value you are getting from the form and keyValue argument to an empty string; not what you need.
Make the following changes and you should be good to go (see comments):
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
// set local storage values
localStorage.setItem("name", name); // modified
localStorage.setItem("email", email); // modified
localStorage.setItem("phoneno", phoneno); // modified
location.reload();
}
console.log(localStorage); // new (maybe unnecessary)
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `${upFirst(key)}: ${value}<br>`; // modified
}
localStorage.clear();
/**
* new: making the first letter an upper case (for labels in the output div).
* See usage in 'for loop' above.
*/
function upFirst(stringValue) {
return stringValue.slice(0, 1).toUpperCase() + stringValue.slice(1);
}

Related

Going through each child in a div generated from API in javascript

I'm trying to access and delete the child in a div generated when I press the "submit" button, the individual divs inside will be generated because there are some functions running with the click, but when I press refresh to delete them nothing happened.
For more clarification here's the src: https://github.com/espnal/wdd230-final-project/blob/main/javascript/js.js
(This is my first post here if you have any suggestions I'm open)
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0]
let dayweather = "Sunday"
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0]["icon"]}#2x.png`;
let individualDiv = document.createElement("Div")
individualDiv.className = "individual"
let description = document.createElement("p")
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4")
day.innerHTML = dayweather
let temperature = document.createElement("p")
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`
let hum = document.createElement("p")
hum.innerHTML = `${firstItem.main.humidity}%`
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city)
SecondItemF(list, city)
ThirdItemF(list, city)
})
});
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.classList.remove("individual");
})
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>
You need to use a linter like this one: https://jshint.com Your code needs a ton of semi-colons and you're missing a bracket and parenthesis }) that .fetch() or submit handler needs. I edited your question just so it doesn't irritate anyone trying to answer the question. You'll see the comment at the bottom of this example showing where I added it, but I guessed because there's no way to test it since there's no key for the API (but not expecting one, so worries there).
Besides that problem, the solution for the problem addressed in the question is the following:
Remove:
contentDiv.classList.remove("individual");
And add:
contentDiv.replaceChildren();
Removing a class doesn't remove the actual elements (well normally unless there's some very convoluted logic going on). .replaceChildren(); without a parameter will remove everything within contentDiv, but if you nee to just remove .individual do the following:
document.querySelector('.individual').remove();
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0];
let dayweather = "Sunday";
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0].icon}#2x.png`;
let individualDiv = document.createElement("Div");
individualDiv.className = "individual";
let description = document.createElement("p");
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4");
day.innerHTML = dayweather;
let temperature = document.createElement("p");
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`;
let hum = document.createElement("p");
hum.innerHTML = `${firstItem.main.humidity}%`;
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`;
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city);
SecondItemF(list, city);
ThirdItemF(list, city);
});
});// <= This is missing
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.replaceChildren();
});
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>

Repeating a div based on user input (JavaScript solution preferred)

Looking for the simplest implementation of the following problem:
I have a user input number field like:
<input type="number" id="numInput" name="numInput" value="1" onchange="myFunc()">
<div id="demo">*** TEST ***</div>
I want to replicate the #demo div based on the #numInput value entered by the user, e.g. if the user enters '5', there would be five #demo divs displayed on the page. At the moment, I'm using the following function:
function myFunc() {
var newArray = [];
var numInput = document.getElementById('numInput').value;
var x = document.getElementById('demo').innerHTML;
for(var i=0; i<numInput; i++) {
newArray.push(x);
}
document.getElementById('demo').innerHTML = newArray;
}
but this is adding to the existing array rather than outputting the exact number of divs based on user input. Please advise. Thanks.
There should not be multiple same id values.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newDiv = document.createElement('div');
newDiv.setAttribute('id', 'demo' + i);
newDiv.innerHTML = '*** TEST ***';
numInput.parentNode.insertBefore(newDiv, numInput.nextSibling);
}
}
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
+Edit
You can also manipulate <form> with javascript.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newInput = document.createElement('input');
newInput.setAttribute('id', 'demoInput' + i);
newInput.setAttribute('type', 'text');
newInput.setAttribute('name', 'demoInputName' + i);
newInput.setAttribute('onchange', 'myFormChangeListener(this)');
numInput.parentNode.insertBefore(newInput, numInput.nextSibling);
numInput.parentNode.insertBefore(document.createElement('br'), numInput.nextSibling);
}
}
function myFormChangeListener(element) {
console.log(element);
console.log(element.value);
myForm.action = 'http://the.url/';
myForm.method = 'post';
console.log(myForm);
//myForm.submit;
}
<form id="myForm">
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
</form>

how to call a function with a submit element [duplicate]

This question already has answers here:
Why can't I get the input from the input box?
(6 answers)
Closed 1 year ago.
I'm trying to call a function using an event listener but for some reason, it won't work. I'm not getting any errors in my javascript or HTML, so what's the deal?
// Data
const clicks = document.getElementById('loc');
const input = document.getElementById('input').value;
const check = document.getElementById('check');
var totalClicks = 0;
var wToType = "var loc = 0";
// functions
function checkCode() {
if (input === wToType) {
totalClicks += 1
clicks.textContent = "Lines of code:" + totalClicks;
}
};
// Event listeners
check.addEventListener("click", checkCode, false);
<h1 id="loc">Lines of code: 0</h1><br><br>
<h3 id="wtt">Lets get started with our loc (lines of code) variable. Type "var loc = 0"</h3>
<input type="text" name="myInput" id="input" size="25" required>
<input type="submit" id="check" value="Write line(s) of code">
Write
const input = document.getElementById('input')
in the line 2, and
input.value == wToType
in line 11.
It's better to take the value from your input right during calling the function.
Here is the right JS code:
// Data
let clicks = document.getElementById('loc');
const check = document.getElementById('check');
let totalClicks = 0;
let wToType = "var loc = 0";
// functions
function checkCode() {
const input = document.getElementById('input').value;
if(input === wToType) {
totalClicks += 1
clicks.textContent = "Lines of code: " + totalClicks;
}
};
// Event listeners
check.addEventListener("click", checkCode, false);

Javascript loop array for form validation

I have a table form with some rows, that are controlled by user. Meaning they can add as more as they want. Let's pretend user requested 5 rows and i need to check if they all have values.
function validateForm() {
var lastRowInserted = $("#packageAdd tr:last input").attr("name"); // gives me "packageItemName5"
var lastCharRow = lastRowInserted.substr(lastRowInserted.length - 1); // gives me 5
var i;
for (i = 1; i <= lastCharRow; i++) {
var nameValidate[] = document.forms["packageForm"]["packageItemName"].value;
if(nameValidate[i].length<1){
alert('Please fill: '+nameValidate[i]);
return false;
}
}
}
How can i receive packageItemName1 to 5 values in a loop so then I can use to validate them. Want the loop to process this code
var nameValidate[] = document.forms["packageForm"]["packageItemName1"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName2"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName3"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName4"].value;
var nameValidate[] = document.forms["packageForm"]["packageItemName5"].value;
Like this
const validatePackageItems = () => {
const nameValidate = $("form[name=packageForm] input[name^=packageItemName]"); // all fields with name starting with packageItemName
const vals = nameValidate.map(function() { return this.value }).get(); // all values
const filled = vals.filter(val => val.trim() !== ""); // all values not empty
console.log("Filled", filled, "= ", filled.length, "filled of", vals.length)
return filled.length === vals.length
};
$("[name=packageForm]").on("submit",(e) => {
if (!validatePackageItems()) {
alert("not valid");
e.preventDefault();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="packageForm">
<input type="text" name="packageItemName1" value="one" /><br/>
<input type="text" name="packageItemName2" value="two" /><br/>
<input type="text" name="packageItemName3" value="" /><br/>
<input type="text" name="packageItemName4" value="four" /><br/>
<input type="submit">
</form>
You can use string interpolation to get the key dynamically:
for (let i = 1; i < 6; i++) {
const currentValue = document.forms.packageForm[`packageItemName${i}`]
console.log('current value:', currentValue)
}

The sum cannot show although i click on the button

What I want is, after the user enters the number of subjects, the system will show the number of input box according to the number of subjects entered, then when the user clicks on the button, it should show the sum. I tried many ways, but I failed to show the sum, anyone knows what is the mistake I made?
Below is my code:
function select() {
var x = parseInt(document.getElementById('1').value);
if (document.getElementById('1').value == "") {
alert("Please fill up number of subject");
} else if (isNaN(x) == true) {
alert("Please fill up number of subject with number");
} else {
var subject = parseInt(document.getElementById('1').value);
var sum = 0;
for (var num = 1; num <= subject; num++) {
document.write("Enter the mark for subject " + num + " : ");
var value = parseFloat(document.write("<input/><br>"));
sum += value;
}
var calc = document.write("<button>Next</button><br>");
calc.onclick = function() {
next()
};
function next() {
document.write("Total marks: " + sum + "%");
}
}
}
<html>
<body>
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</body>
</html>
That's how I have rewritten a big part of your code. I have place inline comments to explain what I do.
function select() {
var x = parseInt(document.getElementById('1').value, 10);
// Getting the div that wraps the initial form.
var formWrapper = document.querySelector('.formWrapper');
// Getting the div, that is going to display the new fields and the results.
var results = document.querySelector('.results');
// I have switch your statement from x == '' to '' === x as it
// consists a good practice
if ( '' === x ) {
alert("Please fill up number of subject");
// I have remove the isNaN(x) == true, because the isNan will
// be either true or false.
} else if ( isNaN(x) ) {
alert("Please fill up number of subject with number");
} else {
// Using parseInt(x, 10) to set the base.
var subject = parseInt(x, 10);
// In this array, I store the auto-generated fields.
var fieldsList = [];
// Removing the first div from the DOM
formWrapper.parentElement.removeChild(formWrapper);
for ( var num = 1; num <= subject; num++ ) {
// I am creating a new field
var newField = document.createElement('input');
// I push the field into the array I made for the fields.
fieldsList.push(newField);
// I append the field in the HTML
results.appendChild(newField);
// I create a <br> tag
var br = document.createElement('br');
// And I append the tag in the DOM
results.appendChild(br);
}
// I create the button that is going to handle the Next functionality
var nextButton = document.createElement('button');
// I set the button text
nextButton.innerText = 'Next';
// I add an Event Listener for the click event.
nextButton.addEventListener(
'click',
function() {
// I reset the sum to 0
var sum = 0;
// I itterate the fields auto-generated and saved in the array
fieldsList.forEach(
function(field) {
// I get the value
sum += parseInt(field.value, 10);
}
);
// I create the field that is going to display the output
let resultText = document.createElement('div');
// I set the text based on the sum
resultText.innerText = "Total marks: " + sum + "%";
// I append the text message to the DOM
results.appendChild(resultText);
}
);
// I append the button to the DOM
results.appendChild(nextButton);
}
}
<html>
<body>
<div class="formWrapper">
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</div>
<div class="results"></div>
</body>
</html>

Categories

Resources