{
document.addEventListener('DOMContentLoaded', () => {
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
const radioWork = document.getElementById('radio-work');
const radioDone = document.getElementById('radio-done');
let nextId = 0;
const todos = [];
//Taskとidを作成
const addTask = (task, id, tableItem) => {
const idSpanTd = document.createElement('td');
const taskSpanTd = document.createElement('td');
//タスク追加時にtodosにtodoを追加
const todo = {
task: 'taskSpanTd',
status: '作業中'
};
todos.push(todo);
//要素内のHTML文章を変更する
idSpanTd.innerText = id;
taskSpanTd.innerText = task;
//生成したテーブル要素をブラウザに表示する
tableItem.append(idSpanTd);
tableItem.append(taskSpanTd);
addTaskTarget.append(tableItem);
};
//Button要素を生成する
const addButton = (tableItem, removeButton, createButton) => {
const createButtonTd = document.createElement('td');
const removeButtonTd = document.createElement('td');
//要素内のHTML文章を変更する
createButton.innerText = '作業中';
removeButton.innerText = '削除';
//生成したテーブル要素をブラウザに表示する
tableItem.append(createButtonTd);
tableItem.append(removeButtonTd);
addTaskTarget.append(tableItem);
//生成したbutton要素を生成する
createButtonTd.append(createButton);
removeButtonTd.append(removeButton);
};
//Perform processing to add td element when clicking the add button
addTaskTrigger.addEventListener('click', () => {
const task = addTaskValue.value;
const tableItem = document.createElement('tr');
const removeButton = document.createElement('button');
const createButton = document.createElement('button');
addTask(task, nextId++, tableItem);
addButton(tableItem, removeButton, createButton);
addTaskValue.value = '';
// //削除ボタンを押した時にタスクを削除する
const deleteElement = (a) => {
const tableTag = a.target.closest('tr');
if (tableTag) tableTag.remove();
updateId();
}
removeButton.addEventListener('click', deleteElement, false);
//When you press the button, it changes from working to completion
createButton.addEventListener('click', (a) => {
if (createButton.textContent === "作業中") {
createButton.textContent = "完了";
const doneParent = a.target.parentNode;
doneParent.className = 'workDone';/*完了class*/
} else {
createButton.textContent = "作業中";
const workParent = a.target.parentNode;
workParent.className = 'work';/*作業中class*/
}
});
})
/*Processing when pressing the radio button in progress*/
radioDone.addEventListener('click', function () {
let workTasks = document.getElementsByClassName('work');
workTasks = Array.from(workTasks);
if (radioWork.checked === true) {
workTasks.forEach(function (workTasks) {
workTasks.style.display = "none";
})
} else {
workTasks.forEach(function (workTasks) {
workTasks.style.display = "none";
})
}
})
//Processing when radio button complete is pressed
radioWork.addEventListener('click', function () {
let doneTasks = document.getElementsByClassName('workDone');
doneTasks = Array.from(doneTasks);
if (radioDone.checked === true) {
doneTasks.forEach(function (doneTasks) {
doneTasks.style.display = "none";
})
} else {
doneTasks.forEach(function (doneTasks) {
doneTasks.style.display = "none";
})
}
})
// Serial number reassignment
const updateId = () => {
const tbody = document.getElementsByTagName("tbody")[0];
const taskList = tbody.getElementsByTagName('tr');
nextId = 0;
Array.from(taskList, tr => {
tr.getElementsByTagName('td')[0].textContent = nextId;
nextId++
});
}
});
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="task" value="1" checked ="checked">全て
<input type="radio" id="radio-work" name="task" value="2">作業中
<input type="radio" id="radio-done" name="task" value="3">完了
</p>
<p></p>
<table>
<thead>
<th>ID</th>
<th>コメント</th>
<th>状態</th>
<th></th>
</thead>
<tbody class="addTask-target" id="tbody"></tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</html>
I am creating a Todo list and trying to implement it with the following contents.
https://gyazo.com/0b47106078622a1e44e912f56b5e9603
-Show/hide depending on task status
-Toggle task display depending on radio button selected
-If you add a new task when "Working" is selected, the task will be displayed
-If you add a new task when "Complete" is selected, the task will not be displayed (but it is added correctly in the background)
■ Current problems
(1) If you press the task completion button and then put the check box into operation, "Only the completion button" will be hidden.
→I want to hide every td
(2) Even if you click the in-process button and then click the completion check box, it will not be hidden
■ Tried
if (createButton.textContent === "Working") {
createButton.textContent = "Done";
const doneParent = a.target.parentNode;
doneParent.className ='workDone'; /* Done class */
Here is this.parentNode;
I changed it to
If you have any other problems, please let me know.
Thank you for your guidance.
Related
I'm currently making a Library project, and I made it so that each book entered is stored in an array (in this case, the array is myLibrary). Then I made it so that each book in the array creates a new div with the class of "card." I've implemented a "Remove Button" for each card, but I'm not sure as to how I can make the button delete the book from the array. Any help would be appreciated, thank you.
I've tried
const remBtn = document.createElement("button");
card.appendChild(remBtn);
remBtn.textContent = "Remove";
remBtn.onclick = remBook;
// Remove book function
function remBook() {
const findBook = myLibrary.findIndex((element) => element === book);
const delBook = myLibrary.slice(findBook, 1);
}
Here are my codes:
html:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Library</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="header">Library</div>
<form id="submitInput" action="">
<label for="title">Title:</label>
<input type="text" id="formTitle" name="title" required />
<label for="author">Author:</label>
<input type="text" id="formAuthor" name="author" required />
<label for="page">Page:</label>
<input type="text" id="formPage" name="page" required />
<div class="read">
<label for="read">Read</label>
<input type="checkbox" id="formRead" name="read" value="" />
</div>
<input type="submit" id="submitBtn" value="Add Book" />
</form>
<div class="currentDisplay"></div>
</body>
<script src="./script.js"></script>
</html>
JS:
// Data inputs
let myLibrary = [
{
title: "test",
author: "test",
page: "123",
read: true,
},
];
// Object constructor
function book(title, author, page, read) {
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
// Add new books to library
function addBookToLibrary() {
let a = document.getElementById("formTitle").value;
let b = document.getElementById("formAuthor").value;
let c = document.getElementById("formPage").value;
let d = document.getElementById("formRead").checked;
if (a !== "" && b !== "" && c !== "") {
myLibrary.push(new book(a, b, c, d));
}
}
const submit = document.getElementById("submitInput");
submit.addEventListener("submit", () => {
event.preventDefault();
addBookToLibrary();
submit.reset();
displayBooks();
});
// Display each book as cards
function displayBooks() {
const currentDisplay = document.querySelector(".currentDisplay");
currentDisplay.textContent = "";
myLibrary.forEach((myLibrary) => {
let card = document.createElement("div");
card.classList.add("card");
currentDisplay.appendChild(card);
for (let key in myLibrary) {
const text = document.createElement("p");
text.textContent = `${key}: ${myLibrary[key]}`;
card.appendChild(text);
}
const readBtn = document.createElement("button");
card.appendChild(readBtn);
if (myLibrary.read === true) {
readBtn.textContent = "Read";
}
if (myLibrary.read === false) {
readBtn.textContent = "Not Read";
}
readBtn.addEventListener("click", () => {
if (readBtn.textContent === "Read") {
readBtn.textContent = "Not Read";
myLibrary.read = false;
} else if (readBtn.textContent === "Not Read") {
readBtn.textContent = "Read";
myLibrary.read = true;
}
});
const remBtn = document.createElement("button");
card.appendChild(remBtn);
remBtn.textContent = "Remove";
remBtn.onclick = remBook;
});
}
// Remove book function
function remBook() {
const findBook = myLibrary.findIndex((element) => element === book);
const delBook = myLibrary.slice(findBook, 1);
}
displayBooks();
First let's give each Book object a unique property.
// Object constructor
function Book(title, author, page, read) {
this.bookId = `book${++Book.id}`;
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
//static property
Book.id = 0;
While rendering a book we use the bookId property as class name for the div. This will be used for deleting the element.
card.classList.add(`${myLibrary.bookId}`);
Inside remove book function, we find the book using bookId property. we use the splice method to remove an element from array. Then we call the remove method on div element to delete the div.
// Remove book function
function remBook() {
const bookId = this.parentElement.classList[1];
const findBook = myLibrary.findIndex(
(element) => element.bookId === bookId
);
const delBook = myLibrary.splice(findBook, 1);
this.parentElement.remove();
}
// Data inputs
let myLibrary = [{
title: 'test',
author: 'test',
page: '123',
read: true,
}, ];
// Object constructor
function Book(title, author, page, read) {
this.bookId = `book${++Book.id}`;
this.title = title;
this.author = author;
this.page = page;
this.read = read;
}
//static property
Book.id = 0;
// Add new books to library
function addBookToLibrary() {
let a = document.getElementById('formTitle').value;
let b = document.getElementById('formAuthor').value;
let c = document.getElementById('formPage').value;
let d = document.getElementById('formRead').checked;
if (a !== '' && b !== '' && c !== '') {
myLibrary.push(new Book(a, b, c, d));
}
}
const submit = document.getElementById('submitInput');
submit.addEventListener('submit', () => {
event.preventDefault();
addBookToLibrary();
submit.reset();
displayBooks();
});
// Display each book as cards
function displayBooks() {
const currentDisplay = document.querySelector('.currentDisplay');
currentDisplay.textContent = '';
myLibrary.forEach((myLibrary) => {
let card = document.createElement('div');
card.classList.add('card');
card.classList.add(`${myLibrary.bookId}`);
currentDisplay.appendChild(card);
for (let key in myLibrary) {
const text = document.createElement('p');
text.textContent = `${key}: ${myLibrary[key]}`;
card.appendChild(text);
}
const readBtn = document.createElement('button');
card.appendChild(readBtn);
if (myLibrary.read === true) {
readBtn.textContent = 'Read';
}
if (myLibrary.read === false) {
readBtn.textContent = 'Not Read';
}
readBtn.addEventListener('click', () => {
if (readBtn.textContent === 'Read') {
readBtn.textContent = 'Not Read';
myLibrary.read = false;
} else if (readBtn.textContent === 'Not Read') {
readBtn.textContent = 'Read';
myLibrary.read = true;
}
});
const remBtn = document.createElement('button');
card.appendChild(remBtn);
remBtn.textContent = 'Remove';
remBtn.onclick = remBook;
});
}
// Remove book function
function remBook() {
const bookId = this.parentElement.classList[1];
const findBook = myLibrary.findIndex(
(element) => element.bookId === bookId
);
const delBook = myLibrary.splice(findBook, 1);
this.parentElement.remove();
}
displayBooks();
<div class="header">Library</div>
<form id="submitInput" action="">
<label for="title">Title:</label>
<input type="text" id="formTitle" name="title" required />
<label for="author">Author:</label>
<input type="text" id="formAuthor" name="author" required />
<label for="page">Page:</label>
<input type="text" id="formPage" name="page" required />
<div class="read">
<label for="read">Read</label>
<input type="checkbox" id="formRead" name="read" value="" />
</div>
<input type="submit" id="submitBtn" value="Add Book" />
</form>
<div class="currentDisplay"></div>
I think you can add specific ids whenever you add a new card. And call the card classes using querySelectorAll. That will return you a nodelist. Loop that nodelist and check if the specific id that you are click right now match with the looped element's id. If true, you can do your stuffs in that loop cuz whatever you're doing will only apply to the button that you're clicking.
I made a sample here. By the way, I used JSON to check the condition in string state.
function remBook(obj) {
let card = document.querySelectorAll(".card");
for(let x=0; x<card.length; x++) {
if(JSON.stringfy(card[y].id) === JSON.stringfy(obj.id) {
/* You can do your stuff here using index */
}
}
}
https://jsfiddle.net/xw26rbvc/
There is a quest I've been trying to solve for quite a time.
In my code, I have a "To-Do List".
And there, I want to make the buttons ("doneButton", "deleteButton") workable with "addEventListener".
Somehow, the buttons don't work as expected.
When I run this within the code console.log(todoItem.doneButton), it shows the correct button.
But just the line below, where I try to "addEventListener" to the same very element, it doesn't work at all.
(function() {
function createAppTitle(title) {
let appTitle = document.createElement('h2');
appTitle.textContent = title;
appTitle.classList.add('mt-5', 'mb-3');
return appTitle;
}
function createToDoList() {
let list = document.createElement('ul')
return list;
}
function createToDoForm() {
let buttonWrapper = document.createElement('div')
let form = document.createElement('form')
let input = document.createElement('input')
let button = document.createElement('button')
form.classList.add('input-group', 'mb-3');
input.classList.add('form-control');
input.placeholder = 'Enter the name of the task';
buttonWrapper.classList.add('input-group-append');
button.classList.add('btn', 'btn-primary');
button.textContent = 'Add a task';
buttonWrapper.append(button);
form.append(input);
form.append(buttonWrapper);
return {
form,
input,
button
};
}
function createToDoItem (name) {
let item = document.createElement('li')
let buttonGroup = document.createElement('div')
let doneButton = document.createElement('button')
let deleteButton = document.createElement('button')
item.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
item.textContent = name;
buttonGroup.classList.add('btn-group','btn-group-sm');
doneButton.classList.add('btn','btn-success');
doneButton.textContent = "Done";
deleteButton.classList.add('btn','btn-danger');
deleteButton.textContent = 'Delete';
buttonGroup.append(doneButton);
buttonGroup.append(deleteButton);
item.append(buttonGroup);
return {
item,
doneButton,
deleteButton
}
}
document.addEventListener('DOMContentLoaded', function () {
let container = document.querySelector('.container');
let appTitle = createAppTitle('Name of the Target');
let list = createToDoList();
let form = createToDoForm();
let todoItems = [createToDoItem('Book your trip'), createToDoItem('Fly to Dubai'), createToDoItem('Book' +
' your trip')];
container.append(appTitle);
container.append(form.form);
container.append(list);
list.append(todoItems[0].item)
list.append(todoItems[1].item)
list.append(todoItems[2].item)
form.form.addEventListener('submit', (e)=> {
e.preventDefault();
if (!form.input.value) {
return;
}
let todoItem = createToDoItem(form.input.value);
console.log(todoItem.doneButton)
todoItem.doneButton.addEventListener('click', function () {
console.log('done button clicked');
});
todoItem.deleteButton.addEventListener('click', ()=> {
console.log('delete button clicked');
})
list.append(createToDoItem(form.input.value).item)
form.input.value = '';
});
})
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ToDo</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous">
<script src="index.js" defer></script>
</head>
<body>
<div id="toDo" class="container"></div>
</body>
</html>
You should attach the event inside the createToDoItem()
(function() {
function createAppTitle(title) {
let appTitle = document.createElement('h2');
appTitle.textContent = title;
appTitle.classList.add('mt-5', 'mb-3');
return appTitle;
}
function createToDoList() {
let list = document.createElement('ul')
return list;
}
function createToDoForm() {
let buttonWrapper = document.createElement('div')
let form = document.createElement('form')
let input = document.createElement('input')
let button = document.createElement('button')
form.classList.add('input-group', 'mb-3');
input.classList.add('form-control');
input.placeholder = 'Enter the name of the task';
buttonWrapper.classList.add('input-group-append');
button.classList.add('btn', 'btn-primary');
button.textContent = 'Add a task';
buttonWrapper.append(button);
form.append(input);
form.append(buttonWrapper);
return {
form,
input,
button
};
}
function createToDoItem (name) {
let item = document.createElement('li')
let buttonGroup = document.createElement('div')
let doneButton = document.createElement('button')
let deleteButton = document.createElement('button')
item.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
item.textContent = name;
buttonGroup.classList.add('btn-group','btn-group-sm');
doneButton.classList.add('btn','btn-success');
doneButton.textContent = "Done";
deleteButton.classList.add('btn','btn-danger');
deleteButton.textContent = 'Delete';
buttonGroup.append(doneButton);
buttonGroup.append(deleteButton);
item.append(buttonGroup);
doneButton.addEventListener('click', function () {
console.log('done button clicked');
});
deleteButton.addEventListener('click', ()=> {
console.log('delete button clicked');
})
return {
item,
doneButton,
deleteButton
}
}
document.addEventListener('DOMContentLoaded', function () {
let container = document.querySelector('.container');
let appTitle = createAppTitle('Name of the Target');
let list = createToDoList();
let form = createToDoForm();
let todoItems = [createToDoItem('Book your trip'), createToDoItem('Fly to Dubai'), createToDoItem('Book' +
' your trip')];
container.append(appTitle);
container.append(form.form);
container.append(list);
list.append(todoItems[0].item)
list.append(todoItems[1].item)
list.append(todoItems[2].item)
form.form.addEventListener('submit', (e)=> {
e.preventDefault();
if (!form.input.value) {
return;
}
let todoItem = createToDoItem(form.input.value);
console.log(todoItem.doneButton)
list.append(createToDoItem(form.input.value).item)
form.input.value = '';
});
})
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ToDo</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
crossorigin="anonymous">
<script src="index.js" defer></script>
</head>
<body>
<div id="toDo" class="container"></div>
</body>
</html>
Excuse the question.
I want to make a todo list like this.
https://gyazo.com/0dd4feeea3f7a27aefe6d2160944c65e
However, when I press the "Add button", the task goes to the right instead of going down.
In such cases, how should I implement it?
※As a condition, I want to separate addTask function and addButton function.
{
document.addEventListener('DOMContentLoaded', function() {
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
let nextId = 0;
const todos = [];
var tableItem = document.createElement('tr');
const addTask = (task, id) => {
let idSpanTd = document.createElement('td');
let taskSpanTd = document.createElement('td');
//要素内のHTML文章を変更する
idSpanTd.innerText = id;
taskSpanTd.innerText = task;
//生成したテーブル要素をブラウザに表示する
tableItem.append(idSpanTd);
tableItem.append(taskSpanTd);
addTaskTarget.append(tableItem);
return(task,id)
};
//Button要素を生成する
let removeButton = document.createElement('button');
let createButton = document.createElement('button');
const addButton = (button) => {
let createButtonTd = document.createElement('td');
let removeButtonTd = document.createElement('td');
//要素内のHTML文章を変更する
createButton.innerText = '作業中';
removeButton.innerText = '削除';
//生成したテーブル要素をブラウザに表示する
tableItem.append(createButtonTd);
tableItem.append(removeButtonTd);
addTaskTarget.append(tableItem);
//生成したbutton要素を生成する
createButtonTd.append(createButton);
removeButtonTd.append(removeButton);
return(button)
};
//追加ボタンをクリックした際にタスクを追加する処理を行う
addTaskTrigger.addEventListener('click', () => {
const task = addTaskValue.value;
addTask(task, nextId++);
addButton();
addTaskValue.value = '';
});
//チェックリスト用オブジェクト
const todo = {
task: 'taskSpanTd',
status: '作業中'
};
todos.push(todo);
removeButton.addEventListener('click', delete_element, false);
// //削除ボタンを押した時にタスクを削除する
function delete_element () {
let tabletag = this.closest ('tr');
if (tabletag)
tabletag.remove ();
}
});
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel ="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="status" value="1" checked="checked">全て
<input type="radio" name="status" value="2">作業中
<input type="radio" name="status" value="3">完了
</p>
<p></p>
<table>
<thead>
<th>ID</th>
<th>コメント</th>
<th>状態</th>
<th></th>
</thead>
<tbody class ="addTask-target"></tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</script>
</html>
You have defined only one tableItem, only one removeButton and only one createButton.
You must define tableItem, removeButton and createButton as void variables, and only give them a value inside the addTaskTrigger.addEventListener('click') function. It would look like this:
addTaskTrigger.addEventListener('click', () => {
const task = addTaskValue.value;
// Must be already defined as variables
tableItem = document.createElement('tr');
removeButton = document.createElement('button');
createButton = document.createElement('button');
addTask(task, nextId++);
addButton();
addTaskValue.value = '';
});
You are defining only one event listener for each button (remove and create), but won't be enough for javascript to understand that it must listen to all of the rows' buttons. To do it the way you want, you must also define the eventListener only when the user adds a new task (you could define it inside the addButton() function, using the buttons IDs)
Just move creating elements (tableItem, removeButton, createButton, etc.) to the click handler.
{
document.addEventListener('DOMContentLoaded', function() {
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
let nextId = 0;
const todos = [];
const addTask = (task, id, tableItem) => {
let idSpanTd = document.createElement('td');
let taskSpanTd = document.createElement('td');
//要素内のHTML文章を変更する
idSpanTd.innerText = id;
taskSpanTd.innerText = task;
//生成したテーブル要素をブラウザに表示する
tableItem.append(idSpanTd);
tableItem.append(taskSpanTd);
addTaskTarget.append(tableItem);
return(task,id)
};
//Button要素を生成する
const addButton = (tableItem, removeButton, createButton) => {
let createButtonTd = document.createElement('td');
let removeButtonTd = document.createElement('td');
//要素内のHTML文章を変更する
createButton.innerText = '作業中';
removeButton.innerText = '削除';
//生成したテーブル要素をブラウザに表示する
tableItem.append(createButtonTd);
tableItem.append(removeButtonTd);
addTaskTarget.append(tableItem);
//生成したbutton要素を生成する
createButtonTd.append(createButton);
removeButtonTd.append(removeButton);
};
//追加ボタンをクリックした際にタスクを追加する処理を行う
addTaskTrigger.addEventListener('click', () => {
const task = addTaskValue.value;
const tableItem = document.createElement('tr');
const removeButton = document.createElement('button');
const createButton = document.createElement('button');
addTask(task, nextId++, tableItem);
addButton(tableItem, removeButton, createButton);
addTaskValue.value = '';
removeButton.addEventListener('click', delete_element, false);
});
//チェックリスト用オブジェクト
const todo = {
task: 'taskSpanTd',
status: '作業中'
};
todos.push(todo);
// //削除ボタンを押した時にタスクを削除する
function delete_element () {
let tabletag = this.closest ('tr');
if (tabletag)
tabletag.remove ();
}
});
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel ="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="status" value="1" checked="checked">全て
<input type="radio" name="status" value="2">作業中
<input type="radio" name="status" value="3">完了
</p>
<p></p>
<table>
<thead>
<th>ID</th>
<th>コメント</th>
<th>状態</th>
<th></th>
</thead>
<tbody class ="addTask-target"></tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</script>
</html>
I want to use the specifications shown in this video, but it does not work.
Please confirm it.
https://gyazo.com/0dd4feeea3f7a27aefe6d2160944c65e
Conditions:
You can delete the task when you press the delete button
ID is reassigned when deleting a task
After deleting, when adding a new task, the IDs are serialized
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel ="stylesheet" href="css/style.css">
<title>Todoリスト</title>
</head>
<body>
<h1>Todoリスト</h1>
<p>
<input type="radio" name="status" value="1" checked="checked">全て
<input type="radio" name="status" value="2">作業中
<input type="radio" name="status" value="3">完了
</p>
<p></p>
<table>
<thead>
<th>ID</th>
<th>コメント</th>
<th>状態</th>
<th></th>
</thead>
<tbody class ="addTask-target"></tbody>
</table>
<h2>新規タスクの追加</h2>
<input class="addTask-value" type="text" />
<button class="addTask-trigger" type="button">追加</button>
<script src="js/main.js"></script>
</body>
</script>
</html>
document.addEventListener('DOMContentLoaded', function() {
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
let nextId = 0;
const todos = [];
const addTask = (task,id) => {
//テーブル要素を生成する td要素を作る
const tableItem = document.createElement('tr');
const addButtonTd = document.createElement('td');
const idSpanTd = document.createElement('td');
const taskSpanTd = document.createElement('td');
const removeButtonTd = document.createElement('td');
//Button要素を生成する
const addButton = document.createElement('button')
const removeButton = document.createElement('button')
//要素内のHTML文章を変更する
addButton.innerText = '作業中';
removeButton.innerText = '削除';
idSpanTd.innerText = id;
taskSpanTd.innerText = task;
//生成したテーブル要素をブラウザに表示する
tableItem.append(idSpanTd);
tableItem.append(taskSpanTd);
tableItem.append(addButtonTd);
tableItem.append(removeButtonTd);
addTaskTarget.appendChild(tableItem);
//生成したbutton要素を生成する
addButtonTd.append(addButton);
removeButtonTd.append(removeButton);
const todo = {
task: 'taskSpanTd',
status: '作業中'
};
todos.push(todo);
};
addTaskTrigger.addEventListener('click',() => {
const task = addTaskValue.value;
addTask(task,nextId ++);
addTaskValue.value = '';
});
const element = document.querySelector('td')
document.getElementById("removebutton").onclick = function() {
element.remove();
};
});
Define your buttons click actions upon buttons creation
Use Object.defineProperty() to handle your todo "status" property and reactively apply changes to the TR element classList
Use String.prototype.trim() - you don'w want empty spaces to become new todo tasks.
preferably use always Element.textContent instead of Element.innerText
When deleting your TR element, don't forget to update the todos Array by removing that item using todos.splice(todos.indexOf(todo), 1);
// Helper functions
const ELNew = (sel, attr) => Object.assign(document.createElement(sel), attr || {});
const EL = (sel, EL) => (EL || document).querySelector(sel);
// Todo App
const EL_list = EL('#todo-list');
const EL_task = EL('#todo-task');
const EL_add = EL('#todo-add');
const todos = [];
let id = 0;
const addTask = () => {
const task = EL_task.value.trim(); // Always trim!
if (!task) return; // Do nothing
EL_task.value = "";
id += 1;
const todo = {
id: id,
task: task,
status: "",
};
// Make "status" reactive
Object.defineProperty(todo, "__status", {
set(val) {
this.status = val;
TR.classList.remove("is-done", "is-doing");
TR.classList.add(`is-${this.status}`);
}
});
todos.push(todo);
// New Elements
const TR = ELNew("tr");
const TD_id = ELNew("td", {textContent: id});
const TD_task = ELNew("td", {textContent: task});
const TD_status = ELNew("td");
const TD_remove = ELNew("td");
const EL_btn_doing = ELNew("button", {
className: "todo-btn-doing",
textContent: "Doing",
type: "button",
onclick() {
todo.__status = "doing";
}
});
const EL_btn_done = ELNew("button", {
className: "todo-btn-done",
textContent: "Done",
type: "button",
onclick() {
todo.__status = "done";
}
});
const EL_btn_remove = ELNew("button", {
textContent: "×",
title: "Remove this task",
type: "button",
onclick() {
if (!confirm(`Remove task ID:${id} "${task}"`)) return; // Do nothing
TR.remove(); // Remove element
todos.splice(todos.indexOf(todo), 1); // Remove from todos list
}
});
// Insertions
TD_status.append(EL_btn_doing, EL_btn_done);
TD_remove.append(EL_btn_remove);
TR.append(TD_id, TD_task, TD_status, TD_remove);
EL_list.append(TR);
};
EL_add.addEventListener("click", addTask);
/*QuickReset*/* {margin:0; box-sizing:border-box;}
table {
border-collapse: collapse;
border-spacing: 0;
}
table th,
table td {
padding: 5px 10px;
}
#todo-list tr.is-doing td {
background: #fb0;
}
#todo-list tr.is-done td {
background: #0fb;
text-decoration: line-through;
}
#todo-list tr.is-doing .todo-btn-doing {
color: #fb0;
}
#todo-list tr.is-done .todo-btn-done {
color: #0fb;
}
<table>
<thead>
<th>ID</th>
<th>Description</th>
<th>Status</th>
<th></th>
</thead>
<tbody id="todo-list"></tbody>
</table>
<h2>Add new Todo</h2>
<input id="todo-task" type="text" />
<button id="todo-add" type="button">Add</button>
I'm creating a CRUD page where the user can add, delete and edit text, but I have an issue in updating the text after I select it for edit.
In editText function when I click the edit button the text that was added will pop up inside the input field. When I click on the update button (triggering the updateText function), I can see the text in console log but the corresponding html is not updated.
HTML
<div class="main">
<form>
<input type="text" placeholder="search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">update</button>
</div>
</div>
Javascript
const inputsearch = document.querySelector('form input');
const addInputBtn = document.querySelector('#add');
const update = document.querySelector('#update');
addInputBtn.addEventListener('click', addtext);
function addtext(){
let li = document.createElement('li');
let inputadd = document.querySelector('.add-text');
let addedtext = inputadd.value;
let h1Tag = '<h1 id="text">'+addedtext+'</h1>';
let tags = h1Tag + '<button id="delete">Delete</button><button id="edit">Edit</button>';
if(addedtext == ''){
alert('please add some text');
return;
}else{
li.innerHTML = tags;
document.querySelector('ul').appendChild(li);
}
li.querySelectorAll('#delete')[0].addEventListener('click', deleteText);
li.querySelectorAll('#edit')[0].addEventListener('click', editText);
getlist(li, h1Tag);
inputadd.value = '';
}
function deleteText(e) {
e.target.parentNode.remove();
document.querySelector('.add-text').value = '';
}
function editText(e) {
let currentText = e.target.parentNode.firstChild.textContent;
let currentValue = document.querySelector('.add-text');
currentValue.value = currentText;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText = currentValue.value
console.log(currentText = currentValue.value);
}
}
function getlist(li, h1Tag) {
inputsearch.addEventListener('keyup', serchText);
function serchText(e) {
let typetext = e.target.value.toLowerCase();
if(h1Tag.toLowerCase().indexOf(typetext) != -1){
li.style.display = 'block';
}else{
li.style.display = 'none';
}
}
}
To solve the issue without changing your overall approach, your edit button click needs to get the corresponding element (not just its textContent) and pass it to your getupdate() function to be updated when your update button is clicked. Relatively minor changes to your current functions:
function editText(e) {
const currentText = e.target.parentNode.firstChild;
const currentValue = document.querySelector('.add-text');
currentValue.value = currentText.textContent;
getupdate(currentText, currentValue);
}
function getupdate(currentText, currentValue) {
update.addEventListener('click', updateText);
function updateText() {
currentText.textContent = currentValue.value;
}
}
There are some other issues with your code, particularly the creation of multiple elements with the same id (which is malformed and will likely become problematic as you add additional features). Following is a snippet that addresses that issue as well as simplifying some of your functions and fixing the search.
const search = document.querySelector('form input');
const input = document.querySelector('.add-text');
const container = document.querySelector('ul');
let items = null;
let currentItem = null;
const searchItems = (event) => {
if (items) {
const s = event.currentTarget.value.toLowerCase();
for (const item of items) {
if (item.firstChild.textContent.toLowerCase().indexOf(s) !== -1) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
}
}
};
const deleteItem = (event) => {
currentItem = null;
event.currentTarget.parentNode.remove();
};
const editItem = (event) => {
currentItem = event.currentTarget.parentNode.firstChild;
input.value = currentItem.textContent;
};
const updateItem = () => {
if (currentItem) {
currentItem.textContent = input.value;
}
};
const addItem = () => {
let val = input.value
if (val) {
const li = document.createElement('li');
let inner = '<h1 class="text">' + val + '</h1>';
inner += '<button class="delete">Delete</button>';
inner += '<button class="edit">Edit</button>';
li.innerHTML = inner;
container.appendChild(li);
val = '';
currentItem = li.firstChild;
items = document.querySelectorAll('li');
for (let del of document.querySelectorAll('.delete')) {
del.addEventListener('click', deleteItem);
}
for (let edit of document.querySelectorAll('.edit')) {
edit.addEventListener('click', editItem);
}
} else {
alert('please add some text');
return;
}
};
search.addEventListener('keyup', searchItems);
document.querySelector('#add').addEventListener('click', addItem);
document.querySelector('#update').addEventListener('click', updateItem);
<div class="main">
<form>
<input type="text" placeholder="Search">
</form>
<ul></ul>
<div>
<input class="add-text" type="text" placeholder="Add Text">
<button id="add">Add</button>
<button id="update">Update</button>
</div>
</div>