Printing List to DOM from array in Local Storage - javascript

I feel like I am very close on this.
Have a checklist which I'm pushing to an array, and setting to local storage. I want to reprint the list from local storage when the browser is re-instantiated
<script>
localStorage.clear();
var Array_ToDoList = [];
var toDoCount = 0;
$("#add-to-do").on("click", function(event) {
event.preventDefault();
var toDoTask = $("#to-do").val().trim();
Array_ToDoList.push(toDoTask)
localStorage.setItem("STR_Tasks", JSON.stringify(Array_ToDoList))
console.log(Array_ToDoList);
var toDoItem = $("<p>");
toDoItem.attr("id", "item-" + toDoCount);
toDoItem.append(" " + toDoTask);
var toDoClose = $("<button>");
toDoClose.attr("data-to-do", toDoCount);
toDoClose.addClass("checkbox");
toDoClose.append("✓");
toDoItem = toDoItem.prepend(toDoClose);
$("#to-dos").append(toDoItem);
$("#to-do").val("");
toDoCount++;
});
$(document.body).on("click", ".checkbox", function() {
var toDoNumber = $(this).attr("data-to-do");
$("#item-" + toDoNumber).remove();
Array_ToDoList.splice(toDoNumber, 1);
console.log(Array_ToDoList);
localStorage.setItem("STR_Tasks", JSON.stringify(Array_ToDoList))
});
var StoredToDos = Array_ToDoList.length;
for (var i = 0; i < StoredToDos; i++) {
$("#to-dos").append(localStorage.getitem(STR_Tasks[i]));
}
</script>
I know that I have to read the array and reprint, it may be something to with de-stringifying what I have in store.

according to my understanding on the literally code:
it's 'localStorage.getItem' not 'getitem'
the key store in localStorage was "STR_Tasks", it's just string, not iterable type
i think you should push the object 'todoItem' into 'Array_ToDoList', then 'JSON.stringify' it then storge into the localStorage
at last, you can do like this:
var tasks = JSON.parse(localStorage.getItem("STR_Tasks"));
for (var i = 0; i < StoredToDos; i++) {
$("#to-dos").append(tasks[i]);
}

In the first line of the script you clear all the keys in the local storage so you can not use the previous list instead replace localStorage.clear() with :
var Array_ToDoList = JSON.parse(localStorage.getItem('STR_Tasks') || '[]');
This will make your script use the currently saved STR_Tasks.

Related

JavaScript - Issues recovering a map in an object after being saved in localStorage

