Add span text to input text value on click - javascript

I am looking for a way to add text from my span tag into the input value field when you click on a checkbox.
I do not want to use jQuery for this, only JavaScript.
I have done it so it adds the text into the input field but when you actually click on the input it doesn't recognise that my text is there. Does anyone know how I go about this so it recognises I have added text to the input field? Any help would be appreciated.
Code here:
const inputContainer = document.querySelector('.input-container');
const spanText = document.querySelector('.span-t');
const checkbox = document.querySelector('#checkbox');
const check = document.getElementById('check');
const btn = document.querySelector('.btn');
/* Add Input Field */
const applyInput = function(){
const inputDiv = document.createElement("div");
const inputContent = `<div class="input-container">
<div>
<input class="input" type="text" name="input-code" value=""></input>
</div>
<button type="submit" class="btn" disabled="">
<span>Submit</span>
</button>
</div>`;
inputDiv.id = "input-container";
inputDiv.innerHTML = inputContent;
};
applyInput();
/* Add Span Text */
const span = document.createElement('div');
if(document.getElementById('p-text') !== null) document.getElementById('p-text').parentNode.removeChild(document.getElementById('p-text'));
span.id = "p-text";
span.innerHTML += '<p class="p-text">P Text<span class="span-t">Span Text</span></p>';
inputContainer.after(span);
/* Add Checkbox */
const addingCheckbox = () => {
if(document.getElementById('checkbox') !== null) document.getElementById('checkbox').parentNode.removeChild(document.getElementById('checkbox'));
const addCheckboxHtml = document.createElement('div');
addCheckboxHtml.id = 'checkbox';
addCheckboxHtml.className = 'checkboxEl';
addCheckboxHtml.innerHTML = `<label class="checkbox"><input type="checkbox" id="check"><span></span></label>`;
if(document.getElementById('checkbox') === null) {
spanText.after(addCheckboxHtml);
}
};
addingCheckbox();
/* Add if Checked */
checkbox.addEventListener('click', () => {
document.querySelector('.input').value = spanText.innerHTML;
});
check.onchange = function() {
btn.disabled = !this.checked;
};

