Text input inserting wrong value into list item - javascript

Here is my code: http://jsfiddle.net/H5bRH/
Every time I click on the submit button, it should insert what I typed into a new li item.
But instead of that, it inserts what I typed the first time PLUS the new value that I typed. Play with my jsfiddle to see what I mean.
How do I fix this so that it only adds what the user inputs into the form?
I assume there's something wrong here:
function saveTweet() {
var tweet = document.getElementById("tweet");
var tweetName = tweet.value;
var li = document.createElement("li");
li.innerHTML = tweetName;
var ul = document.getElementById("tweets");
ul.appendChild(li);
}

You have attached 2 click event to save button.
button.onclick = saveTweet;
Using jQuery $("#saveTweet").click(function ()
$("#saveTweet").click(function () {
var tweet = document.getElementById("tweet");
var tweetName = tweet.value;
var li = document.createElement("li");
li.innerHTML = tweetName;
var ul = document.getElementById("tweets");
ul.appendChild(li);
$("li").slideDown("fast");
});
JSFiddle

Why not just reduce all that code to :
$("#saveTweet").click(function () {
$('#tweets').append('<li>' + $("#tweet").val() + '</li>')
$("li").slideDown("fast");
});
jsFiddle example

Instead of having two click handlers for the #saveTweet button, move the slideDown call to your saveTweet function.
function saveTweet() {
var tweet = document.getElementById("tweet");
var tweetName = tweet.value;
var li = document.createElement("li");
li.innerHTML = tweetName;
var ul = document.getElementById("tweets");
ul.appendChild(li);
$("li").slideDown("fast");
}

It happens because you bind two click handlers on the #saveTweet element.
One to add the content, and one to animate the li elements..
In your case the animated one is occuring first and the appending second.. so you always animate the previously added element...
Since you use jQuery anyway, why not use that for all your interactions ?
$(function () {
var button = $("#saveTweet");
button.on('click', function () {
var tweet = $("#tweet"),
ul = $("#tweets"),
tweetName = tweet.val(),
li = $('<li>', {html: tweetName});
ul.append(li);
li.slideDown("fast");
});
});
Demo at http://jsfiddle.net/gaby/Y9cY3/1/

Related

my list function doesn't work in javascript

so i wrote this code that would create a list and then append an input to it on click. really simple. but the problem is it doesn't work and i have no idea why
here is the code:
function pushing() {
var li = document.createElement("li");
var inputValue = document.getElementById("inp").value;
var pushchild = document.createTextNode(inputValue);
li.appendChild(pushchild);
}
sub.addEventListener("click", pushing);
the id inp is an input id. thank you
Add this to the last line of your function. Append your newly created li element to the ul.
document.querySelectorAll(‘ul’).appendChild(newCreatedLi);
Your list item is never appended to a list element.
// Cache the elements,
// add the button listener,
// & focus on the input
const list = document.querySelector('ul');
const input = document.querySelector('#inp');
const sub = document.querySelector('#sub');
sub.addEventListener('click', pushing);
input.focus();
function pushing() {
const li = document.createElement('li');
const text = document.createTextNode(input.value);
li.appendChild(text);
// Adding the list item to the list element
list.appendChild(li);
}
<input id="inp" />
<button id="sub">Click</button>
<ul></ul>

Using JavaScript to modify the content of html

Now I am doing a shopping cart in my project, when i click the add to cart button, then it will upload the data in localstorage, then i will create an element (product name, price, quantity and two increment and decrement button in the list) and this create process will be looped by the length of localstorage.
When I want to make click event on increment and decrement button, only the last row of increment and decrement button respond. For example, I have 3 rows in shopping cart, only the third row will show the proper result, the first two row have no response.
I would like to ask can you give me some suggestion, how to achieve my goal? Thanks!!!!!!!!!!!!!!
var ul = document.getElementById("cart")
for(var i=0;i<localStorage.length;i++){
var li = document.createElement("li");
var addBtn =document.createElement("BUTTON");
var dropBtn document.createElement("BUTTON");
addBtn.innerHTML = '+';
dropBtn.innerHTML = '-';
addBtn.id='addBtn'
var a = document.getElementById("addBtn")
addBtn.onclick = function(){
alert('here be addBtn');return false;
};
dropBtn.onclick = function(){
alert('here be dropBtn');return false;
};
ul.appendChild(addBtn);
ul.appendChild(dropBtn);
ul.appendChild(li);
}
You need to make some changes to work as expected:
Not to search/find button when you have its reference.
append a button to list i.e. li not to ul (Thanks CBroe).
I've taken some assumption like the localStorage length as 3 and added the text of the cart button.
const ul = document.querySelector("ul#cart");
for (var i = 0; i < 3; i++) {
var li = document.createElement("li");
var addBtn = document.createElement("BUTTON");
var dropBtn = document.createElement("BUTTON");
var text = document.createElement("span");
text.textContent = ` item${i+1} `
addBtn.innerHTML = '+';
dropBtn.innerHTML = '-';
addBtn.id = `addBtn${i+1}`;
dropBtn.id = `dropBtn${i+1}`;
addBtn.addEventListener('click', e => {
alert(`here be addBtn with id ${e.target.id}`);
})
dropBtn.addEventListener('click', e => {
alert(`here be dropBtn with id ${e.target.id}`);
})
li.appendChild(addBtn);
li.appendChild(text);
li.appendChild(dropBtn);
ul.appendChild(li);
}
<ul id="cart"></ul>

Why does deleting this element with a non-unique ID delete the one I want?

Pardon the bad title, it's hard to explain. If you know how to phrase it better, please comment and I will update as soon as I can.
So, I was messing around with a random generator site (perchance.org) and writing my own HTML/Javascript to make my generator work. It has a behavior that is what I want, but that shouldn't be happening according to my knowledge of HTML.
Let me explain with a minimal example.
The example code here is to produce a simple page that has a button.
This button should generate <input>s with <button>s next to them, attached with similar ID's.
The button, when clicked, deletes the <input> and <button>.
Here is a snippet to show you the code/let you reproduce the results:
<html>
<head>
<script>
var current_id = 0;
function add_input () {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + current_id;
delete_button.id = "button_" + current_id;
br.id = "br_" + current_id;
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.onclick = function () {
delete_input(this.id.slice(7)) //To get the numerical ID
}
list.appendChild(input);
list.appendChild(delete_button);
list.appendChild(br);
current_id++;
}
function delete_input (id) {
var input = document.getElementById("input_"+id);
var button = document.getElementById("button_"+id);
var br = document.getElementById("br_"+id);
input.remove();
button.remove();
br.remove();
current_id--;
}
</script>
</head>
<body>
<div id="list">
</div>
<button onclick="add_input()">Add</button>
</body>
</html>
When you add two inputs, then delete the first, and add one more, it leaves you with two inputs using the same ID. It also leaves you with two buttons with the same ID. And yet, both buttons delete their intended target.
Why?
You really should delegate - here I wrap in a div that can be removed in one go
You can rename each input to have incremented IDs but just letting the cnt run, gives you unique IDs
let cnt = 0;
function add_input() {
var list = document.getElementById("list");
var div = document.createElement("div");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
input.id = "input_" + (cnt++)// list.querySelectorAll("div").length
input.value = input.id;
delete_button.textContent = "Delete";
delete_button.classList.add("delete")
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div);
}
window.addEventListener("load", function() {
document.getElementById("list").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("delete")) tgt.closest("div").remove();
})
})
<div id="list">
</div>
<button onclick="add_input()">Add</button>
I changed your code to be more effective.
I'm not using IDs as they aren't adding any benefit instead making it more complex.
Instead I target the element via the event handler and an argument.
I also wrap each set of inputs/buttons in a div so I can just remove that div and it will remove all of the children.
function add_input() {
var list = document.getElementById("list");
var input = document.createElement("input");
var delete_button = document.createElement("button");
var br = document.createElement("br");
delete_button.textContent = "Delete";
delete_button.onclick = function(e) {
e.target.parentNode.remove();
}
var div = document.createElement("div");
div.appendChild(input);
div.appendChild(delete_button);
div.appendChild(br);
list.appendChild(div)
}
<div id="list">
</div>
<button onclick="add_input()">Add</button>