I've been dealing with this for some time. I've a list of sections in which the user checks some checkboxes and that is sent to the server via AJAX. However, since the user can return to previous sections, I'm using some objects of mine to store some things the user has done (if he/she already finished working in that section, which checkboxes checked, etc). I'm doing this to not overload the database and only send new requests to store information if the user effectively changes a previous checkbox, not if he just starts clicking "Save" randomly. I'm using objects to see the sections of the page, and storing the previous state of the checkboxes in a Map. Here's my "supervisor":
function Supervisor(id) {
this.id = id;
this.verif = null;
this.selections = new Map();
var children = $("#ContentPlaceHolder1_checkboxes_div_" + id).children().length;
for (var i = 0; i < children; i++) {
if (i % 2 == 0) {
var checkbox = $("#ContentPlaceHolder1_checkboxes_div_" + id).children()[i];
var idCheck = checkbox.id.split("_")[2];
this.selections.set(idCheck, false);
}
}
console.log("Length " + this.selections.size);
this.change = false;
}
The console.log gives me the expected output, so I assume my Map is created and initialized correctly. Since the session of the user can expire before he finishes his work, or he can close his browser by accident, I'm storing this object using local storage, so I can change the page accordingly to what he has done should anything happen. Here are my functions:
function setObj(id, supervisor) {
localStorage.setItem(id, JSON.stringify(supervisor));
}
function getObj(key) {
var supervisor = JSON.parse(localStorage.getItem(key));
return supervisor;
}
So, I'm trying to add to the record whenever an user clicks in a checkbox. And this is where the problem happens. Here's the function:
function checkboxClicked(idCbx) {
var idSection = $("#ContentPlaceHolder1_hdnActualField").val();
var supervisor = getObj(idSection);
console.log(typeof (supervisor)); //Returns object, everythings fine
console.log(typeof (supervisor.change)); //Returns boolean
supervisor.change = true;
var idCheck = idCbx.split("_")[2]; //I just want a part of the name
console.log(typeof(supervisor.selections)); //Prints object
console.log("Length " + supervisor.selections.size); //Undefined!
supervisor.selections.set(idCheck, true); //Error! Note: The true is just for testing purposes
setObj(idSection, supervisor);
}
What am I doing wrong? Thanks!
Please look at this example, I removed the jquery id discovery for clarity. You'll need to adapt this to meet your needs but it should get you mostly there.
const mapToJSON = (map) => [...map];
const mapFromJSON = (json) => new Map(json);
function Supervisor(id) {
this.id = id;
this.verif = null;
this.selections = new Map();
this.change = false;
this.selections.set('blah', 'hello');
}
Supervisor.from = function (data) {
const id = data.id;
const supervisor = new Supervisor(id);
supervisor.verif = data.verif;
supervisor.selections = new Map(data.selections);
return supervisor;
};
Supervisor.prototype.toJSON = function() {
return {
id: this.id,
verif: this.verif,
selections: mapToJSON(this.selections)
}
}
const expected = new Supervisor(1);
console.log(expected);
const json = JSON.stringify(expected);
const actual = Supervisor.from(JSON.parse(json));
console.log(actual);
If you cant use the spread operation in 'mapToJSON' you could loop and push.
const mapToJSON = (map) => {
const result = [];
for (let entry of map.entries()) {
result.push(entry);
}
return result;
}
Really the only thing id change is have the constructor do less, just accept values, assign with minimal fiddling, and have a factory query the dom and populate the constructor with values. Maybe something like fromDOM() or something. This will make Supervisor more flexible and easier to test.
function Supervisor(options) {
this.id = options.id;
this.verif = null;
this.selections = options.selections || new Map();
this.change = false;
}
Supervisor.fromDOM = function(id) {
const selections = new Map();
const children = $("#ContentPlaceHolder1_checkboxes_div_" + id).children();
for (var i = 0; i < children.length; i++) {
if (i % 2 == 0) {
var checkbox = children[i];
var idCheck = checkbox.id.split("_")[2];
selections.set(idCheck, false);
}
}
return new Supervisor({ id: id, selections: selections });
};
console.log(Supervisor.fromDOM(2));
You can keep going and have another method that tries to parse a Supervisor from localStorageand default to the dom based factory if the localStorage one returns null.

I am making a firebase-database list and don't know how to make it remove items from the database

I am pretty new to Javascript, a couple of months in. Essentially, I am trying to make a simple online-based shared shopping-list for a class. I can add to the database, I can show the items as a list, right now my issue is how to remove. I have given the buttons the keys of the database entry they are attached to, as ID, hoping that that would work, but I can't find a way to use the ID. As you can see, i've been testing it by seeing if I can console.log the key, but no luck so far. I've seen a dozen videos and tried dozens of guides, and I hope you can help me; How to I make it so when I click the button, the corresponding entry in the database is deleted? Sorry that the code is a bit of a mess, right now, it is mostly strung together from old code and guides.
var database = firebase.database();
var ref = database.ref('Varer');
ref.on('value', gotData, errData);
function gotData(data){
document.getElementById('Liste').innerHTML = "";
var kbdt = data.val();
var keys = Object.keys(kbdt);
for (var i = 0; i < keys.length; i++){
var k = keys[i];
var kob = kbdt[k].varer;
var btn = document.createElement('button');
var btnText = document.createTextNode('Done')
var opg = document.createElement('li');
var opgnvn = document.createTextNode(kob);
opg.appendChild(opgnvn);
btn.appendChild(btnText);
opg.appendChild(btn);
opg.setAttribute('id', k);
opg.setAttribute('class', 'button');
document.getElementById('Liste').append(opg);
btn.addEventListener('click', function(){
deleteTask(this.id)});
}
}
function errData(err){
console.log('error!');
console.log(err);
}
function deleteTask(id) {
console.log(id);
}
function Indkob() {
var nyVare = document.getElementById('tilfoj').value;
document.getElementById('Liste').innerHTML = "";
var data = {
varer: nyVare
}
var result = ref.push(data);
console.log(result.keys);
}