SIMPLIFIED CHECK
You can see that this behavior is totally possible - the little snippet below shows a simplified case.
const span = document.querySelector("#from")
const input = document.querySelector("#to")
const cb = document.querySelector("#cb")
const btReset = document.querySelector("#reset")
const btLog = document.querySelector("#log")
cb.addEventListener("change", function(e) {
input.value = span.innerHTML
})
btReset.addEventListener("click", function() {
cb.checked = false
input.value = ''
})
btLog.addEventListener("click", function() {
console.log("input value:", input.value)
})
.container {
margin-bottom: 16px;
}
<div class="container">
<span id="from">This is the text.</span>
</div>
<div class="container">
<input type="text" id="to" /><input type="checkbox" id="cb" />
</div>
<div class="container">
<button id="reset">RESET</button><button id="log">LOG INPUT VALUE</button>
</div>
CODE UPDATE
Now the snippet you gave works without an error.
/* Add Input Field */
const applyInput = function() {
const inputDiv = document.createElement("div");
const inputContent = `
<div class="input-container">
<div>
<input class="input" type="text" name="input-code" value="" />
</div>
<button type="submit" class="btn" disabled="">
<span>Submit</span>
</button>
</div>
`;
inputDiv.id = "input-container";
inputDiv.innerHTML = inputContent;
// you need to add the created element to the DOM,
// e.g. append it to the body
document.body.append(inputDiv)
};
applyInput();
// only elements that are created can be queried, so
// these variables must be initialized AFTER the element(s)
// they are supposed to get exist in the document (DOM)
const inputContainer = document.querySelector('.input-container');
const btn = document.querySelector('.btn');
/* Add Span Text */
// the creation of the span has to be also encapsulated in
// a function - this way it's easier to handle
const addingSpan = () => {
const span = document.createElement('div');
if (document.getElementById('p-text') !== null) document.getElementById('p-text').parentNode.removeChild(document.getElementById('p-text'));
span.id = "p-text";
span.innerHTML += '<p class="p-text">P Text<span class="span-t">Span Text</span></p>';
inputContainer.after(span);
}
addingSpan()
// element after it is actually created
const spanText = document.querySelector('.span-t');
/* Add Checkbox */
const addingCheckbox = () => {
if (document.getElementById('checkbox') !== null) document.getElementById('checkbox').parentNode.removeChild(document.getElementById('checkbox'));
const addCheckboxHtml = document.createElement('div');
addCheckboxHtml.id = 'checkbox';
addCheckboxHtml.className = 'checkboxEl';
addCheckboxHtml.innerHTML = `<label class="checkbox"><input type="checkbox" id="check"><span></span></label>`;
if (document.getElementById('checkbox') === null) {
spanText.after(addCheckboxHtml);
}
};
addingCheckbox();
// element after it is actually created
const checkbox = document.querySelector('#checkbox');
const check = document.getElementById('check');
/* Add if Checked */
checkbox.addEventListener('click', () => {
document.querySelector('.input').value = spanText.innerHTML;
});
check.onchange = function() {
btn.disabled = !this.checked;
};
UPGRADED CODE
I think the following snippet does what your original code does, but the structure is cleaner, simpler.
const getInputHtml = () => `
<div class="input-container">
<div>
<input class="input" type="text" name="input-code" value=""></input>
</div>
<button type="submit" class="btn" disabled="">
<span>Submit</span>
</button>
</div>
`;
const getSpanHtml = () => `<p class="p-text">P Text<span class="span-t">Span Text</span></p>`;
const getCheckboxHtml = () => `<label class="checkbox-label"><input class="checkbox" type="checkbox" id="check" /></label>`;
// only execute function, if selector cannot be found in DOM
const ifNotExistsInDomFn = (selector) => (fn) => {
if (!document.querySelector(selector)) {
return fn()
}
}
const appendHtmlStrTo = (el) => (str) => {
el.insertAdjacentHTML('beforeend', str)
};
const appendHtmlStrToBody = appendHtmlStrTo(document.body);
// IIFE: Immediately Invoked Function Expression
(function() {
// creating UI
const inputHtml = getInputHtml()
appendHtmlStrToBody(inputHtml)
const spanHtml = getSpanHtml()
ifNotExistsInDomFn(".p-text")(() => appendHtmlStrToBody(spanHtml))
const checkboxHtml = getCheckboxHtml()
ifNotExistsInDomFn(".checkbox")(() => appendHtmlStrToBody(checkboxHtml))
// setting event handlers
const cb = document.querySelector(".checkbox")
cb.addEventListener("click", function() {
document.querySelector(".input").value = document.querySelector(".span-t").innerHTML
})
cb.addEventListener("change", function() {
document.querySelector(".btn").disabled = !cb.checked
})
})();

Related

How can I make my delete function work in my todo app?