Javascript DOM manipulation, Each click creates a new li element

I have an app with a few buttons, and every button has an element, button one has a "banana" and button 2 has an "apple", when the user clicks on those buttons, a new li element should be added to a list. Here is a JSFiddle with an example of the problem I'm running into:
https://jsfiddle.net/ejha3q94/
Only 1 li is created with every click and the elements are just added on that same li.
var newElement = document.createElement("li");
var newElText = document.createTextNode ("");
document.getElementById("itemOne").addEventListener("click", function() {
newElText = document.createTextNode("Banana");
document.getElementById("list").appendChild(newElement).appendChild(newElText);
});
document.getElementById("itemTwo").addEventListener("click", function() {
newElText = document.createTextNode("Apple");
document.getElementById("list").appendChild(newElement).appendChild(newElText);
});
How can I make it so every click is a new li element using only Javascript?
You can't reuse elements by reassigning them. You have to create a new element each time you wish to insert a new element into the DOM.
This solution creates a generic function addItem for your procedure. You can see all the element creation and DOM manipulation in one place.
// element references
var list = document.getElementById('list');
var appleBtn = document.getElementById('apple');
var bananaBtn = document.getElementById('banana');
// DOM manipulating function
function addItem(listElem, text) {
var li = document.createElement('li');
var textNode = document.createTextNode(text);
listElem.appendChild(li).appendChild(textNode);
}
// event listeners
appleBtn.addEventListener('click', function(event) {
addItem(list, 'apple');
});
bananaBtn.addEventListener('click', function(event) {
addItem(list, 'banana');
});
<ul id="list"></ul>
<button id="apple">Apple</button>
<button id="banana">Banana</button>
But even repeating addItem(list, *) can get repetitious too. Plus, we don't necessarily need one event listener per button. Wouldn't it be nice if we could just use a single event listener to handle all of the cases?
The solution below uses a data-* attribute to store each button's contribution to the list. Then, using event delegation we handle all buttons with a single event listener (function).
// element references
var list = document.getElementById('list');
var buttons = document.getElementById('buttons');
// single #buttons event delegate
buttons.addEventListener('click', function(event) {
// event.target contains the element that was clicked
var item = event.target.dataset.item;
if (item === undefined) return false;
var li = document.createElement('li');
var textNode = document.createTextNode(item);
list.appendChild(li).appendChild(textNode);
});
<ul id="list"></ul>
<div id="buttons">
<button data-item="apple">Apple</button>
<button data-item="banana">Banana</button>
<button data-item="orange">Orange</button>
<button data-item="grape">Grape</button>
<button data-item="plum">Plum</button>
</div>
Make sure that var newElement and newElText is created or cloned on every click instead of referenced: https://jsfiddle.net/ejha3q94/2/
Otherwise it won't create a new list element but modifies the existing list element every time.
document.getElementById("itemOne").addEventListener("click", function() {
var newElement = document.createElement("li");
var newElText = document.createTextNode("Banana");
document.getElementById("list").appendChild(newElement).appendChild(newElText);
});
document.getElementById("itemTwo").addEventListener("click", function() {
var newElement = document.createElement("li");
var newElText = document.createTextNode("Apple");
document.getElementById("list").appendChild(newElement).appendChild(newElText);
});
You can use document.querySelectorAll() with selector "[id^=item]"; iterate elements using for..of loop; create the elements within click event handler; append #text node to li element using HTMLElement.dataset before appending li element to ul element
<div id="itemOne" data-fruit="Banana">
🍌
</div>
<div id="itemTwo" data-fruit="Apple">
🍎
</div>
<ul id="list"> </ul>
<script>
var list = document.getElementById("list");
for (el of document.querySelectorAll("[id^=item]")) {
el.addEventListener("click", function() {
list.appendChild(document.createElement("li"))
.textContent = this.dataset.fruit;
})
}
</script>
jsfiddle https://jsfiddle.net/ejha3q94/4/
There can only be a single newElText node. If you append it multiple times, it will just be moved. You should clone it manually:
var newElement = document.createElement("li");
var list = document.getElementById("list");
document.getElementById("itemOne").addEventListener("click", function() {
var newElText = document.createTextNode("Banana");
list.appendChild(newElement.cloneNode(false)).appendChild(newElText);
});
document.getElementById("itemTwo").addEventListener("click", function() {
var newElText = document.createTextNode("Apple");
list.appendChild(newElement.cloneNode(false)).appendChild(newElText);
});
<div id="itemOne">🍌</div>
<div id="itemTwo">🍎</div>
<ul id ="list"></ul>

JS problems with adding li

I have a problem with adding li. When I add new li text be in first li and should be in the next. https://jsfiddle.net/zaxmy1nw/1/
Probably problem is here.
function NewLI(){
AddLi;
userp.appendChild(userName);
LiP.appendChild(LiText);
var UladdLi = document.getElementById("chat").appendChild(AddLi);
var AddP = document.getElementById("lispan").appendChild(LiP);
var UseraddLi = document.getElementById("lispan").appendChild(userp);
}
You select by Id, but all li elements have the same id (lispan) so selecting by id will always return the first one.
What you can do is :
function NewLI(){
AddLi;
userp.appendChild(userName);
LiP.appendChild(LiText);
AddLi.appendChild(LiP)
AddLi.appendChild(userp)
var UladdLi = document.getElementById("chat").appendChild(AddLi);
}
see : https://jsfiddle.net/zaxmy1nw/2/

Categories

Resources