Can't store todos to local storage - javascript

I'm learning JavaScript right now and one of the practice application I am doing is to make a to-do list to learn the basics. Right now I'm having a hard time saving my inputs onto the local storage. I look into the console and local storage of my browser and only see that a key "todos" is being created but no values are stored in it.
I was wondering if anyone can help. Please ignore the way I structured my coding. I am still learning. (I know there are better and more efficient ways to make a to-do list.)
My code:
<body>
<header class = "centerAlign ">to-do list </header>
<div class = "divA centerAlign input-group container" style = "list-style-type:none">
<input class = "form-inline input-lg" id="itemInput" "type="text" placeholder="add things to do"/>
<button class = "addButt btn btn-lg">
<span class="glyphicon glyphicon-plus"></span>
</button>
<ul class = "ulist1 container">
<!--List items gets inserted here-->
</ul>
</div>
<button class = "clearAll btn">Clear localStroage</button>
<script>
getTodos();
//press enter to submit
$("input").on('keydown',function(e){
if(e.keyCode ==13){
$("<li>").attr("class","apples").html(itemInput.value).fadeIn().appendTo(".ulist1");
$("<button>").attr("class","doneButt btn pull-left glyphicon glyphicon-ok").appendTo($(".apples").last());
$("<button>").attr("class","delButt btn pull-right glyphicon glyphicon-trash").appendTo($(".apples").last());
clearInput();
saveTodos();
}
});
//click the submit button
$(".addButt").click(function(){
$("<li>").attr("class","apples ").html(itemInput.value).fadeIn().appendTo(".ulist1");
$("<button>").attr("class","doneButt btn pull-left glyphicon glyphicon-ok").appendTo($(".apples").last());
$("<button>").attr("class","delButt btn pull-right glyphicon glyphicon-trash").appendTo($(".apples").last());
clearInput();
saveTodos()
});
//clears the input box for new text
function clearInput(){
itemInput.value = "";
}
//button to delete
$(".ulist1").on("click", ".delButt", function(e) {
e.preventDefault();
$(this).parent().fadeOut(function(){
$(this).remove();});
});
//put a line through the text and undo that line
$(".ulist1").on("click", ".doneButt", function(e) {
$(this).parents("li").toggleClass('withline');
});
//save data localStorage
$(".addButt").click(function(){
saveTodos();
});
function saveTodos(){
localStorage.setItem("todos", itemInput.value);
}
//get data from localStorage
function getTodos(){
localStorage.getItem("todos");
}
</script>
<script>//delete localstroage
$(".clearAll").click(function() {
window.localStorage.clear();
location.reload();
return false;
});
</script>

You call your own clearInput() function before you call saveTodos(). This means you first clear your input field and then save the value of the (now empty) input field to your local storage.
Therefore, you will always have the key 'todos' with an empty String as its value.
To be able to save your last entered input in your desired localStorage variable you'd just need to move the saveTodos() call before the clearInput() call.
However your use case suggests that you surely want to save more than just the last entered input but several todos. To achieve that, you will have to either use a seperate key for every entry or story all entries as an array. As LocalStorage only supports String values, you would have to use something like JSON.stringify

Perhaps commenting out clearInput(); before calling saveTodos(); will solve your problem. :)

Related

javascript & html - creating new checkbox option everytime user enters item in textbox

