Why won't all of my new notes inherit the button function? - javascript

I have the following JavaScript code that is triggered once DOM is loaded:
const add_note = () => {
// Creates a new note and its props
const new_note = document.createElement("div");
const new_input = document.createElement("input");
const new_form = document.createElement("form");
const new_ol = document.createElement("ol");
const new_button = document.createElement("button");
//Populates the new note with inputs and checkboxes
for (let i = 0; i < 5; i++) {
let new_li = document.createElement("li");
let new_checkbox = document.createElement("input");
new_checkbox.setAttribute("type", "checkbox");
let new_li_input = document.createElement("input");
new_li_input.classList.add("li_input");
new_ol.appendChild(new_li);
new_li.appendChild(new_checkbox);
new_li.appendChild(new_li_input);
}
//New note's settings
new_note.setAttribute("id", "note");
new_note.classList.add("note");
new_note.appendChild(new_input);
new_input.classList.add("note_input");
new_input.setAttribute("placeholder", "Note's title");
new_note.appendChild(new_form);
new_form.appendChild(new_ol);
new_ol.setAttribute("id", "ol_id");
new_note.appendChild(new_button);
new_button.classList.add("more_items");
new_button.setAttribute("id", "more_items");
//Inserts the new note and button
const note_block = document.getElementById("notes");
note_block.appendChild(new_note);
const button = document.getElementById("more_items");
button.addEventListener("click", add_more_items);
button.innerHTML = "+";
};
However, once the notes are created, only the first note button inherits its functions as seen on the following image:
Code loaded
I've tried about everything I can but couldn't figure it out. Anyway thanks in advance.

IDs are unique in html, you can't have multiple elements with the same id
Either remove these lines, make them into classes, or somehow distinguish them:
new_note.setAttribute("id", "note");
...
new_ol.setAttribute("id", "ol_id");
...
new_button.setAttribute("id", "more_items");
And just refer to the button with the variable:
const note_block = document.getElementById("notes");
note_block.appendChild(new_note);
new_button.addEventListener("click", add_more_items);
new_button.innerHTML = "+";
You could actually even move these last two lines up to the rest of your code before appending the note block.

Related

How to accessing the value in fieldset

I am writing a code that will allow users to write note, I'm using fieldset instead of textarea. I need to access the value in the fieldset and make use of the text. I can't access it unless I add an input elements.
const write = document.querySelector("#write");
const body = document.querySelector("body");
const form = document.querySelector("#form")
const list = document.querySelector("#list");
const button = document.createElement("button");
write.addEventListener("click", function (e){
e.preventDefault()
console.log(e);
const page = document.createElement("form");
const fieldset = document.createElement("fieldset");
page.action = "./nowhere";
fieldset.contentEditable = true;
fieldset.id = "text";
fieldset.name = "text";
// fieldset.append(input)
page.append(fieldset);
write.append(page);
page.append(button);
const myText = write.form.fieldset.value;
console.log(myText);
})

How to get respective dynamically created element values on button click

I have created a card structure based on results array fetched from API as:
results holds the list of fetched data
resultsDiv is an empty div to append all cards in it
created cards as :
results.forEach((pred, idx) => {
const card = document.createElement('div')
card.classList.add('card');
card.id = idx;
const image = document.createElement('img');
image.src = pred["image_path"]
image.classList.add('image-style')
card.append(image)
const info = document.createElement('h4')
info.innerText = 'Tenant ID: ' + pred["tenant_id"]
card.append(info)
resultsDiv.append(card)
const ol = document.createElement('ol')
pred['prediction'].forEach(p => {
const li = document.createElement('li')
const checkbox = document.createElement("INPUT");
checkbox.setAttribute("type", "checkbox");
li.innerText = p
li.appendChild(checkbox)
ol.appendChild(li)
})
card.append(ol)
const btn = document.createElement('button')
btn.innerText = 'Verify'
btn.classList.add('verify-btn')
const textarea = document.createElement('textarea')
textarea.placeholder = 'comments...'
card.append(btn)
card.append(textarea)
})
Now I want to get all the data that are selected on respective card on clicking its own button (each button i have added an event listener)
currently I am getting the values using closest this works but i think its not the appropriate way :
btn.addEventListener('click', () => {
const cardDiv = btn.closest('div');
const allElems = cardDiv.childNodes;
const imagePath = allElems[0].src; // image src
const comments = allElems[4].value; //
})
May I know any efficient way of getting the values as above , any guiding links or a solution would be much helpful
TIA

