How to store inputs multiple times into local storage - javascript

I am currently inputting values into local storage like this
<form name="myform" action="" method="GET">
Event Name: <INPUT TYPE="text" NAME="name" VALUE="" id="input1"><br />
Event Date and Time: <INPUT TYPE="datetime-local" NAME="date" Value="" id="input2"><br />
Event Location: <INPUT TYPE="text" NAME="location" VALUE="" id="input3"><br />
Event Notes: <INPUT TYPE="text" NAME="notes" VALUE="" id="input4"><br />
<button onclick="storeValues(event)" type=submit>Submit</button>
</form>
<script>
function storeValues(e) {
e.preventDefault();
let storedEvents = JSON.parse(localStorage.getItem("Events")) || [];
const newEventDetails = {
name: document.getElementById('input1').value,
dateTime: document.getElementById('input2').value,
location: document.getElementById('input3').value,
notes: document.getElementById('input4').value
}
storedEvents.push(newEventDetails);
localStorage.setItem("Events", JSON.stringify(storedEvents));
console.log('storedEvents', storedEvents);
}
</script>
However I found that I was unable to Output more than 1 value from local storage which I am currently achieving doing this.
<h2 class="title">Upcoming Events</h2>
<h3 id='input1'> </h3>
<h3 id='input2'> </h3>
<h3 id='input3'> </h3>
<h3 id='input4'> </h3>
<!-- running script here will populate H2's with values from local storage -->
<script>
document.getElementById('input1').innerText = localStorage.getItem('EventName');
document.getElementById('input2').innerText = localStorage.getItem("EventDateAndTime");
document.getElementById('input3').innerText = localStorage.getItem("EventLocation");
document.getElementById('input4').innerText = localStorage.getItem("EventNotes");
</script>
How would I be able to display the most recent input using those fields and then display ALL previous inputs on another page?

Your current code won't work, because you're retrieving items from EventName, EventDateAndTime, etc properties of local storage, but you never save to those properties, so they'll be null.
You're storing all the event info in a single property, localStorage.Events, which contains an array that you push to when you add a new event. So, to display the last item saved, you just need to access the top item in the array, and to display previous items saved, just access the appropriate previous index in the array:
const renderEvent = (event) => {
document.getElementById('input1').textContent = event.name;
document.getElementById('input2').textContent = event.dateTime;
document.getElementById('input3').textContent = event.location;
document.getElementById('input4').textContent = event.notes;
};
// Display last event:
const storedEvents = JSON.parse(localStorage.getItem("Events"));
if (!storedEvents) throw new Error('No events');
const lastEvent = storedEvents.pop();
renderEvent(lastEvent);
// Display nth event:
const index = 5; // for example: display 5th event saved
const storedEvents = JSON.parse(localStorage.getItem("Events"));
if (!storedEvents) throw new Error('No events');
const event = storedEvents[index];
renderEvent(event);

Related

Updating a localStorage Item Using JavaScript/jQuery?