I am making a todo app. In the app, there are delete and edit functions. But the Delete function works at the first todo. If I try other todos, It deletes a lot of todos. I tried many ways but disn't work. Please help!
const todoForm = document.querySelector(".todo-form");
const todos = document.querySelector(".todos");
const todoTitle = document.querySelector(".todo-title");
const modal = document.querySelector("#modal");
const modalClose = document.querySelector(".close-button");
const editedText = document.querySelector(".edited-text ");
const submitEdit = document.querySelector(".submit");
const todoList = [];
let totalTodo = 0;
function findFromArray(id, array) {
for (let i = 0; i < array.length; i++) {
if (id === array[i].id) {
return array[i];
}
}
return null;
}
function deleteTodo(id) {
const element = document.getElementById(id);
element.remove();
const data = findFromArray(id, todoList);
todoList.splice(todoList.indexOf(data), 1);
}
function editTodo(id) {
const element = document.querySelector("#" + id + " h1");
modal.showModal();
modalClose.addEventListener("click", () => {
modal.close();
});
submitEdit.addEventListener("click", () => {
const newTodoText = editedText.value;
element.innerText = newTodoText;
modal.close();
});
}
todoForm.addEventListener("submit", (e) => {
e.preventDefault();
let title = todoTitle.value;
const newTodo = document.createElement("div");
const h1 = document.createElement("h1");
const deleteButton = document.createElement("button");
const editButton = document.createElement("button");
deleteButton.innerText = "Delete";
editButton.innerText = "Edit";
todoList.push({
id: "Todo" + totalTodo,
title,
});
totalTodo++;
for (let i = 0; i < todoList.length; i++) {
newTodo.classList.add("todo-card");
todos.appendChild(newTodo);
h1.innerText = todoList[i].title;
deleteButton.addEventListener("click", () => deleteTodo(todoList[i].id));
editButton.addEventListener("click", () => editTodo(todoList[i].id));
newTodo.appendChild(h1);
newTodo.appendChild(deleteButton);
newTodo.appendChild(editButton);
newTodo.id = todoList[i].id;
}
todoTitle.value = "";
});
<body>
<h1 class="todo-heading">Todo App</h1>
<form class="todo-form">
<input class="todo-title" type="text" placeholder="Todo Name" />
<input type="Submit" class="todo-button" />
</form>
<br />
<div class="todos"></div>
<dialog id="modal">
<h1>Edit</h1>
<input type="text" class="edited-text" placeholder="New Todo" />
<br />
<br />
<button class="submit">Submit</button>
<button class="close-button">
<svg class="svg-icon" viewBox="0 0 20 20">
<path
d="M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z"
></path>
</svg>
</button>
</dialog>
I was expecting to remove a todo element and the todo data. But It removes a lot of todo elements and data. I tried the splice method and the delete keyword but didn't work. Please help!
I think the problem is with the for loop you are using to create the new elements. The loop is iterating through the entire todoList array, but it should only be creating a new todo element for the last array item.
todoForm.addEventListener("submit", (e) => {
e.preventDefault();
let title = todoTitle.value;
const newTodo = document.createElement("div");
const h1 = document.createElement("h1");
const deleteButton = document.createElement("button");
const editButton = document.createElement("button");
deleteButton.innerText = "Delete";
editButton.innerText = "Edit";
todoList.push({
id: "Todo" + totalTodo,
title,
});
totalTodo++;
const lastTodo = todoList[todoList.length - 1];
newTodo.classList.add("todo-card");
todos.appendChild(newTodo);
h1.innerText = lastTodo.title;
deleteButton.addEventListener("click", () => deleteTodo(lastTodo.id));
editButton.addEventListener("click", () => editTodo(lastTodo.id));
newTodo.appendChild(h1);
newTodo.appendChild(deleteButton);
newTodo.appendChild(editButton);
newTodo.id = lastTodo.id;
todoTitle.value = "";
});
Also, like Jelmer commented.. In the deleteTodo function, remove todoList =. You should use the splice method directly on the todoList array to remove the element.
todoList.splice(todoList.indexOf(data), 1);

Going through each child in a div generated from API in javascript