So basically I'm creating a program that allows the user to create and manage a ‘to-do list’. This will allow the user to add new items, remove selected items, highlight/un-highlight selected items, and sort the items, etc. I'm currently working on the add button, but I'm extremely confused with different functions in HTML and code that will allow me to manipulate the DOM.
When the user clicks the add button and the item name is valid, a new item should be added to the page’s to-do list (which esentially creates a new checkbox for every item the user adds). The checkbox is basically so the item can be selected/deselected, as well as the text that was in the item name textbox when the add button was clicked.
I guess I have two problems right now. I'm trying to verify that the item name is at least 1 character long. I wrote code in my "addHandler.js" file but when I write nothing in the textbox and click on the add button on my HTML browser, no error message pops up. I don't know why it's ignoring my function. Another thing I'm struggling with is the part that creates a new checkbox for every valid item that is added. I know how to create a checkbox on my HTML page, but I don't understand how to get my program to create a new one per item that the user inputs.
Any help or push in the right direction would be appreciated. I'm also new to HTML and javascript, so explaining stuff in simple terms would also make me really grateful.
todo.html code:
<html>
<head>
<title>Checklist</title>
</head>
<body>
<div><h1>My to-do list</h1></div><br />
<div id ="myCheckList">Enter an item:</div>
<div>Type something: <input type="text" id="textbox"></input></div>
<button type="button" id="addBut">Add item</button>
<button type="button" id="removeBut">Remove items</button>
<button type="button" id="toggleBut">Toggle highlight</button>
<button type="button" id="sortBut">Sort items</button>
<script src="addHandler.js"></script>
</body>
</html>
addHandler.js code:
function init(){
let button = document.getElementById("addBut");
button.onclick = buttonClicked;
let tb = document.getElementById("textbox");
tb.onblur = validate;
}
function add(){
let someEle = document.getElementById("myCheckList");
someEle.innerHTML = 'You added an item';
}
function validate(){
if(document.getElementById("textbox").value.length == 0){
alert("You need to enter something");
}
}
You should have a wrapper that contains your checkbox items that you can append new elements to.
<div id="checklist_items"></div>
Then you can use the following function to create a new div that contains a checkbox and the entered text, and then append it to your checklist:
function addItem() {
var input = document.getElementById("textbox");
var wrapper = document.getElementById("checklist_items");
if(input.value.trim() != "") {
var new_element = document.createElement("DIV");
new_element.innerHTML = '<input type="checkbox"> '+input.value;
wrapper.appendChild(new_element);
}
else {
alert("You must enter at least 1 character.");
}
}
I would also use the following to add the function to your button:
document.getElementById("addBut").addEventListener("click", addItem);

I want to know the value of the button I pressed in a table

I have an array of buttons arranged in each row of a table. When I click on a certain button, I want to know the row number the clicked button is positioned.
I add each time a row to existing table, where in each row there is a button. I tried to put each button in an array, so when I click on one of them, I will get the index number from the array. Didn't succeed
var btns[];
var btn=document.createElement("BUTTON");
btn.innerHTML="Edit";
btns.push(btn);
cell1.appendChild(btns[btn_num]);
btn_num=btn_num+1;
I expect to get the row number, so I can edit a specific row in a table.
You don't need to store button in memory var btns. I see a couple of practical ways to do this:
Create button with a class name
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" onclick="BtnEditClick(this)">Edit</button>
<script>
function BtnEditClick(clickedElement){
var btns = document.getElementsByClassName("btn-edit")
var result = -1
for(var i=0;i<btns.length; i++) {
if(clickedElement == btns[i]){
result = i
}
}
if(result != -1)
alert("found " + result)
else
alert("not found")
}
</script>
Reference to the value using data-attr in html5
<button class="btn-edit" data-index="0" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" data-index="1" onclick="BtnEditClick(this)">Edit</button>
<button class="btn-edit" data-index="2" onclick="BtnEditClick(this)">Edit</button>
<script>
function BtnEditClick(clickedElement){
var index = clickedElement.getAttribute("data-index")
alert("click index: " + index)
}
</script>
Pass index directly to the function
<button class="btn-edit" data-index="0" onclick="BtnEditClick(0)">Edit</button>
<button class="btn-edit" data-index="1" onclick="BtnEditClick(1)">Edit</button>
<button class="btn-edit" data-index="2" onclick="BtnEditClick(2)">Edit</button>
<script>
function BtnEditClick(index){
alert("clicked on item:" + index)
}
</script>
Yes there are still a few other ways. For myself most of the time I use the second approach that get the element ( the button object that get clicked ) and then read the data that I want from data-attr ( you can define any data-attr you want e.g data-index, data-id ). This is very convenient, you will find it useful because sometimes you might need more data than just an index of the element inside the list. I hope it helps
One possible approach is: for each added button you can add an the HTML attribute id equal table row. Besides that, you can add the HTML attribute onclick="onClickButton(this.id)" to the created button. So you can use the folowing script to get the id value when the button gets clicked:
<script>
function onClickButton(e) {
console.log(e);
}
</script>

