I'm trying to make todolist where I can add new tasks to do with same functionality as default ones (clickable task with 'delete' button next to it). My current code is creating new button, but it's only empty, grey rectangle, without any content (but it works as it should - it's deleting selected task) - how can I set content of new buttons as "delete"?
SNIPPET
function createListElement() {
var li = document.createElement("li");
var span = document.createElement("span");//create span
var button1 = document.createElement("button");//create button
span.appendChild(document.createTextNode(input.value)); //assign value to span
span.classList.add("complited"); //add class "complited" to span
li.appendChild(span); //put span as li child
ul.appendChild(li); // put li as ul child
li.appendChild(button1);
button1.classList.add("buttonli");
button1.value("Delete"); // here I've got error "button1.value is not a function"
li.classList.add("clickable"); //asign "clickable" class to li
input.value = "";
}
<ul id="ul1">
<li class="bold red clickable" random="23"><span class="complited">Notebook</span><button class="buttonli">Delete</button></li>
<li class="clickable"><span class="complited">Jello</span> <button class="buttonli">Delete</button></li>
<li class="clickable"><span class="complited">Spinach</span> <button class="buttonli">Delete</button></li>
<li class="clickable"><span class="complited">Rice</span> <button class="buttonli">Delete</button></li>
<li class="clickable"><span class="complited">Birthday Cake</span> <button class="buttonli">Delete</button></li>
<li class="clickable"><span class="complited">Candles</span> <button class="buttonli">Delete</button></li>
</ul>
button1.value("Delete"); // here I've got error "button1.value is not a function"
No, it's a simple accessor property.
button1.value = "Delete"
… but it sets the value that will be submitted when the button is used to submit a form. It doesn't set the display text, which is the content inside the button element.
That's why you wrote:
<button class="buttonli">Delete</button>
and not:
<button class="buttonli" value="Delete"></button>
So create a text node and put it inside the button:
const button_text = document.createTextNode("Delete");
button1.appendChild(button_text);
function createListElement() {
var li = document.createElement("li");
var span = document.createElement("span"); //create span
var button1 = document.createElement("button"); //create
var ul = document.getElementById("ul1"); //ul
var input = document.createElement("input"); //ul
span.appendChild(document.createTextNode(input.value)); //assign value to span
span.classList.add("complited"); //add class "complited" to span
li.appendChild(span); //put span as li child
ul.appendChild(li); // put li as ul child
li.appendChild(button1);
button1.classList.add("buttonli");
button1.innerHTML = "Delete"; //Because you are using a <button> instead of <input type="button">, you need to set the innerHTML
li.classList.add("clickable"); //asign "clickable" class to li
input.value = "";
}
That is because you are using a instead of therefore you need to set the innerHTML.
Check this answer here
Check the fiddle bellow.
Jsfiddle with solution
Related
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>
Student here!
Lets say i have function append() which generates <li> items inside an <ol>,those li items contain 2 buttons,one for removing the <li> that lies within and one for creating the same item but inside itself this time,in order to make another list layer.
Both by using the closest() method.
i cant figure out how to use the ADD <button>,i can call it but i cannot it make it work the way i want to.
I get this :
But i want to get something like this :
this is how i'm trying to do it :
function append() {
var ol = document.getElementById("ol1");
var li = document.createElement("li");
li.innerHTML = (`LIST ITEM <input class=input><button class=add>ADD</button><button class=remove>REMOVE</button>`);
ol.append(li)
document.getElementById("ol1").addEventListener("click",function(e) {
const tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("li").remove();
if (tgt.classList.contains("add")) tgt.closest("li").appendChild(li);
})
}
<html>
<body>
<button id="btn1" onclick="append()">Append</button>
<ol id="ol1">
</ol>
</body>
</html>
To number with 1., 1.1, 1.2, 2., 2.1, 3., you need to use CSS. The counters function, obtains the number of the li. Each time an ol appears, the counter is reset to 1.. When a li appears, the top counter is used, concatenated with the new next new number of the previous li.
ol {
counter-reset: item
}
li {
display: block;
}
li:before {
content: counters(item, ".") ". ";
counter-increment: item;
}
In the append function, we add the li... For this, we call another function, which we will call create_li() which does the creation of the li.
function append() {
document.querySelector("#ol1").append( create_li() )
}
In the create_li() function, we create the li and return it with return li. In li, we add the two button elements, add and remove, but instead of doing it through a string, we do it with the function we already know, that is to say, document.createElement(), and also, on each button, we can add una función que llamaremos button_click function, used to receive the click event through addEventListener.
function create_li(){
var li = document.createElement("li")
var add = document.createElement("button")
var remove = document.createElement("button")
li.innerHTML = "LIST ITEM <input class=input>"
add.className = "add"
remove.className = "remove"
add.innerHTML = "+"
remove.innerHTML = "-"
add.addEventListener("click",button_click)
remove.addEventListener("click",button_click)
li.appendChild(add)
li.appendChild(remove)
return li
}
The button_click function, what it does is create the ol and li structure. In addition, it detects if the button clicked is the add or remove.
function button_click(e) {
const tgt = e.target;
var litg = tgt.closest("li")
var oltg = litg.querySelector("ol")
if(oltg==null){
var ol = document.createElement("ol")
litg.appendChild(ol)
oltg = ol
}
if (tgt.classList.contains("remove")){
litg.remove()
}
if (tgt.classList.contains("add")){
oltg.appendChild( create_li() )
}
}
The HTML structure is based on the li has to be inside the ol, and each sublist has to have an ol inside the li.
<ol>
<li>
1.
<ol>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ol>
</li>
<li>
2.
<ol>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ol>
</li>
<li>
3.
<ol>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ol>
</li>
</ol>
Finished code:
function button_click(e) {
const tgt = e.target;
var litg = tgt.closest("li")
var oltg = litg.querySelector("ol")
if(oltg==null){
var ol = document.createElement("ol")
litg.appendChild(ol)
oltg = ol
}
if (tgt.classList.contains("remove")){
litg.remove()
}
if (tgt.classList.contains("add")){
oltg.appendChild( create_li() )
}
}
function create_li(){
var li = document.createElement("li")
var add = document.createElement("button")
var remove = document.createElement("button")
li.innerHTML = "LIST ITEM <input class=input>"
add.className = "add"
remove.className = "remove"
add.innerHTML = "+"
remove.innerHTML = "-"
add.addEventListener("click",button_click)
remove.addEventListener("click",button_click)
li.appendChild(add)
li.appendChild(remove)
return li
}
function append() {
document.querySelector("#ol1").append( create_li() )
}
ol {
counter-reset: item
}
li {
display: block;
}
li:before {
content: counters(item, ".") ". ";
counter-increment: item;
}
<button id="btn1" onclick="append()">Append</button>
<ol id="ol1"></ol>
This is probably what you want?
function append() {
var ol = document.getElementById("ol1");
var li = document.createElement("li");
li.innerHTML = (`LIST ITEM <input class="input"><button class="add" onclick="add(this)">ADD</button><button class="remove" onclick="remove(this)">REMOVE</button><ol></ol>`);
ol.append(li)
}
function add(e) {
var li = document.createElement("li");
li.innerHTML = (`LIST ITEM <input class="input"><button class="add" onclick="add(this)">ADD</button><button class="remove" onclick="remove(this)">REMOVE</button><ol></ol>`);
e.parentElement.getElementsByTagName("ol")[0].appendChild(li);
}
function remove(e) {
e.parentElement.parentElement.removeChild(e.parentElement);
}
<html>
<body>
<button id="btn1" onclick="append()">Append</button>
<ol id="ol1">
</ol>
</body>
</html>
Instead of using 'closest' in the add method, you can simply find the parent and append in that.
EG : tgt.parentNode().appendchild(childLi)
So my problem is very simple, but I have struggled to find an answer.
I have created a list and I want to add the a tag inside the <li> tag and then setAttribute to that <a> tag using JS:
<ul>
<li>one</li> <!-- This is what a have right now -->
<li>one</li> <!-- This is what I want -->
</ul>
"use strict";
// This first line you most probably have to change according to your context
// This get the first element of all the li tags in the whole document
const li = document.getElementsByTagName('li')[0]
// This gets the text content ('one') of that 'li'
const tc = li.textContent
// This removes the first child content of li, which is the text
li.childNodes[0].remove()
// This will create a new 'a' element, set the href attribute, insert the text from above into it
// and that insert this 'a' into the 'li'
const a = document.createElement('a')
a.textContent = tc
a.setAttribute('href', '#HTML')
li.append(a)
<ul>
<li>one</li>
</ul>
// select the <li>
const li = document.querySelector('li');
// create the <a>
const a = document.createElement('a');
a.href='#html';
a.innerText = li.innerText;
// empty <li> and replace its content by <a>
li.innerHTML = '';
li.appendChild(a);
<ul>
<li>one</li>
</ul>
I am creating a Todolist, when I write something in the input and use the function addNewFunc() it adds a new li, the problem is that it always just overrides that li, it never makes a new li. (example: I write 1 in the input, use the function and 1 will be added as an li, if i write 2 in the input and use the function, that 1 will now become 2, instead of having a 1 and 2)
let input = document.querySelector(".input");
let ul = document.querySelector("ul");
let addNew = document.createElement("li");
let addNewFunc = function () {
let name = ul.appendChild(addNew);
name.textContent = input.value
};
<h1>spooky</h1>
<input type="text" class="input">
<ul>
<li>1</li>
<li>2</li>
</ul>
let input = document.querySelector(".input");
let ul = document.querySelector("ul");
let addNewFunc = function () {
let addNew = document.createElement("li");
addNew.innerHTML = input.value;
let name = ul.appendChild(addNew);
};
<h1>spooky</h1>
<input type="text" class="input"><button onclick='addNewFunc()'> add</button>
<ul>
<li>1</li>
<li>2</li>
</ul>
Create new li element everytime on the function call, add value to it then append to ul element.
A couple of issues.
1) Move let addNew = document.createElement("li"); inside the function. When it's outside the function you're just reusing the same element over and over. If that line is in the function, you create a new element each time the function is called.
2) Might be worth changing that function expression to a function declaration so that it works better as I was picking up the following error in JSFiddle when I was testing the code:
ReferenceError: can't access lexical declaration `addNewFunc' before initialization
let input = document.querySelector(".input");
let ul = document.querySelector("ul");
let button = document.querySelector('button');
button.addEventListener('click', addNewFunc)
function addNewFunc() {
let addNew = document.createElement("li");
addNew.textContent = input.value;
ul.appendChild(addNew);
};
DEMO (I added a button for convenience)
It happens because you have stored ul element in a variable, so you're appending new child at the same position (ul parent is not updated with information about new elements in it).
Try with:
let addNewFunc = function () {
let name = document.querySelector("ul").appendChild(addNew);
};
You can create new li like this:
let addNewFunc = function () {
var ul = document.getElementById("list");
var li = document.createElement("li");
li.appendChild(document.createTextNode("option string"));
ul.appendChild(li);
};
Full code is
let input = document.querySelector(".input");
let ul = document.querySelector("ul");
input.onchange=function(){
let addNew = document.createElement("li");
addNew.innerHTML=this.value;
this.value="";
ul.appendChild(addNew);
}
This should help u.
please note: I have minute changes to your html; here u enter in inputbox and click button to add it to list
here is the fiddle : https://jsfiddle.net/5o2vwdqc/
html
<h1>spooky</h1>
<input type="text" class="input">
<button id="addToList">
Add to List
</button>
<ul id="theList">
<li>1</li>
<li>2</li>
</ul>
js
let input = document.querySelector(".input");
let ul = document.querySelector("ul");
let addNew = document.createElement("li");
document.getElementById("addToList").onclick = function() {
let inputValue = document.getElementsByClassName("input")[0].value;
let addNew = document.createElement("li");
let textNode = document.createTextNode(inputValue);
addNew.appendChild(textNode);
document.getElementById("theList").appendChild(addNew);
}
I have below code:
<ul id='someId'>
<li class='someClass'>
</li>
</ul>
I want to set focus on first li element within ul based on some condition.
My first attempt is like this:
var ul = document.getElementById('someId');
var child = ul.childNodes[0];
child.focus();
My second attempt is like this :
var y = document.getElementsByClassName('someClass');
var aNode = y[0];
aNode.focus();
But none of the above works
Any ideas?
The problem is that you can't focus a non input element without setting tabIndex.
<li tabIndex="-1">...</li>
You can Try this fiddle: jsfiddle
An 'li' can't have focus, however an 'input' can, so you write yourself the following script:
function installLI(obj){
var ul = document.createElement('ul');
obj.appendChild(ul);
var li = document.createElement('li');
var txt = document.createElement('input');
li.appendChild(txt);
ul.appendChild(li);
txt.focus();
li.removeChild(txt);
}
Where 'obj' is the object (like an editable div) that you're appending your list to.