I'm trying to access and delete the child in a div generated when I press the "submit" button, the individual divs inside will be generated because there are some functions running with the click, but when I press refresh to delete them nothing happened.
For more clarification here's the src: https://github.com/espnal/wdd230-final-project/blob/main/javascript/js.js
(This is my first post here if you have any suggestions I'm open)
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0]
let dayweather = "Sunday"
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0]["icon"]}#2x.png`;
let individualDiv = document.createElement("Div")
individualDiv.className = "individual"
let description = document.createElement("p")
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4")
day.innerHTML = dayweather
let temperature = document.createElement("p")
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`
let hum = document.createElement("p")
hum.innerHTML = `${firstItem.main.humidity}%`
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city)
SecondItemF(list, city)
ThirdItemF(list, city)
})
});
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.classList.remove("individual");
})
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>
You need to use a linter like this one: https://jshint.com Your code needs a ton of semi-colons and you're missing a bracket and parenthesis }) that .fetch() or submit handler needs. I edited your question just so it doesn't irritate anyone trying to answer the question. You'll see the comment at the bottom of this example showing where I added it, but I guessed because there's no way to test it since there's no key for the API (but not expecting one, so worries there).
Besides that problem, the solution for the problem addressed in the question is the following:
Remove:
contentDiv.classList.remove("individual");
And add:
contentDiv.replaceChildren();
Removing a class doesn't remove the actual elements (well normally unless there's some very convoluted logic going on). .replaceChildren(); without a parameter will remove everything within contentDiv, but if you nee to just remove .individual do the following:
document.querySelector('.individual').remove();
const refresh = document.querySelector("#refresh");
const form = document.querySelector("#form-1");
const contentDiv = document.querySelector(".contentdiv");
const input = document.querySelector("#form-1 input");
//There're another two function like this one below
function firstItemF(list, city) {
let firstItem = list[0];
let dayweather = "Sunday";
const icon = `https://openweathermap.org/img/wn/${firstItem.weather[0].icon}#2x.png`;
let individualDiv = document.createElement("Div");
individualDiv.className = "individual";
let description = document.createElement("p");
description.innerHTML = firstItem.weather[0].description;
let day = document.createElement("h4");
day.innerHTML = dayweather;
let temperature = document.createElement("p");
let kelvin = firstItem.main.temp.toFixed(0);
let f = 9 / 5 * (kelvin - 273) + 32;
temperature.innerHTML = `Current temperature: ${f}℉`;
let hum = document.createElement("p");
hum.innerHTML = `${firstItem.main.humidity}%`;
let img = document.createElement('img');
img.setAttribute('src', icon);
img.setAttribute('alt', "icon");
img.setAttribute('loading', 'lazy');
individualDiv.appendChild(img);
individualDiv.appendChild(day);
individualDiv.appendChild(description);
individualDiv.appendChild(temperature);
individualDiv.appendChild(hum);
contentDiv.appendChild(individualDiv);
}
form.addEventListener("submit", e => {
e.preventDefault();
const inputVal = input.value;
const urlForecast = `https://api.openweathermap.org/data/2.5/forecast?q=${inputVal}&appid=${myKey}`;
fetch(urlForecast)
.then((response) => response.json())
.then((object) => {
console.log(object);
const {
city,
list
} = object;
let title = document.createElement("h3");
title.innerHTML = `${city.name}, ${city.country}`;
titleDiv.appendChild(title);
//im using this one for the example
firstItemF(list, city);
SecondItemF(list, city);
ThirdItemF(list, city);
});
});// <= This is missing
//Here is the problem
refresh.addEventListener("click", (e) => {
contentDiv.replaceChildren();
});
<form id="form-1">
<button type="submit">SUBMIT</button>
<i id="refresh" class="fa-solid fa-arrow-rotate-right"></i>
<input id="input-s2" type="text" placeholder="Search for a city" autofocus>
<div class="cards-container">
<div class="contentdiv">
</div>
</div>
</form>

JavaScript - Comments duplicating on another div