how to create a list in todo app more than one time (only javascript)

i move var liElement = document.createElement('li'); out side the function addTodo() to make this function work
function removeTodo(){
liElement.remove()
};
but now i have another problem that is i can't add more than one todo (li)
const input = document.getElementById('input');
const addBtn = document.getElementById('btn');
const todoList = document.getElementById('todoList');
var ulElement = document.createElement('ul');
var liElement = document.createElement('li');
let placeholderValue = '';
// This code is for clear placeholder value
input.addEventListener('focus' , () => {
placeholderValue = input.placeholder;
input.placeholder = '';
});
input.addEventListener('blur' , ()=> {
input.placeholder = placeholderValue;
});
// this function is for add to do to a list
function addTodo(){
todoList.appendChild(ulElement)
ulElement.appendChild(liElement);
liElement.classList.add('liElement')
liElement.innerHTML = input.value;
};
addBtn.addEventListener('click' , addTodo)
// this function is for remove todo from the list
function removeTodo(){
liElement.remove()
};
liElement.addEventListener('contextmenu' , (e) => {
e.preventDefault()
removeTodo()
});
You don't use createTextNode for example :
var t = document.createTextNode(input.value);
liElement.appendChild(t);
...and you have builded a very complex structure. Make it easier for yourself.
And finally
const todoList = document.getElementById('todoList');
var ulElement = document.createElement('ul');
why use to createElements ? you don't need these. You can create them in html file.

Loop doubles the number of notes in note app

