I have a mobile app where I want users to be able to save locations in their localStorage. I have a blank HTML page called "Saved Locations." When a user navigates to this page, I want hyperlinks to be created dynamically from whatever locations are saved in the device. I'm able to iterate through the keys and list them, but I've had trouble trying to create div elements on the fly. Here's my JavaScript:
myApp.onPageInit('saved_locations', function (page) {
var fragment = document.createDocumentFragment();
var parent = document.getElementById("saved");
// iterate localStorage
for (var i = 0; i < localStorage.length; i++) {
// set iteration key name
var key = localStorage.key(i);
// use key name to retrieve the corresponding value
var value = localStorage.getItem(key);
// console.log the iteration key and value
console.log('Key: ' + key + ', Value: ' + value);
let node = document.createElement("div") ;
let text = document.createTextNode(key); //value is taken from your loop
node.appendChild(text);
fragment.appendChild(node);
}
parent.appendChild(fragment);
});
Assign and Id to the element where you want them to appear. Then
var fragment = document.createDocumentFragment();
var parent = document.getElementById("yourId");
loop goes here {
let node = document.createElement("div") ;
let text = document.createTextNode(value); //value is taken from your loop
node.appendChild(text);
fragment.appendChild(node);
}
parent.appendChild(fragment);
Related
I've recently started to work my Todo list without relying on coding tutorials and it's so difficult. I'm able to add items in my list, but I'm not able to remove items. When I click on items, all items gets deleted. Could you help please?
<fieldset>
<legend class="task-list-title">Goals that I need to work on</legend>
<input
id="inpKey"
type="text"
placeholder="add new goal"
aria-label="new list name"
<button type="button" id="btnInsert">New Goal</button>
<div id="task_list">
</div>
</fieldset>
JavaScript Code
const inpKey = document.getElementById("inpKey");
const btnInsert = document.getElementById("btnInsert");
const task_list = document.getElementById("task_list");
btnInsert.onclick = function() {
const key = inpKey.value;
if(key) {
localStorage.setItem(key, inpKey.value);
location.reload();
}
}
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
task_list.innerHTML += `${key}<br />`
}
task_list.onclick = function() {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
window.localStorage.removeItem(key);
task_list.innerHTML = key;
}
}
So I believe the problem was you not checking for which particular todo to delete, instead you were deleting them all
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
// I it would be better if you wrapped each key in its own element
task_list.innerHTML += `<div>${key}</div>`; // I'm using a `div` so there'll be no need for a `<br/>` tag
}
task_list.onclick = function(e) {
// I want to use the event data to find out exactly which localStorage key to delete
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
// Here i'm checking if the key is the same as the todo that you want to delete
if (key == e.target.innerText) {
localStorage.removeItem(key); // Removing the todo from storage
e.target.remove(); // Removing the todo element from the DOM
}
}
}
Appending the new key to the innerHTML for tasks_list makes it very difficult to get the key when you want to delete the item. Instead it would be easier to make each new task a <p> element (or an unordered list element) and to append that new element as a child to tasks_list like so-
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const newTask = document.createElement('p') //create a new html element
newTask.classList.add('task') //add a class of "task" to it
newTask.innerHTML = key //set the innerHTML to equal the key
task_list.appendChild(newTask) //add the newTask element as a child element of task_list
}
You can add event listeners to each element with the task class by looping through each and adding your event listener. The nice thing here is that when you want the key for an individual task you need only grab the innerHTML and use that-
for(let i = 0; i < tasks.length; i++) {
tasks[i].addEventListener("click", () => {
const key = tasks[i].innerHTML
window.localStorage.removeItem(key)
location.reload()
})
}
The way you currently removed items by looping through localStorage was actually removing an element on each pass through of the loop and not checking to see if the item it was removing was the item that had been clicked.
EDIT- a. mola's answer does something similar to mine but you don't need to loop through the entirety of local storage to find your matching key. That's the beauty of having key/value pairs! As long as you know the key you can manipulate the data without having to first search for it through a loop.
Primary requirement
What I really wants to achieve is that there is a text box with a button where user can input values and then those values will be saved into localStorage via different keys (so that even in page refresh these values can be retrieved) and also inserted values will be displayed under the text box.
What I did to accomplish this:
HTML
<div>
<input type="text" name="userInputs" placeholder="Please insert the value" id="idUserInputs">
<button onclick="insertUserInput()">Add</button>
<p id="hiddenP"></p>
</div>
JavaScript
<script>
var i = 0;
function insertUserInput() {
i++;
//fetch the value
var insertedValue = document.getElementById("idUserInputs").value;
//set the value to show user
document.getElementById("hiddenP").innerHTML = insertedValue;
//set the value to localstorage with different key(via incremental i)
window.localStorage.setItem("savedValues" + i, insertedValue);
}
</script>
To retrieve the data if user refresh the tab just added <body onload=funcrtion() and the function coded as shown below:
<body onload="onloadRetrieveData()">
function onloadRetrieveData() {
//check the length
var length = localStorage.length;
var x;
for (x = 1; x <= length; x++) {
document.getElementById("hiddenP").innerHTML = window.localStorage.getItem('savedValues' + x);
}
This will retrieve the last data that user inserted. Like below
I started this based on this article
The complete guide to using localStorage in JavaScript apps
What I wants right now is when user refresh the tab all saved data in local storage to be retrieve and show to user. Can anyone help me with this? Thanks
Here is one way one way to accomplish this, using the code you already have with a few small adjustments for how you add the final result to the DOM:
var hiddenP = document.getElementById('hiddenP');
var ul = document.createElement('ul');
function onloadRetriveData() {
//check the length
var length = localStorage.length;
var storedValues = [];
console.log(length);
var x;
for (x = 1; x <= length; x++) {
var li = document.createElement('li');
var textContent = document.createTextNode(window.localStorage.getItem('savedValues' + x));
li.appendChild(textContent);
ul.appendChild(li);
}
hiddenP.appendChild(ul);
}
That would show all of the items in local storage in an unordered list, you could of course choose to display them in any format you wish.
Here is a short summary of what's going on, in case anything is unclear.
Code Summary
In this version, we are creating an unordered list:
var ul = document.createElement('ul');
Then, we add each item from local storage to the list as we go through the loop:
for (x = 1; x <= length; x++) {
var li = document.createElement('li');
var textContent = document.createTextNode(window.localStorage.getItem('savedValues' + x));
li.appendChild(textContent);
ul.appendChild(li);
}
Notice that we create a new list element each pass:
var li = document.createElement('li');
Then, we create a textNode with the item from local storage as the value:
var textContent = document.createTextNode(window.localStorage.getItem('savedValues' + x));
Then, we add this text node to the list item and finally add the list item to the unordered list using the appendChild() method:
li.appendChild(textContent);
ul.appendChild(li);
Then, after the loop, we add the whole list to the hiddenP paragraph element, again using the appendChild() method:
hiddenP.appendChild(ul);
I have the following javascript code that does not work as I would expect it to. I have a list of checkboxes of which two of the items are "TestDuration" and "AssessmentScores". I'm trying to iterate through the list (which works fine) and have it add the values that are checked to the array.
var SAIndex = 0;
var SSIndex = 0;
var ScoresIndex = 0;
var SubAssessments = [];
var SubAssessmentScores = [];
//Get to the container element
var SSList = document.getElementById("islSubAssessmentScore_container");
//turn it into an array of the checkbox inputs
SSList = SSList.getElementsByTagName("input");
//create a temporary object to store my values
var tempPair = new Object();
//iterate through the checkbox lists
for(var i = 1; i < SSList.length;i++)
{
//if the value is checked add it to the array
if (SSList[i].checked)
{
var P = SubAssessments[SAIndex];
var V = SSList[i].value;
//tempPair.Parent = SubAssessments[SAIndex];
tempPair.Parent = P;
//tempPair.Value = SSList[i].value;
tempPair.Value = V;
//show me the values as they exist on the page
alert(tempPair.Parent + "|" + tempPair.Value);
SubAssessmentScores.push(tempPair);
//show me the values I just added to the array
alert(SubAssessmentScores.length-1 + "|" + SubAssessmentScores[SubAssessmentScores.length-1].Parent + "|" + SubAssessmentScores[SubAssessmentScores.length-1].Value);
//uncheck the values so when I refresh that section of the page the list is empty
SSList[i].checked = false;
}
}
//output the list of objects I just created
for (i = 0;i < SubAssessmentScores.length;i++)
alert(i + "|" + SubAssessmentScores[i].Parent + "|" + SubAssessmentScores[i].Value)
Now what happens is that when I iterate through the list I get the following alerts:
-first pass-
StudentID|TestDuration
0|StudentID|TestDuration
-second pass-
StudentID|AssessmentScores
1|StudentID|AssessmentScores
This is what I expect to output... However at the end of the code snippet when it runs the for loops to spit out all the values I get the following alerts...
0|StudentID|AssessmentScores
1|StudentID|AssessmentScores
I can't for the life of me figure out why it's replacing the first value with the second value. I thought it might be using a reference variable which is why I added in the P and V variables to try to get around that if that was the case, but the results are the same.
This is because you are adding the same variable every iteration of the loop.
Try changing your push like this:
SubAssessmentScores.push({
Parent: P,
Value: V
});
That said, I recommend you study a little more javascript and conventions in the language, for example your variable naming is frowned upon because you should only use capital letters on the beginning of a name for constructor functions.
A good book is Javascript the good parts by Douglas Crockford.
I've been trying this for a while now and could not find anything online...
I have a project, where tablerows get added to a table. Works fine.
Now I want to save the Table in the localStorage, so I can load it again. (overwrite the existing table).
function saveProject(){
//TODO: Implement Save functionality
var projects = [];
projects.push($('#tubes table')[0].innerHTML);
localStorage.setItem('projects', projects);
//console.log(localStorage.getItem('projects'));
The problem is the Array "projects" has (after one save) 2000+ elements. But all I want is the whole table to be saved to the first (or appending later) index.
In the end I want the different Saves to be listed on a Option element:
function loadSaveStates(){
alert('loading saved states...');
var projects = localStorage.getItem('projects');
select = document.getElementById('selectSave'); //my Dropdown
var length = projects.length,
element = null;
console.log(length);
for (var i = 0; i < length; i++) {
element = projects[i];
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = 'project ' + i;
select.appendChild(opt);
}
}
Can anyone tell me what I am doing wrong?
You can easily do this by jquery, are you interested in this, if yes.. then try following code
For setting the value
$.jStorage.set("projects", $.trim(projects));
For Getting the data
$.jStorage.get("projects");
For deleting the data with key
$.jStorage.deleteKey("projects");
I coose to stay with localStorage, but insted of using an Array I just let the user give every project a name and create a new Item for every Save:
function saveProject(){
//TODO: Implement Save functionality
var pname=prompt("Please enter your project name:","projectname")
var text = $('#mainTable')[0].innerHTML;
//console.log(text);
localStorage.setItem(pname, text);
//console.log(localStorage.key(2));
loadSaveStates();
}
function loadProject(){
var selected = $('#selectSave')[0].selectedIndex
//console.log(selected);
if (localStorage.key(selected) == 'jStorage'){
selected++;
}
var innerHTMLTable = localStorage[localStorage.key(selected)];
//console.log(innerHTMLTable);
$('#mainTable')[0].innerHTML = innerHTMLTable;
updateHandlers();
}
function deleteProject(){
var selected = $('#selectSave')[0].selectedIndex
var pname = $('#selectSave')[0].options[selected].value
$('#selectSave')[0].remove(selected);
localStorage.removeItem(pname);
//console.log(pname);
loadSaveStates();
}
I was trying to get the country name and put it in the temparray, so that I can use the temparray to check the country (line 14). The problem is temparray can only contain one value and upon increasing the array length size by using temparray.length = 4, the heat map won't show up in the page.
The code below is to check duplicate name entry from within the array. If the country name is repeated, it will add the past value and its current value and add it into the data table again as the old row.
var i;
var suq = 0;
var temparray = [""];
var rowcount= 0;
//set the value
for (i = 0; i<count; i++){
var countryname = countryarray[i];
var hostcount = hosthitcount[i];
//document.write("hello");
for (rowcount=0;rowcount<temparray.length;rowcount++){
//check for any repeated country name
if (temparray[rowcount] != countryname){
data.setValue(suq, 0, countryname);
data.setValue(suq, 1, hostcount);
temparray[rowcount] = countryname;
//document.write("win");document.write("<br/>");
suq++;
}else{
//get the hits //rowindex
var pastvalue = data.getValue(rowcount,1);
//add the previous value with current value
var value = parseInt(hostcount)+parseInt(pastvalue);
value+= "";
//document.write(value);
//put it in the table
data.setValue(rowcount,1,value);
// document.write("lose");document.write("<br/>");
}
}
}
I don't really understand what you are trying to do with temparray. It can surely contain more than one element with a temparray.push(countryname). Maybe this JavaScript array reference will help you?