I am creating a comment box and I managed to append whatever I type to a div I wanted, however I have added another input and trying to append that along with the comments, however when I do this the second time,it appends both the previous and current comment therefore the previous comment duplicates. I know I'm doing something wrong in my display_commnents function, however I'm not entirely sure what it could be, basically I just want whatever is entered on both title and comments to append on the comment-box with title on top and comment just below. Below is my code:
<div class="container">
<h1>Write New Post</h1>
<form>
<input id="title" type="text" placeholder="Title" value="">
<textarea id="" placeholder="Leave us a comment" value=""></textarea>
<input id="giphy" type="text">
<div class="btn">
<input id="submit" type="submit" value="comment">
<button id="clear">Cancel</button>
</div>
</form>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comment-box" value="submit">
</div>
</div>
And this is my JS code:
const title = document.querySelector('#title')
const field = document.querySelector('textarea');
const textBackUp = title.getAttribute('placeholder')
const backUp = field.getAttribute('placeholder')
const btn = document.querySelector('.btn');
const clear = document.getElementById('clear')
const submit = document.querySelector('#submit')
// const comments = document.querySelector('#comment-box')
const titleText = document.getElementById('title')
const comments = document.getElementById('comment-box')
let title_arr = [];
let comments_arr = [];
title.onfocus = function(){
this.setAttribute('placeholder', '')
}
title.onblur = function(){
this.setAttribute('placeholder', textBackUp)
}
field.onfocus = function(){
this.setAttribute('placeholder','')
this.style.borderColor = '#333'
btn.style.display = 'block'
} // when clicking on this, placeholder changes into ' ', border colour changes and buttons will appear.
field.onblur = function(){
this.setAttribute('placeholder',backUp)
} //click away, placeholder returns
const display_comments = () => {
let list = '<ul>'
title_arr.forEach(title => {
comments_arr.forEach(comment => {
list += `<li>${title} <br>${comment}`
})
})
list += '</ul>'
comments.innerHTML = list
}
clear.onclick = function(e){
e.preventDefault();
btn.style.display = 'none'
title.value = ''
field.value = ''
display_comments()
}
submit.onclick = function(e){
e.preventDefault();
const head = title.value;
const content = field.value;
if(head.length > 0){
title_arr.push(head)
display_comments();
title.value = '';
}
if(content.length > 0){
comments_arr.push(content)
display_comments();
field.value = '';
}
}
any help would be appreciated
The problem is that you have a double nested loop, producing a Cartesion product of the all the introduced titles and the comments.
To solve this, use only one array for collecting the input, so that title and comment are always kept together in one array entry. Such an entry can be an object with two properties, one for the title, and one for the comment.
Here is your code adapted, just for fixing that issue:
const title = document.querySelector('#title')
const field = document.querySelector('textarea');
const textBackUp = title.getAttribute('placeholder')
const backUp = field.getAttribute('placeholder')
const btn = document.querySelector('.btn');
const clear = document.getElementById('clear')
const submit = document.querySelector('#submit')
// const comments = document.querySelector('#comment-box')
const titleText = document.getElementById('title')
const comments = document.getElementById('comment-box')
let arr = []; // Only one array
title.onfocus = function(){
this.setAttribute('placeholder', '');
}
title.onblur = function(){
this.setAttribute('placeholder', textBackUp);
}
field.onfocus = function(){
this.setAttribute('placeholder','');
this.style.borderColor = '#333';
btn.style.display = 'block';
}
field.onblur = function(){
this.setAttribute('placeholder', backUp);
}
const display_comments = () => {
let list = '<ul>';
// Only one loop -- over objects with two properties
arr.forEach(({head, content}) => {
list += `<li><b>${head}</b><br>${content}`;
})
list += '</ul>';
comments.innerHTML = list;
}
clear.onclick = function(e){
e.preventDefault();
btn.style.display = 'none';
title.value = '';
field.value = '';
display_comments();
}
submit.onclick = function(e){
e.preventDefault();
const head = title.value;
const content = field.value;
// Only one if-block
if(head.length > 0 || content.length > 0){
arr.push({head, content}); // Only one push -- of an object
display_comments();
title.value = '';
field.value = '';
}
}
<div class="container">
<h1>Write New Post</h1>
<form>
<input id="title" type="text" placeholder="Title" value="">
<textarea id="" placeholder="Leave us a comment" value=""></textarea>
<div class="btn">
<input id="submit" type="submit" value="comment">
<button id="clear">Cancel</button>
</div>
</form>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comment-box" value="submit">
</div>
</div>

How to create div inside another div using prototype javascript