Not able to reset input field in laravel

I need to reset the input field when user clicks on the rest button, I have other content on the page which is getting cleared except input field, I'm not sure if this is happening because I'm using old values after post request.
<input type="text" name="app_number" class="form-control" onreset="this.value=''" value="{!! Request::input('app_number') !!}" id="app_number" placeholder="Application Number" required>
JS for reset button:
document.getElementById("appForm").onreset = function() {
document.getElementById("app_number").value = "";
};
Reset Button:
<button class="btn btn-primary" id="reset-button" type="reset">Reset</button>
Use type="reset" for your button:
<button type="reset">Cancel</button>
try using reset():
document.getElementById("app_number").reset();
In this case you must use JQuery Lib. Basic you need to set ID for this element. And in jquery you listen click on this Element.
$('#app_number').on('change', function () {
// enter code here
});
Please try to use in js like:
$(document).on('click', '#YourOnclickButtonID', function(){
var $alertas = $('#YourFormID');
$alertas.validate().resetForm();
});
So answering my own question, any feedback would be appreciated but this is working.
It turns out that no matter what value="{!! Request::input('app_number') !!}" will always have value as this code gets executed on the server side and unless you make another post request you can not change the value and by using only vanilla JS and without post request this cannot be done.
So, instead of getting values from Request why not just takes the values from user input and save it to local storage and then just grab it and inject into the input field.
I added onkeyup event ion to the input field
<input type="text" name="app_number" class="form-control" onkeyup='saveValue(this);' id="app_number" placeholder="Application Number" required>
and JS to store and retrieve input
document.getElementById("app_number").value = getSavedValue("app_number"); // set the value to this input
function saveValue(e) {
var id = e.id; // get the sender's id to save it .
var val = e.value; // get the value.
localStorage.setItem(id, val); // Every time user writing something, the localStorage's value will override .
}
//get the saved value function - return the value of "v" from localStorage.
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return ""; // You can change this to your defualt value.
}
return localStorage.getItem(v);
}
and then reset the form as usual
document.getElementById("appForm").onreset = function() {
document.getElementById("app_number").value = '';
};
Your reset button :
<button class="btn btn-primary" id="reset-button" onclick="myFunction()">Reset</button>
In js:
function myFunction(){
document.getElementById("app_number").value = "";
}

Why is the array empty every time on click?

