Simplifying code using localStorage - javascript

I wanted to find out whether it was possible to use a loop to simplify all this rather than hard-coding the entire structure. For the second part of my Javascript where I tried to store the user inputs into localStorage using a for loop, I'm getting an error where it says
CreateEvent.js:72 Uncaught TypeError: name.push is not a function at createReplace (CreateEvent.js:72) at HTMLButtonElement.onclick (CreateEvent.html:130)
HTML:
<span class="border1">
<input class="forms" type="text" id="title" placeholder="Enter Title!">
<p id="title1"></p>
<input class="forms" type="text" id="brief" placeholder="Enter brief description!">
<p id="brief1"></p>
</span>
<div class="Hovertrees">
<p>Hover over me!</p>
<span class="Hovertrees2">
<input class="hover" type="text" id="hover" placeholder="Enter some fun facts!">
<p id="hover1"></p>
</span>
</div>
<div id="what">
<input class="forms" type="text" id="whattitle" placeholder="What is this event?">
<h2 id="whattitle1"></h2>
<input class="forms" type="text" id="whatdesc" placeholder="Enter brief description!">
<p id="whatdesc1"></p>
</div>
<div id="why">
<input class="forms" type="text" id="whytitle" placeholder="Why is this event important?">
<h2 id="whytitle1"></h2>
<input class="forms" type="text" id="whydesc" placeholder="Description of this event">
<p id="whydesc1"></p>
</div>
<div id="fun">
<input class="forms" type="text" id="funtitle" placeholder="Anything interesting you can add!">
<h3 id="funtitle1"></h3>
<input class="forms" type="text" id="fundesc" placeholder="Description of the interesting info!">
<p id="fundesc1"></p>
</div>
Javascript:
var title;
var brief;
var hover;
var whatTitle;
var whatDesc;
var whyTitle;
var whyDesc;
var funTitle;
var funDesc;
function createReplace() {
title = document.getElementById('title').value;
document.getElementById('title1').innerHTML = title;
document.getElementById('title').className = 'hidden';
document.getElementById('news').innerHTML = title;
brief = document.getElementById('brief').value;
document.getElementById('brief1').innerHTML = brief;
document.getElementById('brief').className = 'hidden';
hover = document.getElementById('hover').value;
document.getElementById('hover1').innerHTML = hover;
document.getElementById('hover').className = 'hidden';
whatTitle = document.getElementById('whattitle').value;
document.getElementById('whattitle1').innerHTML = whatTitle;
document.getElementById('whattitle').className = 'hidden';
whatDesc = document.getElementById('whatdesc').value;
document.getElementById('whatdesc1').innerHTML = whatDesc;
document.getElementById('whatdesc').className = 'hidden';
whyTitle = document.getElementById('whytitle').value;
document.getElementById('whytitle1').innerHTML = whyTitle;
document.getElementById('whytitle').className = 'hidden';
whyDesc = document.getElementById('whydesc').value;
document.getElementById('whydesc1').innerHTML = whyDesc;
document.getElementById('whydesc').className = 'hidden';
funTitle = document.getElementById('funtitle').value;
document.getElementById('funtitle1').innerHTML = funTitle;
document.getElementById('funtitle').className = 'hidden';
funDesc = document.getElementById('fundesc').value;
document.getElementById('fundesc1').innerHTML = funDesc;
document.getElementById('fundesc').className = 'hidden';
document.getElementById("create").className = "hidden";
var varNames = [
'titles',
'brief',
'hover',
'whatTitle',
'whatDesc',
'whyTitle',
'funtitle',
'fundesc'
]
for (var name in varNames) {
var value = window[name]
var obj = {name : value};
if(localStorage.getItem(name) != null) {
var tmp = JSON.parse(localStorage.getItem(name));
for(var i = 0;i<tmp.length;i++) {
name.push(tmp[i]);
}
}
name.push(obj);
localStorage.setItem(name, JSON.stringify(value));
}
}

For the first part, simplifying is not possible since you have different properties for each elements.
For the second part, you are getting error because push is a method for array object.But name is an string object declared in for loop
for (var name in varNames) {
var value = window[name]
var obj = {name : value};
if(localStorage.getItem(name) != null) {
var tmp = JSON.parse(localStorage.getItem(name));
for(var i = 0;i<tmp.length;i++) {
name.push(tmp[i]);
}
}
name.push(obj);
localStorage.setItem(name, JSON.stringify(value));
}
}

You can set item in loop
localStorage.setItem(1,'name1');
localStorage.setItem(2,'name2');
localStorage.setItem(3,'name2');
1 2 and 3 would be key that you want to set and then get according to these keys.
localStorage.key(index)
By passing index in key method it will return you the value of that key.