my goal is to create div inside another one, but I need to use prototypes for that. To be honest I'm new to programming. I know those objects should have something in common with inheritance, but I couldn't find anything that resolve my problem.
There is a code in HTML
<input type="button" value="div" onclick='ND.createDiv()'>
<input type="button" value="divInside" onclick="NDI.insideCreateDiv()">
<div id='main'></div>
And there is JavaScript code
function Div(text, type){
this.text = text;
this.type = type;
}
Div.prototype.createDiv = function(){
this.type = document.createElement('div');
this.type.innerHTML = this.text;
main.appendChild(this.type);
}
Div.prototype.insideCreateDiv = function(){
let parent = this.type;
const child = document.createElement('div');
child.innerHTML = this.text;
parent.appendChild(child);
}
const ND = new Div('helloDIV', 'div');
const NDI = new Div('helloInsideDIV', 'div');
Thank you for your time
I'm not sure why you would want to use prototypes.
A simple way of doing this is by adding any extra information/configuration to the button themselves and read their values on the click listeners
var parent = document.querySelector("#main");
document.querySelectorAll("[data-bucket]").forEach(function(button) {
var type = button.getAttribute("data-bucket");
var bucket;
button.addEventListener("click", function(event) {
event.preventDefault();
if (bucket) return;
bucket = document.createElement(type);
if (button.hasAttribute("data-text")) bucket.appendChild(new Text(button.getAttribute("data-text")));
parent.appendChild(bucket);
});
var childButton = document.querySelector("[data-child='" + type + "']");
if (!childButton) return;
childButton.addEventListener("click", function(event) {
event.preventDefault();
if (!bucket) return;
var child = document.createElement(type);
if (childButton.hasAttribute("data-text")) child.appendChild(new Text(childButton.getAttribute("data-text")));
bucket.appendChild(child);
});
});
<input type="button" value="div" data-bucket="div" data-text="helloDIV" />
<input type="button" value="divInside" data-child="div" data-text="helloInsideDIV" />
<input type="button" value="p" data-bucket="p" data-text="helloP" />
<input type="button" value="pInside" data-child="p" data-text="helloInsideP" />
<div id='main'></div>
first of all I want to apologize for bad explenation. After some time i figured out what exactly I have to do, if someone is interested I will leave a code:
const main = document.getElementById('main');
let layer1 = null;
let layer2 = null;
let layer3 = null;
let layer4 = null;
class Bucket{
constructor(name, text){
this.name = name;
this.text = text;
}
Layer1(){
layer1 = document.createElement(this.name);
layer1.innerHTML = this.text;
main.appendChild(layer1)
}
Layer2(){
layer2 = document.createElement(this.name);
layer2.innerHTML = this.text;
layer1.appendChild(layer2);
}
Layer3(){
layer3 = document.createElement(this.name);
layer3.innerHTML = this.text;
layer2.appendChild(layer3);
}
Layer4(){
layer4 = document.createElement(this.name);
layer4.innerHTML = this.text;
layer3.appendChild(layer4);
}
}
const L1_D = new Bucket('div', 'div');
const L1_P = new Bucket('p', 'paragraph');
const L1_S = new Bucket('span', 'span');
const L1_H = new Bucket('h5', 'h5');
const L2_D = Object.create(L1_D);
const L2_P = Object.create(L1_P);
const L2_S = Object.create(L1_S);
const L2_H = Object.create(L1_H);
const L3_D = Object.create(L2_D);
const L3_P = Object.create(L2_D);
const L3_S = Object.create(L2_D);
const L3_H = Object.create(L2_D);
const L4_D = Object.create(L3_D);
const L4_P = Object.create(L3_D);
const L4_S = Object.create(L3_D);
const L4_H = Object.create(L3_D);
<input type='button' value='1 Layer' onclick='L1_D.Layer1(); this.onclick=null;'>
<input type='button' value='2 Layer' onclick='L2_D.Layer2(); this.onclick=null;'>
<input type='button' value='3 Layer' onclick='L3_D.Layer3(); this.onclick=null;'>
<input type='button' value='4 Layer' onclick='L4_D.Layer4(); this.onclick=null;'>
<input type="button" value="Reload Page" onClick="document.location.reload(true)">
<div id='main'></div>

Moving items to different lists with DOM Manipulation JS