So basically every time I click on the icon '.favorite i' it should add an object to my array. If I click the first time it adds the parent div to the array, but on the second time it deletes the first one and grabs the last parent div.
I'm working with three tabs called 'Monday', 'Tuesday' and 'Favorites'. I have a toggle icon which is an empty heart at start 'favorite i'. If I'm in Monday and click on the icon, the empty heart turns to be filled out and its parent is cloned and added to the '#fav' tab. When this happens the clone is saved to local storage. So if people refresh the page, they can still see their preferences.
When the heart is clicked in one of those cloned divs that specific div is removed from '#fav' and will also have to be removed from the array and local storage too.
To conclude, I need to save each cloned div into an array/local storage and then be able to delete each one of those from the array when these are removed from the #fav tab.
How to overcome this issue? Many thanks.
HTML
<div class="container">
<div class="tabs_main">
<div class="col-md-5"><a data-target="#mon" class="btn active" data-toggle="tab">Monday</a></div>
<div class="col-md-5"><a data-target="#tue" class="btn active" data-toggle="tab">Tuesday</a></div>
<div class="col-md-2"><a data-target="#fav" class="btn active" data-toggle="tab"><i class="fa fa-heart" aria-hidden="true"></i></a></div>
</div>
<div class="tab-content">
<div class="tab-pane active" id="mon">
<br>
<div class="spaces">
<div class="box-container">
<div class="box not-selected" id="box1">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
<div class="box-container">
<div class="box not-selected" id="box2">
<i class="fa fa-heart-o" aria-hidden="true"></i>
</div>
</div>
</div>
<div class="tab-pane" id="tue">
<br>
<div class="spaces">
</div>
</div>
<div class="tab-pane" id="fav">
<br>
</div>
</div>
</div>
JS
$('div.tab-pane').on('click', '.favorite', function(e) {
var add = $(this).parent().parent();
add.each(function(){
if ($(add.find('.not-selected .favorite i').hasClass('fa-heart'))) {
var boxContent = $(add).clone(true, true);
var showHide = $(boxContent).find(".session").addClass('selected').removeClass('not-selected');
var get = $(boxContent).wrap('<p/>').parent().html();
$(boxContent).unwrap();
var tempArray = [];
tempArray.push(get);
var myJSONString = JSON.stringify(get);
var parseString = $.parseJSON(myJSONString);
var finalString = myJSONString.replace(/\r?\\n/g, '').replace(/\\/g, '').replace(/^\[(.+)\]$/,'$1').replace (/(^")|("$)/g, '');
var final = localStorage.setItem('sessions', finalString);
$("#fav").append(tempArray);
};
});
});
Fiddle: https://jsfiddle.net/itsfranhere/nbLLc3L0/44/
Your question title is quite clear...
But your question itself and the code you provide prevents anyone to answer with full assurance.
Here is what the provided code produces, as an attempt to reproduce.
Now if I do not bother that code, which I think no one can deduct what it should do exactly...
Your question in title can be can answered by:
Simple! You declare (using var) the tempArray at every click.
That is why it do not retain the information (whatever it is supposed to retain) of the previous click.
I'm not "satisfied" of this answer to you... So if this do not answers completely your issue, please edit your question with more details. Feel free to fork the CodePen to make it look more like your project.
EDIT
From what I get of your script, you want to save "favorited" divs to localstorage. This implies you also have to remove them from localstorage and favorites tab if one is "unfavorited".
Also, you use id on "to be cloned" element. Be extremely cautious with this. An id has to be unique. So if the id is usefull (which was not obvious in the provided code), ensure you make it unique when you clone the element.
I improved you attempt to remove spaces and line feeds in what is to be saved.
Another good advise I have to give you is to use significative variable names in your code. Make your code speak by itself. Readability helps!
Here is your code, updated to do what is mentionned above. Have a close look to comments in code.
var tempArray = [];
// Clones
$('div.tab-pane').on('click', '.favorite', function(e) {
e.preventDefault();
// Elements we play with... Having significative variable names.
var heartLink = $(this);
var box = heartLink.parent('.box');
var container = box.parent('.box-container');
var favoriteTab = $("#fav .spaces");
// I don't know what is the use for those 3 lines below.
var idFind = box.attr("id");
var idComplete = ('#' + idFind);
console.log(idComplete);
//TOGGLE FONT AWESOME ON CLICK
heartLink.find('i').toggleClass('fa-heart fa-heart-o'); // .selected or not, you need those 2 classes to toggle.
box.toggleClass("selected not-selected"); // Toggle selected and not-selected classes
// Clone div
var boxContent = container.clone(true, true);
// Change the id
var thisID = boxContent.attr("id")+"_cloned";
boxContent.attr("id", thisID);
// Get the html to be saved in localstorage
var get = boxContent.wrap('<p>').parent().html();
get = get.replace(/\r?\n/g, "").replace(/>\s*</g, "><"); // remove line feeds and spaces
console.log(get);
boxContent.unwrap();
// Decide to add or remove
if(box.hasClass("selected")){
console.log("Add to array")
tempArray.push(get);
// Add to favorites tab
favoriteTab.append(boxContent);
}else{
console.log("Remove from array");
var index = tempArray.indexOf(get);
tempArray.splice(index);
// Remove from favorite tab
favoriteTab.find("#"+thisID).remove();
}
// Save
localStorage.setItem('sessions', tempArray.join(""));
});
// Append item if localstorage is detected
if (localStorage["sessions"]) {
$("#fav .spaces").append(localStorage["sessions"]);
console.log( localStorage.getItem('sessions') );
}
Updated CodePen
Don't save div elements in localStorage. I recommend you use an object constructor function like below to create a unique object for each [whatever] pushing these into an array then to localStorage in a try block.
localStorage.setItem('myobjects', JSON.stringify(myobjects));
// Object Constructor Functions
function Myobject(id, username, password) {
this.id = id;
this.username = username;
this.password = password;
this.type = 'credential';
}
function duplicate(id,obj){
var result = false;
obj.forEach( function (arrayItem){
if (arrayItem.id == id){
result = true;
}
});
return result;
}
function deleteObject(type, id){
var obj = {};
if (type === 'foo') {
obj = myobjectwhatever;
deleteThis(obj);
//save to local storage
try {
localStorage.setItem('myobject', JSON.stringify(myobjects));
}
catch (e) {
console.log(e);
}
}
else if (type === 'bar') {
//...
}
function deleteThis(o){
try {
for (var i = 0, iLen = o.length; i < iLen; i++) {
if (o[i].id === id) {
o.splice(i, 1);
}
}
}
catch (e) {
console.log(e);
}
}
}

