I have a project I'm working on where there's a "Save" button that saves the user's data to localStorage and there's a "Load" button that loads a user's saved data from localStorage. However, it's not working. Can someone please help me fix this problem?
HTML:
<textarea rows="10" cols="50" id="text"></textarea>
<br/><button id="save">Save</button>
<button id="load">Load</button>
JavaScript:
function doSave(){
var txt = text.value;
localStorage.storedText= txt;
}
function doLoad(){
text.value = localStorage.storedText;
}
window.onload = function(){
saveButton = document.getElementById("save");
saveButton.onclick = doSave();
loadButton = document.getElementById("load");
loadButton.onclick = doLoad();
textarea = document.getElementById("text");
};
You're using localStorage incorrectly:
function doSave(){
//Set the item in doSave()
//localStorage.setItem("text", text.value);
}
function doLoad(){
//Get the item in doLoad()
//text.value = localStorage.getItem("text");
}
Also, read Quentin's answer: Don't call doSave() and doLoad() when setting the onclick event:
//When the window loads...
window.onload = function(){
saveButton = document.getElementById("save");
saveButton.onclick = doSave;
loadButton = document.getElementById("load");
loadButton.onclick = doLoad;
textarea = document.getElementById("text");
};
Here's the "fiddle": http://jsfiddle.net/NobleMushtak/JNKaU/
You have to assign functions to onclick properties. You are calling doSave and doLoad and assigning their return values. Since those functions do not have return statements, they return undefined.
Remove the (). Don't call them immediately.
Related
I am very new to javascripts and trying to create a dynamic html form where there are multiple button, and each button click map to a corresponding form input. Here is my code:
<html>
<head>
<title>Create Group</title>
<script src="/js/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function(){
$("#generate_form").click(function(){
var number = document.getElementById("number_of_groups").value;
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
var i;
for (i=1;i<=number;i++){
var p = document.createElement("p");
var node = document.createTextNode("group " + i + " :");
p.appendChild(node);
container.appendChild(p);
var input = document.createElement("input");
input.type = "text";
var thisID = 'group_'+i;
input.id = thisID;
input.name=thisID;
container.appendChild(input);
var button = document.createElement("button");
button.id = "button_"+i;
button.type = "button";
container.appendChild(button);
button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
var buttonLabel = document.createTextNode("Generate");
button.appendChild(buttonLabel);
container.appendChild(document.createElement("br"));
}
})
});
</script>
</head>
<body>
<h2>Create some group(s)</h2>
<br>
Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
<button id="generate_form" type="button">GO</button>
<div id="container"/>
</body>
</html>`
So, the user would input number of groups to create and click 'Go' button, then the code should dynamically generate the form with the number the user choose. Each group of the form includes a input textbox and a 'Generate' button. When the button is clicked, the input textbox will show "hello world". However, the "hello world" only show up in the last input textbox no matter which 'Generate' button I click. So I changed the onclick function of the button to:
button.onclick = function(){ alert(thisID);};
Then I found that thisID is always the id of the last input textbox no matter which 'Generate' button I click. I guess that is because the binding of the click event does not happen till the script is done when 'thisID' would always be its latest value.
Would anyone please help me to realize the functionality I want? Thank you very much!
You would need to wrap the code within the for loop in a separate function, passing in the value of i as a parameter. This would create a closure, creating a new execution scope for your code. Otherwise what is happening is that your var is being hoisted, and is not exclusive to each iteration of the for loop, so your DOM is reflecting only the last value it was assigned.
for (i=1;i<=number;i++){
(function (i) {
var p = document.createElement("p");
var node = document.createTextNode("group " + i + " :");
p.appendChild(node);
container.appendChild(p);
var input = document.createElement("input");
input.type = "text";
var thisID = 'group_'+i;
input.id = thisID;
input.name=thisID;
container.appendChild(input);
var button = document.createElement("button");
button.id = "button_"+i;
button.type = "button";
container.appendChild(button);
button.onclick = function(){ document.getElementById(thisID).value = "hello world";};
var buttonLabel = document.createTextNode("Generate");
button.appendChild(buttonLabel);
container.appendChild(document.createElement("br"));
})(i);
}
You can check out an article on closures here:
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36
EDIT: As one of your commenters mentioned, you can also set your vars to 'let' to achieve a similar effect. This is because let scopes the variable to the current code block, rather than being hoisted to the scope of the function, so each for loop iteration has a private let variable. It is still recommended to get a good understanding of closures and how they work, however.
Since you are already using JQuery, you can reduce some of the logic.
Let me know if this helps-
<html>
<head>
<title>Create Group</title>
</head>
<script src="/js/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(()=>{
var txtGroup='<input type="text" id="txt_group_{0}" value="">';
var btnGroup='<button id="btn_group_{0}" type="button">Click Me</button>';
var container=$('#container');
$('#generate_form').click((e)=>{
var groupCount=parseInt($('#number_of_groups').val());
var idToStart=$('#container').children('div').length+1;
for(let i=idToStart;i< idToStart+groupCount;i++){
var divGroup=`<div id="div_group_${i}">`+
txtGroup.replace('{0}',i)+
btnGroup.replace('{0}',i)+`</div>`;
container.append(divGroup);
$('#btn_group_'+i).on('click',(e)=>{
console.log('#txt_group_'+i);
$('#txt_group_'+i).val('Hello World');
});
}
});
});
</script>
<body>
<h2></h2>
<br>
Create <input type="text" id="number_of_groups" name="number_of_groups" value="1"> group(s).
<button id="generate_form" type="button">GO</button>
<div id="container"></div>
</body>
</html>
So I am trying to make an edit function for a favorites bar. Editing one box is okay, but when I try to edit a different box, all the boxes that I clicked on previously gets edited as well. Here is a jsfiddle with the complete code: https://jsfiddle.net/1exrf9h8/1/
I am trying to understand why my editFavorite function is updating multiple boxes and not just one.
function clickEdit(input, title, url, plus, editIcon, anchorEdit, editBtn)
{
let i = editIcon.length - 1;
editIcon[i].addEventListener("click", function(event){
input.style.display = "block";
title.value = plus[i + 1].textContent;
url.value = anchorEdit[i].href;
console.log(i);
console.log(anchorEdit[i]);
editFavorite(anchorEdit[i], url, title, input, editBtn);
});
}
function editFavorite(changed, url, title, input, editBtn)
{
editBtn.addEventListener("click", function(){
changed.href = url.value;
changed.textContent = title.value;
input.style.display = "none";
});
}
There is a few problems in your logic, architecture and use of the event handler, Let's give it a shot in a more OOP way so you can actually make it to work and understand what is going on.
Every single favorite is an object by itself, that can spawn and update itself.
function favorite(newTitle, newUrl) {
this.element = container.appendChild(document.createElement("div"));
this.title = this.element.appendChild(document.createElement("h2"));
this.url = this.element.appendChild(document.createElement("h2"));
this.update = (newTitle, newUrl) => {
this.title.textContent = newTitle;
this.url.textContent = newUrl;
}
this.createButton = () => {
button = this.element.appendChild(document.createElement("button"));
button.append("Edit");
button.addEventListener("click", () => {
let titleInput = document.getElementById("title").value;
let urlInput = document.getElementById("url").value;
this.update(titleInput, urlInput);
})
}
this.update(newTitle, newUrl);
this.createButton();
}
Then let's have a simple form where we can take inputs, using the same for editing, and creating a new favorites.
<input id="title" type="text" name="title" placeholder="Title">
<input id="url" type="text" name="url" placeholder="Url">
<button id="submit">Create New</button>
Now the actual submit logic.
document.getElementById("submit").addEventListener("click", () => {
let titleInput = document.getElementById("title").value;
let urlInput = document.getElementById("url").value;
if (!titleInput.length || !urlInput.length) return;
let newFavorite = new favorite(titleInput, urlInput);
container.appendChild(newFavorite.element);
});
https://jsfiddle.net/p50L27us/48/
The problem is caused by editFavorite function. when you call editFavorite function automatically starts new listener. Evey click start new one.
The solution is " ,{once : true} "
function editFavorite(changed, url, title, input, editBtn)
{
editBtn.addEventListener("click", function(){
changed.href = url.value;
changed.textContent = title.value;
input.style.display = "none";
},{once : true});
}
I'm new to Javascript and am trying to write code for a simple greeting. The user will have an input box to type their name in to and below a button for them to click that outputs a value of "Hello {name}!". If you could help me out I would appreciate it!
You could start doing something like this:
(function() {
// Creates <input id="myTextBox" type="text" />
var textBox = document.createElement("input");
textBox.id = "myTextBox";
textBox.type = "text";
// Creates <button id="myButton" type="button">Show</button>
var btnShow = document.createElement("button");
btnShow.id = "myButton";
btnShow.type = "button";
btnShow.innerHTML = "Show";
// When you click in the button, show the message.
btnShow.onclick = function showMessage() {
alert("Hello " + textBox.value + "!");
};
// Add created elements.
document.body.appendChild(textBox);
document.body.appendChild(btnShow);
})();
You can find more information about createElement function in this site: Document.createElement().
Here is my JSFiddle: http://jsfiddle.net/kboucheron/XVq3n/15/
When I start a list of items and I click on "Clear", I would like to text input be cleared as well.I'm not able to clear the fields
<input type="text" placeholder ="Add List" id="listItem"/>
<button id="addButton">add Item</button>
<button id="clearButton">Clear Items</button>
<ul id="output"></ul>
clearButton.addEventListener("click", function(e) {
var text = document.getElementById('listItem').value;
var addItem = document.getElementById('output');
addItem.innerHTML = '';
text.value = '';
});
Just need to make this change here:
var text = document.getElementById('listItem');
You had this:
var text = document.getElementById('listItem').value;
What you are doing is getting the value of the input text, when you actually want the input element.
Also here is the updated fiddle: http://jsfiddle.net/XVq3n/16/
you are referring in your code to input's value, replace
var text = document.getElementById('listItem').value
with
var text = document.getElementById('listItem')
Ok, it's a really simple (but easy to make) error. Try this change and it should work:
clearButton.addEventListener("click", function(e) {
var text = document.getElementById('listItem');
var addItem = document.getElementById('output');
addItem.innerHTML = '';
text.value = '';
});
Basically, you did .value one too many times. Hope that helps.
I'm dynamically adding text inputs to a form. The new input also receives focus. On adding an onblur event however the onblur event seems to be firing as soon as the input is added. To test this I added an alert for the onblur event. The alert appears, and only after clicking OK is the new input created. This happens in IE, Firefox and Opera.
The following is the code I am using. I have removed all other code to for ease of reading.
<head><title>""</title>
<script type="text/javascript">
var count = 1;
function addinput () {
var inpmaster = document.getElementById("inpMaster");
var myinput = document.createElement("input");
myinput.id = "myfield"+count;
myinput.name = "myfield"+count;
myinput.type = "text";
myinput.onblur = alert("woot");
inpmaster.parentNode.insertBefore(myinput,inpmaster);
inpmaster.disabled="disabled";
myinput.focus();
count++;
};
</script>
</head>
<body>
<form action="" method="post" id="admin">
<input id="inpMaster" type="text" name="prodDesccc" onfocus="addinput();" />
</form>
</body>
It is because you are using alert("woot") to assign to onblur event instead of function(){ alert("woot") ;}.
Change your code to:
function addinput () {
var inpmaster = document.getElementById("inpMaster");
var myinput = document.createElement("input");
myinput.id = "myfield"+count;
myinput.name = "myfield"+count;
myinput.type = "text";
myinput.onblur = function(){alert("woot");};
inpmaster.parentNode.insertBefore(myinput,inpmaster);
inpmaster.disabled="disabled";
myinput.focus();
count++;
};