create a Edit Button while manipulating DOM in javascript - javascript

I am creating a simple TODO APP, which adds and deletes and edits a task when it's added, I am trying to figure out how to do edit a task. should I create a new P tag and equal it to par.value?
h1.innerText = 'TODO LIST';
document.body.appendChild(h1);
const input = document.createElement('input');
document.body.appendChild(input);
const addBtn = document.createElement('button');
addBtn.innerText = 'Add';
document.body.appendChild(addBtn);
const container = document.createElement('div');
container.innerText = 'Output';
document.body.appendChild(container);
addBtn.addEventListener('click', function(){
const par = document.createElement('p');
par.innerText = input.value;
container.appendChild(par);
const deleteBtn =document.createElement('button');
deleteBtn.innerText = 'Delete';
par.appendChild(deleteBtn);
const editBtn = document.createElement('button');
editBtn.innerText = 'Edit';
par.appendChild(editBtn);
deleteBtn.addEventListener('click', function(){
this.parentElement.remove();
editBtn.addEventListener('click', function(){
})
})
})

There are many ways how you can do this. One way is to use the attribute contenteditable for your paragraph. See this example:
const h1 = document.createElement('h1');
h1.innerText = 'TODO LIST';
document.body.appendChild(h1);
const input = document.createElement('input');
document.body.appendChild(input);
const addBtn = document.createElement('button');
addBtn.innerText = 'Add';
document.body.appendChild(addBtn);
const container = document.createElement('div');
container.innerText = 'Output';
document.body.appendChild(container);
addBtn.addEventListener('click', function() {
const par = document.createElement('p');
par.innerText = input.value;
container.appendChild(par);
const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
container.appendChild(deleteBtn);
const editBtn = document.createElement('button');
editBtn.classList.add('edit');
editBtn.innerText = 'Edit';
container.appendChild(editBtn);
deleteBtn.addEventListener('click', function() {
this.parentElement.remove();
editBtn.addEventListener('click', function() {
})
})
})
// Since the selector ".edit" is dynamic, listen to all elements
document.querySelector('*').addEventListener('click', (e) => {
// Return, if the element has not the class "edit"
if (e.target.className !== 'edit') return
// Set attribute to the paragraph
e.target.previousSibling.previousSibling.setAttribute('contenteditable', 'true');
// focus the paragraph
e.target.previousSibling.previousSibling.focus();
});

Related

How do you get the user data from a HTML input (text) created using createElement()?

My Problem
I would like some help understanding how to access the value inside input1 and input2, store them in a variable so I can later use them with a function that will calculate the two values and display it in the result div.
const input1 = document.createElement("input");
document.body.appendChild(input1);
const input2 = document.createElement("input");
document.body.appendChild(input2);
const result = document.createElement("div");
document.body.appendChild(result);
an idea can be to use EventListener on the created input to manipulate the data
const input1 = document.createElement("INPUT");
document.body.appendChild(input1);
input1.addEventListener('change', function (e) {
var target = e.target || e.srcElement;
console.log(target.value);
});
you can also add a selector (id or class) to the created element and recover it by this selector
const input1 = document.createElement("INPUT");
document.body.appendChild(input1);
input1.id = 'test';
function showData() {
var input = document.getElementById('test');
console.log(input.value);
}
<button onclick="showData()">show data</button>
with your sample it can look like
const input1 = document.createElement("INPUT");
input1.id = 'input1';
document.body.appendChild(input1);
const input2 = document.createElement("INPUT");
input2.id = 'input2';
document.body.appendChild(input2);
const result = document.createElement("DIV");
result.id = 'result';
document.body.appendChild(result);
function showResult() {
var input1 = document.getElementById('input1');
var input2 = document.getElementById('input2');
var result = document.getElementById('result');
if (input1 && input2 && result) {
result.innerText = input1.value * input2.value;
}
}
<button onclick="showResult()">show result</button>
if you have to dynamically create div and showresult you can also create the button and manipulate the onclick event
var numberOfRow = 0;
function copyResultInNextInput(nextNumber, result) {
var next = document.getElementById('input1_' + (nextNumber));
if (next) {
next.value = result.innerText;
}
}
function createNewRow(haveSeveralButtons) {
numberOfRow++;
const nextNumber = numberOfRow + 1;
const input1 = document.createElement("INPUT");
input1.id = 'input1_' + numberOfRow;
document.body.appendChild(input1);
const input2 = document.createElement("INPUT");
input2.id = 'input2_' + numberOfRow;
document.body.appendChild(input2);
const result = document.createElement("DIV");
result.id = 'result_' + numberOfRow;
document.body.appendChild(result);
const button = document.createElement("BUTTON");
button.innerText = 'show result';
button.addEventListener('click', function() {
result.innerText = input1.value * input2.value;
if (!haveSeveralButtons) {
copyResultInNextInput(nextNumber, result);
}
});
document.body.appendChild(button);
if (haveSeveralButtons) {
const button2 = document.createElement("BUTTON");
button2.innerText = 'copy result in next input1';
button2.addEventListener('click', function() {
copyResultInNextInput(nextNumber, result);
});
document.body.appendChild(button2);
}
const hr = document.createElement("HR");
document.body.appendChild(hr);
}
<button onclick="createNewRow(false)">create New Row with one button</button>
<button onclick="createNewRow(true)">create New Row with two buttons</button>
<hr/>
OK, so the Id work, but it only works for that one row. I need to repeat that process (equation) independanly on each new row that's created.