Unable to Clone HTML & Values into jQuery Datatables 1.10

This question has been asked on a few occasions, for example:
Store Cloned Element in Variable
Copy DOM Element
However, I'm having issues selecting say <div id="XYZ"></div> and cloning it to a variable for the jQuery DataTable fnStateSaveParams to save. When the page refreshes it is then meant to reload the cloned object back into the HTML via fnStateLoadParams. I am trying to use .clone() over .html() because I also need the values stored within the dynamically generated textboxes.
If I'm not saving and loading via the Datatables plugin, then it works perfectly. As soon as I try calling code similar to the below then it ceases to work (please bare in mind I've tried a number of variations to the below code). Has anyone got any ideas or suggestions?
"fnStateSaveParams": function (oSettings, oData) {
var clonedHtml= $("#XYZ").clone(true);
oData.storedHtml = clonedHtml;
},
"fnStateLoadParams": function (oSettings, oData) {
//$("#displayHtml").append(oData.storedHtml);
//$("#displayHtml").html(oData.storedHtml);
//$(oData.storedHtml).prependTo("#displayHtml")
}
<div id="XYZ">
<div data-template="">
<label class="bolder"></label>
<div class="input-append">
<div class="inline-block advancedSearchItem">
<input type="text" id="test1" value="Test Scenario" />
</div>
<a href="#" data-id="" class="btn btn-small btn-danger removeField">
<div class="hidden-phone">Remove</div>
<i class="icon-trash icon-only hidden-tablet hidden-desktop"></i>
</a>
</div>
</div>
</div>
The end scenario will be more complex, however the above is the simplest form of what I am trying to create. If you need more information, feel free to ask and I'll update the question accordingly.
I didn't find a way of utilising .clone() to grab all HTML and Text Box values. However, I did come up with a solution and the code below is for anyone who needs a reference point.
Using .html() (as most will know) will only copy the available HTML and ignore what is essentially 'placeholder' text within text fields. My solution though is to force the value into the HTML rather than being treated as 'placeholder' text, this allows it to be used again when the page is loaded.
$(document).on("click", "#advancedSearchButton", function(event) {
event.preventDefault();
// DO SOME STUFF HERE
$("[data-value]").each(function(index) {
if (index > 0) {
fieldCount++;
$(this).attr("value", $(this).val());
}
});
oTable.fnFilter("");
});
function loadData() {
// ... ... ...
"fnStateSaveParams": function(oSettings, oData) {
oData.advancedSearchHtml = $("#addedSearchFields").html();
oData.fieldCount = fieldCount;
oData.isAdvancedSearch = isAdvancedSearch;
},
"fnStateLoadParams": function(oSettings, oData) {
$("#addedSearchFields").html(oData.advancedSearchHtml);
if (oData.isAdvancedSearch == true) {
$("#collapseElement").removeClass("collapsed");
$("#collapseIcon").removeClass().addClass("icon-chevron-up");
$("#filter").hide();
}
isAdvancedSearch = oData.isAdvancedSearch;
advancedSearchFields = oData.fieldCount;
}
// ... ... ...
}

Categories

Resources