I'm creating something like GMAIL functionality with JavaScript ES5 ( I use only const and let, that's it, rest ES5).
So I manage to create the list functionality, all works except that when I select the items and move them to a different list, they lose any functionality, and I can't do anything with them.
I believe I need to use querySelectorAll to get all the lists, but that doesn't work. Not sure what should I do here.
I think I need to select all the lists, and then loop them to add interactivity.
CodePen: https://codepen.io/Aurelian/pen/dJryrX?editors=1010
JS:
window.onload = function() {
//////////////////////////////////
// VARIABLES
//////////////////////////////////
// Form
const form = document.querySelector('#registrar');
const input = form.querySelector('input');
// Lists
const partyList = document.querySelector('.party-lists');
const partyInvitedList = document.querySelector('#list-invited')
const partyGoingList = document.querySelector('#list-going');
const partyNotSure = document.querySelector('#list-not-sure');
const partyNotGoing = document.querySelector('#list-not-going');
// List Options
const listOptions = document.querySelector('.list-options');
const btnMoveToGoing = document.querySelector('.btnMoveGoing');
const btnMoveToNotSure = document.querySelector('.btnMoveNotSure');
const btnMoveToNotGoing = document.querySelector('.btnMoveNotGoing');
const btnDeleteSelected = document.querySelector('.btnDeleteSelected');
//////////////////////////////////
// FUNCTIONS
//////////////////////////////////
function createLI(text) {
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = text;
li.appendChild(span);
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
label.appendChild(checkbox);
li.appendChild(label);
const editButton = document.createElement('button');
editButton.textContent = 'edit';
li.appendChild(editButton);
const removeButton = document.createElement('button');
removeButton.textContent = 'remove';
li.appendChild(removeButton);
return li;
}
//////////////////////////////////
// EVENT HANDLERS
//////////////////////////////////
form.addEventListener('submit', function(e) {
e.preventDefault();
const text = input.value;
input.value = '';
const li = createLI(text);
partyInvitedList.appendChild(li);
});
partyList.addEventListener('click', function(e) {
if (e.target.tagName === 'BUTTON') {
const button = e.target;
const li = button.parentNode;
const ul = li.parentNode;
if (button.textContent === 'remove') {
ul.removeChild(li);
} else if (button.textContent === 'edit') {
const span = li.firstElementChild;
const input = document.createElement('input');
input.type = 'text';
input.value = span.textContent;
li.insertBefore(input, span);
li.removeChild(span);
button.textContent = 'save';
} else if (button.textContent === 'save') {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'edit';
}
}
});
listOptions.addEventListener('click', function(e) {
partyList.querySelectorAll('*:checked').forEach(function (listItems) {
const button = e.target;
var items = listItems.parentNode.parentNode;
if(button.className === 'btnMoveGoing') {
partyGoingList.appendChild(items);
items.checked = false;
var item = listItems;
item.checked = false;
} else if(button.className === 'btnMoveNotSure'){
partyNotSure.appendChild(items);
var item = listItems;
item.checked = false;
} else if(button.className === 'btnMoveNotGoing'){
partyNotGoing.appendChild(items);
var item = listItems;
item.checked = false;
} else if(button.className === 'btnDeleteSelected'){
listItems.parentNode.parentNode.remove();
var item = listItems;
item.checked = false;
}
});
});
}
HTML:
<div class="top">
<form id="registrar">
<input type="text" name="name" placeholder="Invite Someone">
<button type="submit" name="submit" value="submit">Submit</button>
</form>
<div class="list-options">
<button class="btnMoveGoing">Move to Going</button>
<button class="btnMoveNotSure">Move to Not Sure</button>
<button class="btnMoveNotGoing">Move to Not Going</button>
<button class="btnDeleteSelected">Delete Selected</button>
</div>
</div><!-- /top -->
<div class="col">
<h3>Invited</h3>
<ul id="list-invited" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Going</h3>
<ul id="list-going" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Not Sure</h3>
<ul id="list-not-sure" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Not Going</h3>
<ul id="list-not-going" class="party-lists">
</ul>
</div>

Categories

Resources