I am sorry to keep asking this question but I am really struggling with it and I cannot figure out what is going wrong, I have read countless SO pages and general internet searches with no luck. A few people have helped me on here but the values are updating incorrectly so I thought it would be best to ask a fresh question with my most recent trials.
The challenge is to create a client-side (only) mock dog walking application based on localStorage, I so far am able to add, delete, and view appointments in the browser. I also have an edit function set up, however when I hit submit (#edit), the value at position [x] (end index) updates no matter which index I try to edit. Here is an example of my stored arrays in localStorage under key 'bookings':
[0]{fname: "John", lname: "Smith"}
[1]{fname: "Jane", lname: "Doe"}
[2]{fname: "David", lname: "Miller"}
When I hit edit on John Smith, for example, it will replace the values of David Miller, rather than Johns details. I thought of trying to find the index of each person similar to what I have done when finiding the values to display in HTML (bookings[i].lname), however this throws an error saying that i cannot be used before initialisation (makes sense, but not sure how to work around it).
Here is my most recent JS:
// ~~~ 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");
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 form for creating an appointment (this changes when editBooking is called):
<form id="regForm" name="regForm" action="" class="col-sm-6">
<div id="editAppt" 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>
You need to assign a unique identifier to each appointment. This will help fix your problem as you are currently identifying appointments by their first name, last name and position in the array.
When you edit an appointment, it removes it from its current position and adds it at the end which changes the index of all the current elements leading to your problem.
This would also cause problems if you had two appointments with the same name.
For a unique identifier, I suggest using new Date().getTime() for now.
var newBookings = {
id: new Date().getTime(),
fname: $('#fname').val(),
lname: $('#lname').val()
}
Once you've assigned a unique identifier to each appointment, you can change your Edit button so that it looks like this:
<input data-id="${bookings[i].id}" id="edit" type="submit" value="Edit">
Then in your Edit event handler, change the bottom part so that it looks like this:
let i = bookings.findIndex(booking => booking.id == $(this).data("id"));
bookings[i].fname = fname;
bookings[i].lname = lname;
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
So to explain, assign a unique identifier to each appointment, store the id in the data-id attribute, retrieve the data-id, find the index of the appointment with that id, update the appointment properties, save the bookings.
If you also want to improve the readability of your code, I suggest not mixing vanilla JavaScript and jQuery, i.e. document.getElementById("result") could be $("#result")

How do I display this information from the local storage on a different page

This is supposed to be a reminder app which has an input page to put the task and some information in and an output page which is supposed to contain all the things on the checklist.
What do I need to add to make the information go to the output page?
This is the code that stores the items locally and the html
<form id="todoForm">
<label for="ReminderInput">Reminder</label>
<input class="u-full-width" type="text" id="ReminderInput">
<label for="DateInput">Date</label>
<input class="u-full-width" type="datetime-local" id="DateInput">
<label for="InfoInput">Additional Information</label>
<textarea class="u-full-width" type="text" placeholder="Remember to..."
id="InfoInput"></textarea>
<button type="button" id="btn" class="button-primary">Add Reminder</button>
</form>
let reminders = [];
const addReminders = (ev) => {
ev.preventDefault();
let reminder = {
ReminderInput: document.getElementById("ReminderInput").value,
DateInput: document.getElementById("DateInput").value,
InfoInput: document.getElementById("InfoInput").value,
};
const arr = [reminder.ReminderInput, reminder.DateInput, reminder.InfoInput];
localStorage.setItem("todoForm", JSON.stringify(arr));
reminders.push([
reminder.ReminderInput,
reminder.DateInput,
reminder.InfoInput,
]);
localStorage.setItem("reminders", JSON.stringify(reminders));
};
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("btn").addEventListener("click", addReminders);
});
Use sessionStorage instead of localStorage
localStorage and sessionStorage accomplish the exact same thing and
have the same API, but with sessionStorage the data is persisted only
until the window or tab is closed
sessionStorage.setItem('todoForm', JSON.stringify(arr))
reminders.push([reminder.ReminderInput, reminder.DateInput, reminder.InfoInput]);
sessionStorage.setItem("reminders", JSON.stringify(reminders));
To get the keys above:
let todoForm = sessionStorage.getItem('todoForm');
let reminders = sessionStorage.getItem('reminders');
console.log(todoForm);
console.log(reminders);

JS Form: How do I push() into an array, without creating a new array every time I click Submit?