Related

Why can't I see the query parameters in the form present in the url?

I'm having a problem getting the form values by passing the two query parameters, id and type, from the url.
Let's assume the URL is:
... page.html?id=14&type=Title
I want the values of these to be shown in the form to then make the change later.
function getQueryVariable () {
var query = window.location.search.substring (1);
var vars = query.split ("&");
for (var i = 0; i <vars.length; i ++) {
var pair = vars [i] .split ("=");
}
}
function onLoad () {
var value = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = value;
type.value = value;
}
<div class = "container">
<form method ="post" id="save" action="javascript: myFunction()" onload="onLoad()">
<div class = "field">
<label for = "id"> ID: </label>
<input type = "number" id = "id" name = "id" />
</div>
<div class = "field">
<label for = "type"> Fragment Type: </label>
<input type = "text" id = "type" name = "type" />
</div>
<div class = "field">
<button type = "submit" class = "full"> Save changes </button>
</div>
</form>
</div>
As you can see from the code, I call the onLoad() function to load the data into the form.
I don't get any errors; the values of the getQueryVariable() function variables are correct, but I notice that it is not called.
myFunction() is not shown, but this is the function that will serve me later to modify the fields of the form.
Could you kindly help me?
First of all, you need to execute onLoad function,
then you need to create an object to store the values and pass it to another function.
And your loop is really out of the world, I corrected it, please try to understand my code and if you have questions feel free to comment.
Here you go, for query, I changed it to a string that you provided as an exemple, so it would work in snippet.
function getQueryVariable () {
var object = {}
var query = "id=14&type=Hello%20Title";
var vars = query.split ("&");
for (var i = 0; i <vars.length; i ++) {
let splitted = vars[i].split('=')
object[splitted[0]] = decodeURI(splitted[1])
}
return object;
}
function onLoad () {
var pairs = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = pairs.id;
type.value = pairs.type;
}
onLoad();
<div class = "container">
<form method ="post" id="save" action="javascript: myFunction()" onload="onLoad()">
<div class = "field">
<label for = "id"> ID: </label>
<input type = "number" id = "id" name = "id" />
</div>
<div class = "field">
<label for = "type"> Fragment Type: </label>
<input type = "text" id = "type" name = "type" />
</div>
<div class = "field">
<button type = "submit" class = "full"> Save changes </button>
</div>
</form>
</div>
Your getQueryVariable () function is not returning anything. You can try something like this:
function getQueryVariable () {
var query = window.location.search.substring (1);
var vars = query.split ("&");
var params = {}
for (var i = 0; i <vars.length; i ++) {
var pair = vars [i] .split ("=");
params[pair[0]] = pair[1]
}
return params
}
function onLoad () {
var params = getQueryVariable ();
var id = document.getElementById ('id');
var type = document.getElementById ('type');
id.value = params.id ;
type.value = params.type ;
}

Updating LocalStorage Objects Based on Edit Form with JavaScript/jQuery?