Switching between button class's using localstorage

I am trying to use javascript to switch between class's when I push a button. At the same time keeping their state the same when the page is refreshed. The script below runs correctly, because I see the button changes state when clicked. However, when the page is refreshed it is all gone. I did read around this forum about using a cookie in jquery, but I thought I would use local storage because why not.
What am I doing wrong please?
<button name='idButton' class='glyphicon glyphicon-eye-open' id=confirmButton onclick='addBasket(this)'>Click Me</button>
<script>
function addBasket($element) {
var className = $element.getAttribute("class");
if (className == "glyphicon glyphicon-eye-open") {
$element.className = "glyphicon glyphicon-eye-close";
}
else {
$element.className = "glyphicon glyphicon-eye-open";
}
localStorage.setItem("item", $element); //Store the element so it can be accessed later.
localStorage.setItem("class", $element.className); //Store the last class name
}
localStorage.getItem("item").className = localStorage.getItem("class").name;
//The last line should run when page loads because it is outside the scope of the method
</script>
You can't store an element in localStorage. It only stores strings.
Try the following:
//Storing
localStorage.setItem("class", className);
//Page Load (after element exists)
var btnClass = localStorage.getItem("class")
if (btnClass) {
document.getElementById('confirmButton ').className = btnClass;
}
for more advanced objects you can JSON.stringify to store and JSON.parse when you retrieve from storage
I know this is late, but I made an example for persistent button states using dynamically created buttons. You can check out the comments to see what is going on! Persistent Button State using LocalStorage
//These are shortcut helper methods
let select = document.querySelector.bind(document);
let selectAll = document.querySelectorAll.bind(document);
function init() {
//First, create grid of buttons (for testing)
let sethtml = '';
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
sethtml += "<button class='glyphicon changestate glyphicon-eye-open' id='eyebtn" + x + "" + y + "' onclick='changeState(this)'></button>";
}
sethtml += '<br>';
}
document.body.innerHTML = sethtml;
//Next, get all of the elements whose state can be changed and are persistent
let changeEls = selectAll('.changestate');
//for each one in this list
for (var i = 0; i < changeEls.length; i++) {
let el = changeEls[i];
let id = el.id;
//see if there is a reference to them already in the storage
//and if there is not add that reference
if (localStorage) {
if (!localStorage.getItem(id)) {
//Save the states of the buttons to localStorage
localStorage.setItem(id, JSON.stringify([id, JSON.stringify(el.classList)]));
}
else {
//Set the states based on stored data
let data = JSON.parse(localStorage.getItem(id));
let elid = data[0];
let classList = JSON.parse(data[1]);
//Eliminate previous classes
document.getElementById(elid).className = "";
//Add in classes gathered from storage
for (let myclass in classList) {
select('#' + elid).classList.add(classList[myclass]);
}
}
}
}
}
//Change state of each button
function changeState(el) {
let id = el.id;
//if open, set to close
if (el.classList.contains('glyphicon-eye-open')) {
el.classList.remove('glyphicon-eye-open');
el.classList.add('glyphicon-eye-close');
}
//if close, set to open
else {
el.classList.remove('glyphicon-eye-close');
el.classList.add('glyphicon-eye-open');
}
if (localStorage) {
//set the localStorage to reflect this
localStorage.setItem(id, JSON.stringify([id, JSON.stringify(el.classList)]));
}
}
init();

Javascript: loop through array