Every time I click Submit, its creating a new array with an object
Array should receive keep receiving objects and not create a new one
JS:
const form = document.querySelector('#form')
form.addEventListener('submit', (e) => {
e.preventDefault()
const title = document.querySelector('#title').value
const img = document.querySelector('#img').value
const story = document.querySelector('#story').value
const author = document.querySelector('#author').value
const eachStory = {
myTitle : title,
myImg : img,
myStory : story,
myAuthor : author
}
let stories = []
stories.push(eachStory)
stories.forEach((story) => {
root.innerHTML +=
`
${eachStory.myTitle}
${eachStory.myStory}
${eachStory.myImg}
${eachStory.myAuthor}
`
})
console.log(stories)
})
HTML:
<body>
<div>
<form id="form">
<input type="text" id="title" >
<input type="text" id="img" >
<input type="text" id="story" >
<input type="text" id="author" >
<button>SUBMIT</button>
</form>
<div id="root"></div>
</div>
Can someone tell me what I should do here?
I need to add objects to the same array every time i click submit
Everytime the form is submitted, the submit event fires up and the handler function is executed. Since, you are initializing a new stories array inside your function, every time the form is submitted, a new stories array is created.
You might want to move your stories array declaration out of the function, so that new posts are added to the existing the stories array.
const form = document.querySelector('#form')
let stories= [];
form.addEventListener('submit', (e) => {...}
First declare the array outside the submit handler. Secondly if you want to append it to the dom you can avoid the array and iterating it. Also iterating over the array may create duplication over row
const form = document.querySelector('#form')
let stories = []
form.addEventListener('submit', (e) => {
e.preventDefault()
const title = document.querySelector('#title').value;
const img = document.querySelector('#img').value;
const story = document.querySelector('#story').value;
const author = document.querySelector('#author').value;
root.innerHTML +=
`<div>
${title}
${img}
${story}
${author}</div>
`;
stories.push({
myTitle: title,
myImg: img,
myStory: story,
myAuthor: author
})
})
<div>
<form id="form">
<input type="text" id="title">
<input type="text" id="img">
<input type="text" id="story">
<input type="text" id="author">
<button>SUBMIT</button>
</form>
<div id="root"></div>
</div>
On Submit click it will create new Object and add in array.And next/every click it will add only object in existing array and not will remove the existing Object.
const form = document.querySelector("#form");
let stories = [];
form.addEventListener("submit", e => {
e.preventDefault();
const title = document.querySelector("#title").value;
const img = document.querySelector("#img").value;
const story = document.querySelector("#story").value;
const author = document.querySelector("#author").value;
var storyObj = {};
storyObj["myTitle"] = title;
storyObj["myImg"] = img;
storyObj["myStory"] = story;
storyObj["myAuthor"] = author;
stories.push(storyObj);
stories.forEach(story => {
root.innerHTML += `
${story.myTitle}
${story.myStory}
${story.myImg}
${story.myAuthor}
`;
});
console.log("Create data value==>+", JSON.stringify(stories));
});

How to stop overwriting object values

I create a function in which my input values of form are being collected in an object then afterwards I push whole object in an array and save my array in local Storage...But the problem is when I change the value and sign up again my old values are overwritten with new one but I want it to push on index 1 of array so that my array contain 2 objects and so on... Please help me Thanking You.
<script>
var labelsarray = document.getElementsByTagName("label");
var inputsarray = document.getElementsByTagName("input");
var array = [];
function subm() {
var users = {
FirstName: inputsarray[0].value,
LastName: inputsarray[1].value,
UserName: inputsarray[2].value,
Password:  inputsarray[3].value,
DateofBirth: inputsarray[4].value,
Age: inputsarray[5].value,
Purpose: ""
};
if (inputsarray[6].checked === true) {
users.Gender = "Male";
}
else if (inputsarray[7].checked === true) {
users.Gender = "Female";
}
if (inputsarray[8].checked === true) {
users.Purpose += " Storing Apps";
}
if (inputsarray[9].checked === true) {
users.Purpose += " Storing Sites";
}
if (inputsarray[10].checked === true) {
users.Purpose += " Fun";
}
array.push(users);
for (var i=0;i<array.length;i++) {
localStorage.setItem("User Data: ", JSON.stringify(array[i]));
}
}
</script>
<div>
<center>
<form action="Javascript:void(0);"method="post" onsubmit="subm();">
<label for="fname">First Name:</label> 
<input type="text" id="fname" />
<br/>
<label for="lname">Last Name:</label> 
<input type="text" id="lname" />
<br/>
<label for="uname">User Name:</label> 
<input type="text" id="uname" />
<br/>
<label for="pass">Password:</label>  
<input type="text" id="pass" />
<br/>
<label for="dob">Date of Birth:</label>  
<input type="date" id="dob" />
<br/>
<label>Age:</label>     
<input type="text" id="age" />
<br/>
<span>Gender:</span>     
<input type="radio" name="gender" id="male" />
<label for="male">Male</label>
<input type="radio" name="gender" id="female" />
<label for="female">Female</label>
<br/>
<p>For what purpose(s) you are making account?</p>
<input type="checkbox" id="app" name="purpose" value="storingapps" />
<label for="app">Storing Apps</label>
<input type="checkbox" id="site" name="purpose" value="storingsites" />
<label for="site">Storing Sites</label>
<input type="checkbox" id="fun" name="purpose" value="fun" />
<label for="fun">Fun</label>
<br/>
<input type="submit" value="Submit" class="button" />
</form>
</center>
</div>
Each time you save in your local storage you are saving just the last item. Because each save will be replaced by the next one and only the last one would be visible. Instead you only need to save the array into the local storage
// (not needed) for (var i=0;i<array.length;i++) {
localStorage.setItem("User Data: ", JSON.stringify(array));
// (not needed) }
Now your local storage will have array of objects
You're recreating your array every time instead of reading it from Local Storage. As such, you're starting with a fresh array every time.
Where you're doing var array = []; you should be reading from local storage.
For example:
var array = [];
var savedArrayJSON = localStorage.getItem("userData");
if (savedArray) {
try {
array = JSON.parse(savedArrayJSON);
} catch (e) {
// Probably do nothing
}
}
...
array.push(users);
// No more for-loop
localStorage.setItem("userData", JSON.stringify(array));
After you set up your array, you loop through it and upon each iteration you are overwriting the User Data key from the last iteration in localStorage, so only the last array item is getting stored:
for (var i=0;i<array.length;i++) {
localStorage.setItem("User Data: ", JSON.stringify(array[i]));
}
You should just set the entire array into local storage or make distinct keys to store the individual items with:
localStorage.setItem("User Data: ", JSON.stringify(array));
Next, each time someone comes to your page, you create a new, empty array, so when does the data in localStorage ever get pulled out and used? Upon page access, you should be getting the saved data so that you can push more into it:
// Set the array variable equal to the array in localStorage or an empty array
var array = JSON.parse(localStorage.getItem("User Data")) || [];
ADDITIONAL NOTES:
Your HTML is not valid and follows out of date methodologies.
Javascript:void(0);
Is not only mis-capitalized (should be: javascript:void()), but that entire technique for doing nothing shouldn't be used as well as onsubmit (HTML event handling attributes). All your JavaScript should be in dedicated scripts and event handling should be done using element.addEventListener().
<center> is deprecated. All formatting should be done with CSS.
<input> and <br> elements should not use the XML self-terminating syntax of /> at the end of the tag. While this is legal, it is a left-over relic of 2000 when the world thought that XML was going to be the future. It buys you nothing in your code and can lead to bugs when not used correctly.
You can try the following code.This occurs because you are overwriting the localStorage values everytime you are creating a new user.A simple solution is to store the users in array format and appending new users to it everytime a new user fill up form and then save it to the localStorage.
```
<script>
var labelsarray = document.getElementsByTagName("label");
var inputsarray = document.getElementsByTagName("input");
//Here We first Grab the already stored value from the localStorage and parse it because it is in string format.
var array = JSON.parse(localStorage.getItem('User Data: ')) || [];
function subm() {
var users = {
FirstName: inputsarray[0].value,
LastName: inputsarray[1].value,
UserName: inputsarray[2].value,
Password:  inputsarray[3].value,
DateofBirth: inputsarray[4].value,
Age: inputsarray[5].value,
Purpose: ""
};
if (inputsarray[6].checked === true) {
users.Gender = "Male";
}
else if (inputsarray[7].checked === true) {
users.Gender = "Female";
}
if (inputsarray[8].checked === true) {
users.Purpose += " Storing Apps";
}
if (inputsarray[9].checked === true) {
users.Purpose += " Storing Sites";
}
if (inputsarray[10].checked === true) {
users.Purpose += " Fun";
}
//We Now append the users to the array and save it to localStorage.
array.push(users);
localStorage.setItem("User Data: ", JSON.stringify(array));
}
```
I hope this works for you also.

HTML Form Submit to Google Calendar: Uncaught TypeError, Failed due to illegal value in property: 1

I believe I'm having a similar issue to this problem, but his solution isn't working for me.
I'm trying to have a Google App Script serve an HTML form that adds a Google Calendar event to my calendar.
Code.gs:
function doGet() {
return HtmlService.createHtmlOutputFromFile('form.html')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function scheduleEvent(array) {
CalendarApp.getDefaultCalendar().createEvent(array[0], array[1], array[2]);
return 1;
}
form.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="//netdna.bootstrapcdn.com/bootswatch/3.3.6/paper/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.4/moment-timezone-with-data-2010-2020.min.js"></script>
<style>body{padding:8px}</style>
</head>
<body>
<form class="form">
<fieldset>
<legend>Schedule a Meeting</legend>
<div class="form-group">
<label for="email">Your email:</label>
<input type="email" class="form-control" id="email" placeholder="you#gmail.com" required>
</div>
<div class="form-group">
<label for="eventName">What's the topic?</label>
<input type="text" class="form-control" id="eventName" required>
</div>
<div class="form-group">
<label for="eventLocation">Where?</label>
<input type="text" class="form-control" id="eventLocation" required>
</div>
<div class="form-group">
<label for="startTime">When? (EST)</label>
<input type="datetime-local" class="form-control" id="startTime" required>
</div>
<div class="form-group">
<label for="select">How Long?</label>
<select class="form-control" id="duration" required>
<option value="15">15 Minute Meeting</option>
<option value="30" selected>30 Minute Meeting</option>
<option value="60">60 Minute Meeting</option>
</select>
</div>
<button type="submit" class="btn btn-primary submit" onClick="preprocessForm(this.form)">Submit</button>
</fieldset>
</form>
<script type="text/javascript">
function preprocessForm (form) {
// check if they filled out their email, and set the variable if they did
if (form.email.value) {
var email = form.email.value;
} else {
alert("Please enter your email address, so I know who the appointment is with!");
event.preventDefault();
return 1;
}
// check if they filled out the event name, and set the variable if they did
if (form.eventName.value) {
var eventName = form.eventName.value;
} else {
alert("Please enter a name for the event!");
event.preventDefault();
return 1;
}
// set and format the event time and date, and grab the current time and date
var currentTime = moment().tz('America/New_York');
var startTime = moment(form.startTime.value).tz('America/New_York');
var formattedStartTime = startTime.toDate();
// html5 should stop the user from skipping filling out this section, but check anyway, just in case
if (!form.startTime.value) {
alert("Please enter a time for the event to occur!");
event.preventDefault();
return 1;
}
// we don't want people scheduling meetings in the past
if (startTime.isBefore(currentTime)) {
alert("Please pick a time that is in the future!");
console.log('Start Time: ' + startTime);
console.log('Current Time: ' + currentTime);
event.preventDefault();
return 1;
}
// check if they filled out the event location, and set the variable if they did
if (form.eventLocation.value) {
var eventLocation = form.eventLocation.value;
} else {
alert("Please enter an event location, so I know where to go!");
event.preventDefault();
return 1;
}
// it's not possible to skip the duration, since it's a dropdown that defaults to 30 minutes
var duration = form.duration.value;
var endTime = moment(startTime).add(duration, 'minutes');
var formattedEndTime = endTime.toDate();
var assembledDetails = [eventName, formattedStartTime, formattedEndTime];
//toadd: , {location: eventLocation, guests: email}
google.script.run.scheduleEvent(assembledDetails);
// things to try and stop the redirect/refresh when pressing the submit button
event.preventDefault();
return false;
}
</script>
</body>
</html>
I'm not having any luck. On submit, I get this error in the console:
Any advice?
Thanks!
You can't send a date object in the array. Property 1 is the second element in the array: assembledDetails
var assembledDetails = [eventName, formattedStartTime, formattedEndTime];
You could change the code to this:
formattedStartTime = formattedStartTime.toDateString();
formattedEndTime = formattedEndTime.toDateString();
var assembledDetails = [eventName, formattedStartTime, formattedEndTime];
Then you'd need to convert the date strings back to date objects in the server code.
Or:
You can strigify the object:
assembledDetails = JSON.stringify(assembledDetails);
google.script.run.scheduleEvent(assembledDetails);
And convert the object back in the server:
function scheduleEvent(array) {
array = JSON.parse(array);
Quote from documentation:
Requests fail if you attempt to pass a Date, Function, DOM element besides a form, or other prohibited type, including prohibited types inside objects or arrays.
Apps Script documentation - Parameters and return values

Categories

Resources