I asked a question earlier with answers which didn't help, I still haven't been able to figure out where my issue is. Originally I thought it was because I had two IDs named the same but this was not the issue.. The form submits and there are no errors but it does not update the values in localStorage?
Edit: After changing const idx to const i the value at position [2] (or final value) would update for every booking (regardless of index). I thought of maybe changing the i value to below but it gives error i is defined before it is initialised?
bookings.findIndex(booking => bookings[i].fname == fname && bookings[i].lname == lname);
Here's what I have (updated code):
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
window.onload = showBooking();
$("#submit").click(function() {
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
showBooking();
});
// ~~~ edit bookings in localStorage
$(document).on('click','#edit',function (e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
const i = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);
deleteBooking(i);
bookings.push({
fname,
lname
});
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
// showBooking();
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
// var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
// $('#regForm').hide();
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname} </h3>
</div>`;
editBooking.innerHTML = `<input type="text" class="input" id="fname_${i}" placeholder="${bookings[i].fname}" name="${bookings[i].fname}" value="${bookings[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookings[i].lname}" name="${bookings[i].lname}" value="${bookings[i].lname}" required>
<input id="edit" type="submit" value="Edit">`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
My HTML form:
<form id="regForm" name="regForm" action="" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname" placeholder="First Name" name="fname" required>
<input type="text" class="input" id="lname"placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
<div id="result" class="row"></div>
<div id="currentItem" class="row"></div>
<div id="editAppt" class="row"></div>
There are several changes you need to consider
You have bookings AND bookingItems
You do some changes (I assume there will be some destination change) but do not save them
You parse the localStorage far too often. Not needed. Only read once and write when modified
You cannot have duplicate IDs so you need to delegate and use class names
Be consistent and use jQuery to create elements and to add events- for example the delete button should be d er legates and remove its closest form element
Here is how to find the booking based on names
const idx = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);

How to display array from local storage in html element?

Obviously, a beginner's question:
How do I get array data to display in an html element using html and javascript?
I'd like to display the user saved array data in a paragraph tag, list tag, or table tag, etc.
[http://www.mysamplecode.com/2012/04/html5-local-storage-session-tutorial.html]
Above is a link to the kindly provided example of localStorage except how to display the array on the html page rather than in the console.log.
Below is the code snip that demonstrates what I'm trying to do.
function saveArrayData() {
console.log("Saving array data to local storage.");
var myArrayObject = [];
var personObject1 = new Object();
personObject1.name = "Array1";
personObject1.age = 23;
myArrayObject.push(personObject1);
var personObject2 = new Object();
personObject2.name = "Array2";
personObject2.age = 24;
myArrayObject.push(personObject2);
var personObject3 = new Object();
personObject3.name = "Array3";
personObject3.age = 25;
myArrayObject.push(personObject3);
localStorage.setItem("persons", JSON.stringify(myArrayObject));
}
function restoreArrayData() {
console.log("Restoring array data from local storage.");
var myArrayObject = JSON.parse(localStorage.getItem("persons"));
for (var i = 0; i < myArrayObject.length; i++) {
var personObject = myArrayObject[i];
console.log("Name: " + personObject.name, "Age: " + personObject.age);
}
}
<label for="name">Name:</label>
<input type="text" data-clear-btn="true" name="name" id="name" value="">
<label for="age">Age:</label>
<input type="text" data-clear-btn="true" name="age" id="age" value="">
<br>
<br>
<input type="button" id="sArray" value="Save Array data" onclick="Javascript:saveArrayData()">
<input type="button" id="rArray" value="Restore Array data" onclick="Javascript:restoreArrayData()">
<p id="displayArrayDataHere"></p>
You should update your code like below:
function restoreArrayData() {
var myArrayObject = JSON.parse(localStorage.getItem("persons"));
$("#displayArrayDataHere").append("<table>");
myArrayObject.forEach(function(personObject) {
$("#displayArrayDataHere").append("<tr><td>"+personObject.name+"</td><td>"+personObject.age+"</td></tr>")
})
$("#displayArrayDataHere").append("</table>");
}

JS: Push to array and update select without getting duplicates

I am populating a SELECT with an array. The array contains strings with employee-names.
I want to be able to add a new employee name in the array and then update the SELECT. I've made this, but I keep getting duplicates as I call the function. I kind of understand why, but I haven't quite figured out yet how to make this code better so that I only add the one employee name that is written in the text input.
I don't want to have a function that removes all duplicates, as I think it should be possible to have several employees with the name "John".
My HTML:
<section id="sidebar">
<form onSubmit="return false">
<label for="Name">Name:</label>
<input id="nameInput" type="text" value="Your name here..." name="name" />
<input type="submit" value="Add to list" name="Add" onClick="addToArray();"><br>
<label for="Default">List over employees:</label>
<select id="employeeSelect">
</select>
</form>
</section>
My JS:
var employeeList = ['Sarah', 'Louse', 'Dan', 'John', 'Peter'];
function listEmployees(){
var select = document.getElementById('employeeSelect');
for (var i = 0; i < employeeList.length; i++)
{
var option = employeeList[i];
var newOption = document.createElement("option");
newOption.textContent = option;
newOption.value = option;
select.appendChild(newOption);
}
}
listEmployees();
function addToArray(){
var txtbox = document.getElementById('nameInput');
var value = txtbox.value;
employeeList.push(value);
listEmployees();
}
You're calling listEmployees() (which adds, and re-adds, everything in your list) each time a new name is added.
I'd move the add-a-new-option code out to its own function. Call it for each name in the original list, then call it again when a new name is added.
var employeeList = ['Sarah', 'Louse', 'Dan', 'John', 'Peter'];
function addEmployee(name) {
var select = document.getElementById('employeeSelect');
var newOption = document.createElement("option");
newOption.textContent = name;
newOption.value = name;
select.appendChild(newOption);
}
function listEmployees() {
for (var i = 0; i < employeeList.length; i++) {
addEmployee(employeeList[i])
}
}
listEmployees();
function addToArray() {
var txtbox = document.getElementById('nameInput');
var value = txtbox.value;
employeeList.push(value); // update the list
addEmployee(value); // update the select
}
<section id="sidebar">
<form onSubmit="return false">
<label for="Name">Name:</label>
<input id="nameInput" type="text" placeholder="Your name here..." name="name" />
<input type="submit" value="Add to list" name="Add" onClick="addToArray();">
<br>
<label for="Default">List over employees:</label>
<select id="employeeSelect">
</select>
</form>
</section>

Getting value of <p> without the use of innerHTML

first of all I'm sorry if this is a long code segment however, I'm trying to make a modal window which writes the thing you wrote in my user form and asks you to confirm it. I am currently in a class to learn Javascript and I'm not allowed to use innerHTML and I must write the "Firstname:" etc dynamically (the text for firstname) and am not allowed to just write it inside the popup window. I've gotten most stuff to work but the "Firstname:" "Lastname" etc comes up as "undefined" or (as you can see the thing I tried with just the first name in this case) comes up as "null".
Hopefully someone can shed some light on this subject for me, this is the HTML:
<form action="http://voyager.lnu.se/tekinet/kurser/dtt/wp_webbteknik/process_form.php" method="POST" id="userform" target="_blank">
<p id="formQuestion1">Förnamn</p>
<div id="error1"></div>
<input type="text" name="firstName" id="test"/>
<p id="formQuestion2">Efternamn</p>
<div id="error2"></div>
<input type="text" name="lastName" />
<p id="formQuestion3">Postnummer</p>
<div id="error3"></div>
<input type="text" name="postCode" id="codeText"/>
<p id="formQuestion4">E-post</p>
<div id="error4"></div>
<input type="text" name="eMail" />
<br />
<br />
<label id="model" class="formQuestion" for="priceModel">Prismodell</label>
<br />
<select name="Type" id="priceModel">
<option value="Låg" selected>Låg</option>
<option value="Medel">Medel</option>
<option value="Hög">Hög</option>
</select>
<br />
<br />
<br />
<input id="sendButton" type="submit" value="Genomför Köp" />
</form>
And here is the segment for the modal window (Javascript)
function popup(backgroundDiv) {
var popForm = document.getElementById("userform");
var myDiv = document.createElement("div");
myDiv.className = "popupWindow";
var priceModel = document.getElementById("priceModel");
// Knappar
var newButton = document.createElement("button");
var newerButton = document.createElement("button");
newButton.setAttribute("value", "Skicka");
newButton.innerHTML = "Skicka"; // Here I actually use innerHTML because I don't know
newerButton.innerHTML = "Stäng"; // any other way to set the text inside the button
newButton.className = "popupButton";
newerButton.className = "popupButton";
newButton.setAttribute("id", "Skicka");
newerButton.setAttribute("id", "Avbryt");
myDiv.appendChild(newButton);
myDiv.appendChild(newerButton);
// Information
var h1 = document.createElement("h1");
h1.setAttribute("id", "popuph1");
var h1Text = document.createTextNode("Vänligen kontrollera dina uppgifter");
var text = document.getElementById("formQuestion1");
var writeFname = text.nodeValue + popForm.elements.firstName.value;
var writeLname = document.getElementById("formQuestion2").value + popForm.elements.lastName.value;
var writeCode = document.getElementById("formQuestion3").value + popForm.elements.postCode.value;
var writeMail = document.getElementById("formQuestion4").value + popForm.elements.eMail.value;
var writePlan = document.getElementById("model").value + priceModel.value;
var p1 = document.createTextNode(writeFname);
var p2 = document.createTextNode(writeLname);
var p3 = document.createTextNode(writeCode);
var p4 = document.createTextNode(writeMail);
var p5 = document.createTextNode(writePlan);
h1.appendChild(h1Text);
myDiv.appendChild(h1);
myDiv.appendChild(p1);
myDiv.appendChild(document.createElement('br'));
myDiv.appendChild(p2);
myDiv.appendChild(document.createElement('br'));
myDiv.appendChild(p3);
myDiv.appendChild(document.createElement('br'));
myDiv.appendChild(p4);
myDiv.appendChild(document.createElement('br'));
myDiv.appendChild(p5);
document.body.appendChild(myDiv);
newButton.onclick = function () {
document.body.removeChild(myDiv);
document.body.removeChild(backgroundDiv);
return true;
};
If you don't want to use innerHTML then you can use those options, suppose you want value from this node <p id="formQuestion1">Förnamn</p>
Then your code would be
var dom = document.getElementById('formQuestion1');
1) var res = dom.innerText;
OR
2) var res = dom.textContent;
OR
3) var res = dom.firstChild.nodeValue;

Categories