How to create a dynamic list, which removes deleted items from an array in JS?

I have created a list, which creates a new paragraph, with the value of the input field and adds the value of the input field into an array, if the add-Button is pressed. Each paragraph has a delete Button, which removes the paragraph visually, if pressed. Now I want that the Input of the paragraph also gets removed from the array.
For example lets say, that the array usernames includes usernames[1] = Lukas, usernames[2] = Martin, usernames[3] = Bob and I want to delete the paragraph, which includes Martin.
How can I create a function, where the paragraphs content also automatically gets removed from the array usernames. I would be very thankful for some help.
Here is my code:
let name = document.getElementById('name');
let addButton = document.getElementById('button');
let output = document.getElementById('output')
let usernames = [];
addButton.addEventListener('click', function() {
usernames.push(document.getElementById('name').value)
console.log(usernames)
let paragraph = document.createElement('ul')
paragraph.innerText = document.getElementById('name').value
output.appendChild(paragraph)
let deleteButton = document.createElement('button')
deleteButton.innerHTML = "X"
paragraph.appendChild(deleteButton)
deleteButton.addEventListener('click', function() {
output.removeChild(paragraph)
})
})
You can find an element in the array by name and remove it from there:
const usernameToRemove = usernames.indexOf(name => name === paragraph.innerText);
usernames.splice(usernameToRemove, 1);
let name = document.getElementById('name');
let addButton = document.getElementById('button');
let output = document.getElementById('output')
let usernames = [];
addButton.addEventListener('click', function() {
usernames.push(document.getElementById('name').value)
console.log(usernames)
let paragraph = document.createElement('ul')
paragraph.innerText = document.getElementById('name').value
output.appendChild(paragraph)
let deleteButton = document.createElement('button')
deleteButton.innerHTML = "X"
paragraph.appendChild(deleteButton)
deleteButton.addEventListener('click', function() {
const usernameToRemove = usernames.indexOf(name => name === paragraph.innerText);
usernames.splice(usernameToRemove, 1);
output.removeChild(paragraph)
})
})
<input id="name">
<button id="button">button</button>
<div id="output">output</div>
Every time the event handler to delete an item is called, just collect all of the text of each item and convert it into an array.
del.addEventListener('click', function() {
this.closest('li').remove();
usernames = [...list.querySelectorAll('li')].map(item => item.textContent);
console.log(usernames);
});
/*
This removes an <li>, if you don't change your "paragraph" then
change 'li' to 'ul'
*/
const user = document.getElementById('user');
const add = document.querySelector('.add');
const list = document.querySelector('.list')
let usernames = [];
add.addEventListener('click', function() {
let name = user.value;
user.value = '';
usernames.push(name);
console.log(usernames);
const item = document.createElement('li');
item.textContent = name+' ';
list.append(item);
const del = document.createElement('button');
del.textContent = "X";
item.append(del);
del.addEventListener('click', function() {
this.closest('li').remove();
usernames = [...list.querySelectorAll('li')].map(item => item.textContent);
console.log(usernames);
});
});
<input id='user'><button class='add'>ADD</button>
<ul class='list'></ul>
Thank you for your answers, but unfortunately the inner Text of the delete Button gets added to the array content, if something gets deleted, because it is part of the 'li' component. I simply created a div which includes the name and the delete Button to solve the problem. But nevertheless thank you for your help. Thats the working code:
const user = document.getElementById('user');
const add = document.querySelector('.add');
const list = document.querySelector('.list')
let usernames = [];
add.addEventListener('click', function() {
let name = user.value;
user.value = '';
usernames.push(name);
console.log(usernames);
const paragraph = document.createElement('div')
paragraph.style.display = 'flex'
const item = document.createElement('li');
item.textContent = name + ' ';
list.append(paragraph);
paragraph.append(item)
const del = document.createElement('button');
del.textContent = "X";
paragraph.append(del);
del.addEventListener('click', function() {
this.closest('div').remove();
usernames = [...list.querySelectorAll('li')].map(item => item.textContent);
console.log(usernames);
});
});