This is driving me crazy. I'm just trying to print out an array and it's not working. What am I missing? The results variable is returning "undefined" which much mean my for loop isn't working correctly. Everything else works properly, the console.log I have correctly displays the fields are added to the array.
// The list of accounts array.
var accountsArray = [];
function addAccount() {
// Take fields and put user data into varables.
var accountName = document.getElementById('accountName').value;
var accountBalance = document.getElementById('accountBalance').value;
var accountType = document.getElementById("accountType");
var accountTypeSelected = accountType.options[accountType.selectedIndex].text;
var accountCurrency = document.getElementById("accountCurrency");
var accountCurrencySelected = accountCurrency.options[accountCurrency.selectedIndex].text;
// Put these variables into the array.
accountsArray.push(accountName);
accountsArray.push(accountBalance);
accountsArray.push(accountTypeSelected);
accountsArray.push(accountCurrencySelected);
// Items added to the array, logged.
console.log('user added: ' + accountsArray);
}
function accountsListHtml() {
var results;
// Loop through the array
for (var i = 0; i < accountsArray.length; i++) {
results = accountsArray[i];
}
document.getElementById('accountsList').innerHTML = results;
}
Here's a link to all the files. It's an iOS web app using Framework7. Balance Pro
You are calling accountsListHtml() in body.onload. At that point accountsArray is empty.
I can't find any other possibility to call accountsListHtml() on that page you linked to.
Add one line inside function addAccount() and it will work:
function addAccount() {
/* vour code */
console.log('user added: ' + accountsArray);
accountsListHtml(); // add this line
}
Try changing results = accountsArray[i]; to results += accountsArray[i];.
Update
And initialize results with an empty string, for example :)
for (var i = 0; i < accountsArray.length; i++) {
results = accountsArray[i];
}
The statement in the for loop i.e. results = accountsArray[i]; overwrites the variable results evry loop run. You could change the statement to :
results += accountsArray[i].toString();
and initialise results to an empty string.
The following works for me: http://jsfiddle.net/95ztrmk3/13/
HTML:
<div id="accountsList"></div>
JS:
// The list of accounts array.
var accountsArray = [];
addAccount();
accountsListHtml();
function addAccount() {
// Take fields and put user data into varables.
var accountName = "John Doe";
var accountBalance = "500.00";
var accountTypeSelected = "Checking"
var accountCurrencySelected = "USD";
// Put these variables into the array.
accountsArray.push(accountName);
accountsArray.push(accountBalance);
accountsArray.push(accountTypeSelected);
accountsArray.push(accountCurrencySelected);
// Items added to the array, logged.
console.log('user added: ' + accountsArray);
}
function accountsListHtml() {
var results = [];
// Loop through the array
for (var i = 0; i < accountsArray.length; i++) {
results += accountsArray[i] + " ";
}
document.getElementById('accountsList').innerHTML = results;
console.log(results);
}
Assuming the input isn't malformed or otherwise weird. I made sure Javascript recognizes results is an empty array and not a string or something: var results = []

Show contents of localStorage into div

I have this basic function :
pid = 1;
$(function() {
if (localStorage["key"+pid] != null) {
var contentsOfDiv = localStorage.getItem("key"+pid);
$("#Div").html(contentsOfdDiv);
}
});
The problem is that the pid value will change eventually and I don't want to overwrite the contents of the key.
How can I proceed to stack every Div content that localStorage is saving for me ?
You can iterate on localStorage entries just like on any object properties :
for (var key in localStorage) {
console.log(key, localStorage[key]);
}
So your code could be :
$(function() {
var lines = [];
for (var key in localStorage) {
if (/^key/.test(key)) { // does the key start with "key"
lines.push(key.slice(3) + ' = ' + localStorage[key]);
}
}
$("#Div").html(lines.join('<br>'));
});
If I have understood well, you want to use pid to loop over the object.
Best way to do this and avoid for in chain prototypical problems is the following:
(I think for this case you are better with an array rather than with an object)
http://jsfiddle.net/hqkD9/
var localStorage = ['aaaa', 'bbbbb', 'cccc', 'dddd']; // don't forget to declare with var
var html_string = '';
$.each(localStorage, function(index, value) {
html_string += value + '<br>';
});
$('#my_div').html(html_string);

Categories

Resources