I'm trying to learn JavaScript and am trying to avoid tutorials and guides as much as I can but I'm stuck. I have a tasklist I'm working on. Currently, I can add a new task. Initially I had hard-coded a few starting tasks, Each task that's been hard-coded can be closed(hidden). When I add a new task to the list it is given a close button like the existing tasks, it has the same class as them as well, but will not close. I'm not sure what to do at this point since the new tasks looks like the existing as far as structure and class names but the JavaScript doesn't work on these newly added elements. Here's my code
html:
<div class="container">
<form class="form">
<h2>Tasks to do today: <span id="today"></span> </h2>
<div class="form-control">
<input type="text" id="addTask" placeholder="Add task">
<span onclick="addElement()" class="addBtn">Add</span>
<small>Error Message</small>
</div>
</form>
<ul class="taskList" id="taskList">
<li class="taskItem">item1</li>
<li class="taskItem">item2</li>
<li class="taskItem">item3</li>
<li class="taskItem">item4</li>
</ul>
</div>
JavaScript:
function addClose() {
const nodeList = document.getElementsByClassName("taskItem");
let i;
for (i = 0; i < nodeList.length; i++) {
const span = document.createElement("SPAN");
const txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
nodeList[i].appendChild(span);
}
}
function closeTask() {
const close = document.getElementsByClassName("close");
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
const div = this.parentElement;
div.style.display = "none";
}
}
}
function addElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("addTask").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
li.classList.add("taskItem")
if (inputValue === '') {
alert("You must write something!");
} else {
document.getElementById("taskList").appendChild(li);
}
document.getElementById("addTask").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
// Run Functions
addClose();
closeTask();
Related
I am trying to remove items from my local storage. I m pretty new at this, and I m confused about what to do. Tried different things but nothing worked.
So this is my HTML:
Inside ul, I am creating a ToDo list.
My JS file creates elements inside UL. After each input, the item is saved to local storage.
I have two problems: My items are not adding up to my To-DO list, and can not delete items from local storage after I press the delete button on the span.
<div id="myDiv" class="header">
<h2>My To Do List</h2>
<input type="text" name="text" id="myInput" placeholder="Title...">
<span onclick="newElement()" class="addBtn">Add</span>
</div>
<ul id="myUl"></ul>
<script>
var myNodelist = document.getElementsByTagName("Li");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.addEventListener("click", removeFromLocalStorage);
span.appendChild(txt);
myNodelist[i].appendChild(span);
console.log(span);
}
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
}
var list = document.querySelector("ul");
list.addEventListener(
"click",
function (ev) {
if (ev.target.tagName === "LI") {
ev.target.classList.toggle("checked");
}
},
false
);
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === "") {
alert("You must write something");
} else document.getElementById("myUl").appendChild(li);
inputValue.value = "";
saveToLocalStorage();
var span = document.createElement("span");
span.classList = "close";
var text = document.createTextNode("\u00D7");
span.appendChild(text);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
removeItem();
};
}
}
function saveToLocalStorage() {
var inputValue = document.getElementById("myInput").value;
window.localStorage.setItem("myInput", JSON.stringify(inputValue));
}
Not sure even what I suppose to do. If any explanation about my code would be appreciated.
I can search the person name and surname from the list and I can display the person's name and surname.For example: I have a person who called 'Agne Gabrielle' when I write only 'Gabrielle' to input field I could not display this person name and surname. Because my codes work only for when I write the person'full name.I tries to use split() method but I think I could not use properly so it did not work.
How can I fix this problem?
Thank you in advance.
HTML Codes
const input = document.getElementById("the-filter");
const list = document.getElementById('the-list');
const button = document.getElementById("button");
const element = document.querySelector(".main-div");
const li = document.getElementsByClassName('list-group-item');
const items = document.getElementsByClassName('list-group-item');
const newList = document.querySelector('#myList');
const listDiv = document.querySelector('.list-container');
button.addEventListener('click', listName);
function listName() {
element.style.visibility = "hidden";
listDiv.style.visibility = "visible";
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
input.value = "";
input.focus();
if (!inputTrimmedLower) {
return;
}
for (const lis of items) {
const liTrimmedLower = lis.textContent.trim().toLocaleLowerCase();
if ((liTrimmedLower === inputTrimmedLower)) {
console.log(`${inputTrimmedLower} is already listed`);
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.append(inputTrimmedLower);
newList.prepend(newItem);
input.addEventListener('keyup', function(e) {
if (newList.childElementCount > 1) {
if (newList.hasChildNodes()) {
newList.removeChild(newList.childNodes[0]);
}
}
});
return;
}
}
}
input.addEventListener('keyup', search);
function search() {
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
for (i = 0; i < li.length; i++) {
if (li[i].innerHTML.toLocaleLowerCase().includes(inputTrimmedLower) ||
li[i].innerHTML.toLocaleUpperCase().includes(inputTrimmedLower)) {
li[i].style.display = "";
} else {
li[i].style.display = 'none';
}
}
}
<div class="container mt-5">
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container container">
<ul id="myList" class="list-group">
</ul>
</div>
<div id="button">
<button class=" btn btn-primary btn-lg btn-block" id="button">Click</button>
</div>
</div>
<div class="container">
<ul id="the-list" class="list-group list">
<li class="list-group-item">Adele Ak</li>
<li class="list-group-item">Agne Gabrielle</li>
<li class="list-group-item">Alex Thomson</li>
<li class="list-group-item">Alice</li>
<li class="list-group-item">Anderson</li>
<li class="list-group-item">Anna</li>
</ul>
</div>
There are various tweaks that could be made here - for instance in your search function:
function search() {
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
for (i = 0; i < li.length; i++) {
if (li[i].innerHTML.toLocaleLowerCase().includes(inputTrimmedLower) ||
li[i].innerHTML.toLocaleUpperCase().includes(inputTrimmedLower)) {
li[i].style.display = "";
} else {
li[i].style.display = 'none';
}
}
}
What's the point in the second clause of your if statement? You're converting the input string to lowercase on assignment to the variable, so this: li[i].innerHTML.toLocaleUpperCase().includes(inputTrimmedLower) will always return false... You could also use a conditional assignment, since you're doing nothing else in the if statement.
You can also tidy it up a little bit by doing a foreach (which might be marginally quicker). Those improvements would make your search function:
function search() {
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
li.forEach(function(item) {
item.style.display = item.innerHTML.toLocaleLowerCase().includes(inputTrimmedLower) ? "" : "none";
});
}
As for your listName function, you're essentially saying that you want to find the listitems that contain the value entered by the user and append them to the new list? If so... why reinvent the wheel?
You can do something similar to your search function to find the elements:
function listName() {
element.style.visibility = "hidden";
listDiv.style.visibility = "visible";
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
input.value = "";
input.focus();
li.forEach(function(item) {
if (item.innerHTML.toLocaleLowerCase().includes(inputTrimmedLower)){
let newItem = createElement('li','new-list-group-item');
newItem.append(item.innerHTML);
newList.prepend(newItem);
}
});
}
I'm trying to create a tasklist in javascript. I want the user to be able to add new list items as tasks, but I cannot figure out how to do next...
So my problem is the following:
for each new input the user gives, instead of adding on li-element to the ul-element, new ul-elements keep creating containing only one li-element. How do I do to add li-elements to the same ul-element, without creating new ul-elements for each new task/input created?
This is html and javascript code:
<html>
<body>
<div id="createNewTaskContainer">
<form id="taskForm">
<input id="taskInput" type="text" />
<button type="submit" id="createTaskButton">Add</button>
</form>
</div>
<div id="listOfTasksContainer"></div>
</body>
</html>
let toDoList = [];
window.onload = function () {
let form = document.getElementById("taskForm");
form.addEventListener("submit", addTask); }
function insertTasksInHtml() {
let liElement = document.createElement("li");
let ulElement = document.createElement("ul");
ulElement.appendChild(liElement);
document.getElementById("listOfTasksContainer").innerHTML = "";
document.getElementById("listOfTasksContainer").appendChild(ulElement);
console.log(ulElement);
for (let i = 0; i < toDoList.length; i++) {
liElement.innerText = toDoList[i];
}
}
function addTask(e) {
e.preventDefault();
let taskInput = document.getElementById("taskInput").value;
if (taskInput === "") {
alert("Please insert a task before you submit");
} else {
toDoList.push(taskInput);
insertTasksInHtml();
}
}
let toDoList = [];
window.onload = function () {
let ulElement;
let node;
let textnode;
let form = document.getElementById("taskForm");
form.addEventListener("submit", addTask); }
function insertTasksInHtml(newTask) {
ulElement = document.getElementById("list");
node = document.createElement("li");
textnode = document.createTextNode(newTask);
node.appendChild(textnode);
ulElement.appendChild(node);
}
function addTask(e) {
e.preventDefault();
let taskInput = document.getElementById("taskInput").value;
if (taskInput === "") {
alert("Please insert a task before you submit");
} else {
toDoList.push(taskInput);
insertTasksInHtml(taskInput);
}
}
<html>
<body>
<div id="createNewTaskContainer">
<form id="taskForm">
<input id="taskInput" type="text" />
<button type="submit" id="createTaskButton">Add</button>
</form>
</div>
<div id="listOfTasksContainer">
<ul id="list">
</ul>
</div>
</body>
</html>
Create liElement inside the loop and append to Ul.
function insertTasksInHtml() {
let ulElement = document.createElement("ul");
document.getElementById("listOfTasksContainer").innerHTML = "UL";
document.getElementById("listOfTasksContainer").appendChild(ulElement);
//console.log(ulElement);
for (let i = 0; i < 10; i++) {
let liElement = document.createElement("li");
liElement.innerText = 'LI ' + i;
ulElement.appendChild(liElement);
}
}
insertTasksInHtml();
<div id="listOfTasksContainer">
</div>
I have made a to do list using vanilla JS , each list item has a delete and an edit option , delete works fine, but when I am editing a list item it is not editing the line item on which i use the edit option rather it updates the last added list item
HTML:
<div id="wrapper">
<div id="inputWrapper">
<input type="text" name="" id="listDetail"
placeholder="What's the task about" autofocus>
<button id="addBtn">Add</button>
</div>
<ul id="ul"></ul>
JS:
var listDetail = document.getElementById("listDetail");
var addBtn = document.getElementById("addBtn");
var ul = document.getElementById("ul");
addBtn.onclick = function () {
if (listDetail.value !== "") {
var li = document.createElement("LI");
ul.appendChild(li);
}
else {
alert("List item cannot be empty");
}
var entry = document.createElement("SPAN");
var entryText = document.createTextNode(listDetail.value);
entry.className = "userEntry";
entry.appendChild(entryText);
li.appendChild(entry);
var span = document.createElement("SPAN");
var spanText = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(spanText);
li.appendChild(span);
var close = document.getElementsByClassName("close");
for (var i = 0; i < close.length; i++) {
close[i].onclick = function () {
this.parentElement.style.display = "none";
}
}
var edit = document.createElement("SPAN");
var eText = document.createTextNode("\u270E");
edit.className = "edit";
edit.appendChild(eText);
li.appendChild(edit);
var editC = document.getElementsByClassName("edit");
for (var e = 0; e < editC.length; e++) {
editC[e].onclick = function () {
var p = prompt("Edit your entry");
entry.innerText = p;
}
}
var liTag = document.getElementsByTagName("LI");
for (var j = 0; j < liTag.length; j++) {
liTag[j].onclick = function () {
this.classList.toggle("checked");
}
}
listDetail.value = "";
}
How do I ensure it updates the right line item?
Here lies your problem:
var entry = document.createElement("SPAN"); // <<<
...
for (var e = 0; e < editC.length; e++) {
editC[e].onclick = function () {
var p = prompt("Edit your entry");
entry.innerText = p; // <<< you are modifying the entry that you've just created
}
}
I don't see a need for a for loop.
var listDetail = document.getElementById("listDetail");
var addBtn = document.getElementById("addBtn");
var ul = document.getElementById("ul");
addBtn.onclick = function () {
if (listDetail.value !== "") {
var li = document.createElement("LI");
ul.appendChild(li);
}
else {
alert("List item cannot be empty");
}
var entry = document.createElement("SPAN");
var entryText = document.createTextNode(listDetail.value);
entry.className = "userEntry";
entry.appendChild(entryText);
li.appendChild(entry);
var close = document.createElement("SPAN");
var cText = document.createTextNode("\u00D7");
close.className = "close";
close.appendChild(cText);
li.appendChild(close);
close.onclick = function () {
this.parentElement.style.display = "none";
}
var edit = document.createElement("SPAN");
var eText = document.createTextNode("\u270E");
edit.className = "edit";
edit.appendChild(eText);
li.appendChild(edit);
edit.onclick = function () {
var p = prompt("Edit your entry");
var entry = this.parentElement.getElementsByClassName("userEntry")[0]; // get sibling userEntry element
entry.innerText = p;
}
li.onclick = function () {
this.classList.toggle("checked");
}
listDetail.value = "";
}
<body>
<div id="wrapper">
<div id="inputWrapper">
<input type="text" name="" id="listDetail" placeholder="What's the task about" autofocus>
<button id="addBtn">Add</button>
</div>
<ul id="ul"></ul>
You have to create an ID for each specific tag, and when the user edits it uses that rather than the class.
var listDetail = document.getElementById("listDetail");
var addBtn = document.getElementById("addBtn");
var ul = document.getElementById("ul");
var cnt = 0
addBtn.onclick = function() {
if (listDetail.value !== "") {
var li = document.createElement("LI");
ul.appendChild(li);
} else {
alert("List item cannot be empty");
}
var entry = document.createElement("SPAN");
var entryText = document.createTextNode(listDetail.value);
entry.className = "userEntry";
entry.setAttribute("id", "entry" + cnt);
entry.appendChild(entryText);
li.appendChild(entry);
var span = document.createElement("SPAN");
var spanText = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(spanText);
li.appendChild(span);
var close = document.getElementsByClassName("close");
for (var i = 0; i < close.length; i++) {
close[i].onclick = function() {
this.parentElement.style.display = "none";
}
}
var edit = document.createElement("SPAN");
var eText = document.createTextNode("\u270E");
edit.className = "edit";
edit.setAttribute("id", "edit" + cnt);
edit.appendChild(eText);
li.appendChild(edit);
var editC = document.getElementById("edit" + cnt);
editC.onclick = function() {
var p = prompt("Edit your entry");
var obj = document.getElementById("entry" + cnt);
obj.innerText = p;
}
var liTag = document.getElementsByTagName("LI");
for (var j = 0; j < liTag.length; j++) {
liTag[j].onclick = function() {
this.classList.toggle("checked");
}
}
listDetail.value = "";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vquery/5.0.1/v.min.js"></script>
<div id="wrapper">
<div id="inputWrapper">
<input type="text" name="" id="listDetail" placeholder="What's the task about" autofocus>
<button id="addBtn">Add</button>
</div>
<ul id="ul"></ul>
I wan't add element after every DIV tag, while 'i=0','i=1','i=2'...untill 'max-DIV.length'. What should I do? I'm just a little worry.. OH!
var NewSpan = document.createElement("span");
NewSpan.setAttribute("id", "gotop");
var NewSpanText = document.createTextNode("to be continue...");
NewSpan.appendChild(NewSpanText);
var i = 0;
var OldDiv = document.getElementsByTagName('div')[i];
var parent = OldDiv.parentNode;
if (parent.lastChild == OldDiv) {
parent.appendChild(NewSpan);
} else {
parent.insertBefore(NewSpan, OldDiv.nextSibling);
};
<div id="n1">DIV</div>
<div id="n2">DIV</div>
<div id="n3">DIV</div>
<div id="n4">DIV</div>
lile this
You need to wrap this in a for loop and create a new span element every time you want to insert one.
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
var NewSpan = document.createElement("span");
NewSpan.setAttribute("id", "gotop" + i); // Can't have duplicate IDs
var NewSpanText = document.createTextNode("to be continue...");
NewSpan.appendChild(NewSpanText);
var OldDiv = divs[i];
var parent = OldDiv.parentNode;
if (parent.lastChild == OldDiv) {
parent.appendChild(NewSpan);
} else {
parent.insertBefore(NewSpan, OldDiv.nextSibling);
}
}
<div id="n1">DIV</div>
<div id="n2">DIV</div>
<div id="n3">DIV</div>
<div id="n4">DIV</div>