How do I add a checkbox on the same line as my paragraph?

I am trying to add a check box on the same line as my paragraph in my to do list.
I have tried:
let addToDoButtton = document.getElementById('addToDo');
let toDoContainer = document.getElementById('toDoContainer');
let inputField = document.getElementById('inputField');
addToDoButtton.addEventListener('click', function(){
var paragraph = document.createElement('p');
var checkbox = document.createElement('input');
checkbox.type='checkbox';
paragraph.classList.add('paragraph-styling');
paragraph.innerText = inputField.value;
toDoContainer.appendChild(checkbox);
toDoContainer.appendChild(paragraph);
inputField.value=""
paragraph.addEventListener('click', function () {
paragraph.style.textDecoration="line-through";
paragraph.style.color='#5493f7';
})
paragraph.addEventListener('dblclick', function(){
toDoContainer.removeChild(paragraph);
toDoContainer.removeChild(paragraph)
})
I have also tried:
toDoContainer.appendChild(checkbox) &&
toDoContainer.appendChild(paragraph);
I got this for the output:
Please take a look here
const input = document.createElement('input');
input.id = 'input';
input.type = 'checkbox';
const label = document.createElement('label');
label.htmlFor = 'input';
toDoContainer.append(input, label);

How to add a repeated element based on button click using javascript?

How to add a repeated element using a button click example code is given bellow I am not able to set proper event that can add multiple div element based on click.
const Form = document.createElement('form)
const Input = document.createElement('input')
const Button = document.createElement('button')
const NewDiv = document.createElement('div').className = "repeatedBlock"
NewDiv.append(Input)
NewDiv.append(Button)
Form.append(NewDiv)
Button.onclick = function changeContent() {
// append multiple NewDiv in the Form element based on every click
}
In this code, I have created a form, then call a function which creates div and bind event inside it. Let me know if required more details on this.
Change name, provide id to each field. These are up to you.
const Form = document.createElement('form');
Form.id = "form";
document.body.appendChild(Form);
const Button = document.createElement('button') ;
Button.textContent ="Click";
Button.addEventListener("click", function(e){ e.preventDefault(); createDiv() });
Form.appendChild(Button);
createDiv();
function createDiv() {
var i = document.getElementById('form');
const NewDiv = document.createElement('div');
const Input = document.createElement('input') ;
NewDiv.append(Input);
i.appendChild(NewDiv);
}
Only a single Button
const Form = document.createElement('form');
const Button = document.createElement('button')
document.body.appendChild(Form);
Button.innerHTML = "Go";
Button.classList.add("formBtn");
window.onload = generateNew;
Form.appendChild(Button)
var x = 0;
function generateNew(e){
x++;
e.preventDefault();
const Input = document.createElement('input')
const NewDiv = document.createElement('div')
NewDiv.classList.add( "repeatedBlock" );
Input.value = "Input #"+x;
NewDiv.append(Input);
Form.append(NewDiv);
setEvents();
}
function setEvents(){
var Buttons = document.querySelectorAll(".formBtn");
for(i = 0; i < Buttons.length; i++){
Buttons[i].addEventListener("click", generateNew);
}
}

cancel btn for a contenteditable html option

I'm really new to the contenteditable variable for html and so I want to dig your brains a bit :).
I want to allow users to edit content if they wish to but I'm stuck in the cancel btn option.
How can I retain the previous content if a user clicks the cancel btn? I've been looking at the documentation but struggle to find something. Please see the code below:
const cancelBtn = document.getElementById('cancel-btn');
console.log(editBtn);
function editable() {
const h3 = document.querySelector('h3');
const h4 = document.querySelector('h4');
const p = document.querySelector('p');
h3.className = 'edit';
h4.className = 'edit';
p.className = 'edit';
h3.contentEditable = true;
h4.contentEditable = true;
p.contentEditable = true;
addSaveBtn();
}
function cancelEdit() {
const h3 = document.querySelector('h3');
const h4 = document.querySelector('h4');
const p = document.querySelector('p');
h3.classList.remove('edit');
h4.classList.remove('edit');
p.classList.remove('edit');
h3.contentEditable = false;
h4.contentEditable = false;
p.contentEditable = false;
removeSaveBtn();
}
function addSaveBtn() {
const cardAccess = document.querySelector('.card');
const saveBtn = document.createElement('button');
saveBtn.id = 'edit-save-btn';
saveBtn.textContent = 'Save';
if (document.getElementById('edit-save-btn')) {
return;
} else {
cardAccess.insertAdjacentElement('beforeend', saveBtn);
}
saveBtn.addEventListener('click', () => {
const h3 = document.querySelector('h3');
const h4 = document.querySelector('h4');
const p = document.querySelector('p');
h3.classList.remove('edit');
h4.classList.remove('edit');
p.classList.remove('edit');
h3.contentEditable = false;
h4.contentEditable = false;
p.contentEditable = false;
removeSaveBtn();
});
}
function removeSaveBtn() {
if (!document.getElementById('edit-save-btn')) {
return;
} else {
document.getElementById('edit-save-btn').remove();
}
}
editBtn.addEventListener('click', editable);
cancelBtn.addEventListener('click', cancelEdit);```
Edit:
To add a cancel button:
Create a variable that stores the innerHTML when save was pressed.
Set the innerHTML of the contenteditable element to this variable when the cancel button is pressed.
Full Example:
// Set up the variable
var savedText = content.innerHTML;
save.onclick = ()=>{
// store the current content in savedText
savedText = content.innerHTML;
}
cancel.onclick = ()=>{
// set the new html content to what was stored
content.innerHTML = savedText;
}
<div id="content" contenteditable="true"><h1>Edit Me!</h1></div>
<button id="save">Save</button>
<button id="cancel">Cancel</button>
The contentEditable property takes a string, so you probably want something like this:
function cancelEdit() {
const h3 = document.querySelector('h3');
const h4 = document.querySelector('h4');
const p = document.querySelector('p');
h3.classList.remove('edit');
h4.classList.remove('edit');
p.classList.remove('edit');
h3.contentEditable = "false";
h4.contentEditable = "false";
p.contentEditable = "false";
removeSaveBtn();
}
function editable() {
const h3 = document.querySelector('h3');
const h4 = document.querySelector('h4');
const p = document.querySelector('p');
h3.className = 'edit';
h4.className = 'edit';
p.className = 'edit';
h3.contentEditable = "true";
h4.contentEditable = "true";
p.contentEditable = "true";
addSaveBtn();
}
Example with toggling:
toggle.onclick = ()=>{
content.contentEditable = (!content.isContentEditable).toString();
toggle.textContent = content.isContentEditable ? "Turn Editability Off" : "Turn editability On"
}
<div id="content" contenteditable="true"><h1>Edit Me!</h1></div>
<button id="toggle">Turn Editability Off</button>

Categories

Resources