I'm making a small project for keeping notes. Everytime I click "Add a new note" note is added. After clicking second or more times the "Add" button, the loop keeps adding wrong amount of notes. First is 1 then 3,6,10 and so on.
document.querySelector('#newNoteBtn').addEventListener('click', onNewNote);
function onNewNote() {
const title = document.querySelector('#noteTitle').value;
const content = document.querySelector('#noteContent').value;
const note = {
title: title,
content: content,
colour: '#ff1455',
pinned: false,
createDate: new Date()
}
notes.push(note);
console.log(note);
localStorage.setItem(lsNotesKey, JSON.stringify(notes));
const notesFromLocalStorage = JSON.parse(localStorage.getItem(lsNotesKey));
const convertedNotes = notesFromLocalStorage.map( note => {
note.createDate = new Date(note.createDate);
return note;
});
const notesContainer = document.querySelector('main');
for (const note of convertedNotes) {
const htmlNote = document.createElement('section');
const htmlTitle = document.createElement('h1');
const htmlContent = document.createElement('p');
const htmlTime = document.createElement('time');
const htmlButton = document.createElement('button');
htmlNote.classList.add('note');
htmlTitle.innerHTML = note.title;
htmlContent.innerHTML = note.content;
htmlTime.innerHTML = note.createDate.toLocaleString();
htmlButton.innerHTML = 'remove';
htmlButton.addEventListener('click', removeNote);
htmlNote.appendChild(htmlTitle);
htmlNote.appendChild(htmlContent);
htmlNote.appendChild(htmlTime);
htmlNote.appendChild(htmlButton);
notesContainer.appendChild(htmlNote);
}
}
You just never clean up your container, but adding whole set of nodes on each call.
Easiest way to solve that is to cleanup notesContainer:
// ...
const notesContainer = document.querySelector('main');
notesContainer.innerHTML = ''; // <-- this line cleans up your container.
for (const note of convertedNotes) {
// ...
This isn't optimal. From performance prospective, it better to add only newly created note, but this should hightlight the issue.
Looks like you are never clearing the contents of noteContainer:
// before the loop
notesContainer.innerHtml = ""
Good luck!

JavaScript Class Constructor and DOM (Updated)

I am new to programming, and I don't quite grasp the idea of utilizing class constructor in real life. For instance, let's just say I am trying to create a DOM event handler so I can take user input and push it into CreateTodoList.todos array.
class CreateTodoList {
constructor(list) {
this.todoList = list;
this.todos = [];
}
Then let's just assume that I have built addTodo() function which takes text parameter where an user enters her/his todo.
addTodo(text) {
this.todos.push(text);
this.todoList.appendChild(CreateTodoList.addtoList(text));
}
Here, addtoList creates DOM element that takes value of the user input.
This addTodo function, then pushes the text parameter into the array I made in constructor, while also calling addtoList that makes the DOM element.
Now, let's say I click on "add" button where it takes user input value.
I will build an event handler that responds to click which will add user input to the todoList.
CreateTodoList.eventHandler('click', (e) => {
let userText.todos = document.querySelector(#userInput).value;
addTodo(userText);
})
I am trying to build an eventHandler here, so I can add user input to todoList, and have implemented this several times, but had no luck but receiving reference error.
Below is my full code.
/** #format */
const add = document.querySelector('#btn_add');
let addInput = document.querySelector('#add');
const form = document.querySelector('#form');
class CreateTodoList {
constructor(list) {
this.todoList = list;
this.todos = [];
}
addtoList(text) {
let checkboxEl = document.createElement('span');
checkboxEl.classList.add('round');
let checkboxEl2 = document.createElement('input');
checkboxEl2.id = 'checkbox';
checkboxEl2.type = 'checkbox';
let checkboxEl3 = document.createElement('label');
checkboxEl3.htmlFor = 'checkbox';
checkboxEl.appendChild(checkboxEl2);
checkboxEl.appendChild(checkboxEl3);
let todoTextEl = document.createElement('input');
todoTextEl.value = text;
todoTextEl.disabled = true;
todoTextEl.classList.add('edit_input');
todoTextEl.id = 'edit_input';
todoTextEl.type = 'text';
todoTextEl.name = 'edit_input';
let todoTextEl2 = document.createElement('label');
todoTextEl2.htmlFor = 'edit_input';
let editEl = document.createElement('i');
editEl.classList.add('far');
editEl.classList.add('fa-edit');
let deleteEl = document.createElement('i');
deleteEl.classList.add('far');
deleteEl.classList.add('fa-trash-alt');
let dateEl = document.createElement('small');
dateEl.textContent = timeago.format(new Date());
let liEl = document.createElement('li');
liEl.appendChild(checkboxEl);
liEl.appendChild(todoTextEl);
liEl.appendChild(todoTextEl2);
liEl.appendChild(editEl);
liEl.appendChild(deleteEl);
liEl.appendChild(dateEl);
let list = document.querySelector('ul');
list.appendChild(li);
return liEl;
}
removeFromList(text) {
let list = document.querySelector('ul');
let childs = Array.from(list.childNodes);
let removable = child.find((i) => i.innerText === text);
return item;
}
//todos 배열(todo 데이터에) text를 추가한다.
//todoList 에 liEL(리스트 엘레먼트) 를 append 한다.
addTodo(text) {
this.todos.push(text);
this.todoList.appendChild(CreateTodoList.addtoList(text));
}
removeTodo(text) {
let removed = this.todos.filter((el) => el !== text);
todo.todoList.removeChild(CreateTodoList.removeFromList(text));
this.todos = removed;
}
get getList() {
return this.todos;
}
}
class Handlers {}

Categories

Resources