[英]JavaScript Todo List - When I click 'edit' button, it selects the wrong text input, but still edits the correct item
const todoList = { todos: [], addTodo: function(todoText) { this.todos.push({ todoText: todoText, completed: false }); view.displayTodos(); }, changeTodo: function(position, newTodoText) { this.todos[position].todoText = newTodoText; view.displayTodos(); }, deleteTodo: function(position) { this.todos.splice(position, 1); view.displayTodos(); }, toggleCompleted: function(position) { let todo = this.todos[position]; todo.completed = !todo.completed; }, toggleAll: function() { const allTodos = this.todos.length; let completedTodos = 0; for (let i = 0; i < allTodos; i++) { if (this.todos[i].completed === true) { completedTodos++; } } if (completedTodos === allTodos) { for (let i = 0; i < allTodos; i++) { this.todos[i].completed = false; } } else { for (let i = 0; i < allTodos; i++) { this.todos[i].completed = true; } } view.displayTodos(); } }; const handlers = { toggleAll: function() { todoList.toggleAll(); }, addTodo: function(e) { if (e.keyCode === 13) { e.preventDefault(); // Ensure it is only this code that rusn let todoTextInput = document.getElementById('todoTextInput'); todoList.addTodo(todoTextInput.value); todoTextInput.value = ''; } }, deleteTodo: function(position) { todoList.deleteTodo(position); } }; const view = { displayTodos: function() { let todosUl = document.getElementById('todoList'); todosUl.innerHTML = ''; for (let i = 0; i < todoList.todos.length; i++) { let todoLi = document.createElement('li'); let todoLiText = document.createElement('input'); todoLiText.type = "text"; todoLiText.disabled = true; todoLiText.id = 'textInput'; let todoTextWithCompletion = todoList.todos[i].todoText;; let check = document.createElement('input'); check.type = "checkbox"; check.id = "checkbox"; check.className = "checkbox"; check.checked = ''; todoLi.id = i; todoLiText.value = todoTextWithCompletion; todoLi.appendChild(check); todoLi.appendChild(todoLiText); todoLi.appendChild(this.createDeleteButton()); todoLi.appendChild(this.createEditButton()); todosUl.appendChild(todoLi); if (document.getElementById('checkbox').checked === true) { todoList.toggleCompleted(i); }; if (todoList.todos[i].completed === true) { todoLiText.style.textDecoration = "line-through"; }; } }, createDeleteButton: function() { let deleteButton = document.createElement('a'); deleteButton.href = "#"; deleteButton.textContent = "Delete"; deleteButton.className = 'x'; return deleteButton; }, createEditButton: function() { let editButton = document.createElement('a'); editButton.href = "#"; editButton.textContent = "edit"; editButton.className = 'edit'; return editButton; }, setUpEventListeners: function() { let todosUl = document.getElementById('todoList'); todosUl.addEventListener('click', (event) => { let elementClicked = event.target; if (elementClicked.className === 'x') { handlers.deleteTodo(parseInt(elementClicked.parentNode.id)); }; }); // Edit List Item todosUl.addEventListener('click', (event) => { let elementClicked = event.target; let position = elementClicked.parentNode.id; if (elementClicked.className === 'edit') { let input = document.getElementById('textInput'); input.disabled = false; input.className += " activeTextInput "; input.focus(); input.select(); input.addEventListener('keyup', (event) => { let elementClicked = event.target; if (event.keyCode === 13) { let textInput = input.value; input.disabled = true; input.classList.remove("activeTextInput"); todoList.changeTodo(position, textInput); }; }); }; }); // Line through on check todosUl.addEventListener('click', (event) => { let elementClicked = event.target; let position = elementClicked.parentNode.id; let check = document.getElementById('checkbox'); if (elementClicked.className === 'checkbox') { todoList.toggleCompleted(position); check.checked = true; }; }); //Delete All let clearAll = document.getElementById('clearAll'); clearAll.addEventListener('click', (event) => { todoList.todos.splice(0, todoList.todos.length); view.displayTodos(); }); // TODO Delete Selected } }; view.setUpEventListeners();
html, body { margin: 0; height: 100%; } body { background-color: #eeeeee !important; } h1 { color: #282845 !important; } p { opacity: .3; } .container { min-height: 70%; display: flex; justify-content: center; flex-direction: column; width: 50% !important; } #todoTextInput { background-color: white; opacity: .7; box-shadow: 1px 1px 10px rgba(5, 5, 5, 0.2); height: 50px; padding: 10px; border: none; font-style: italic; } ul { display: flex; flex-direction: column; padding: 0; margin: 0; } li { list-style-type: none !important; border-bottom: 1px solid rgba(5, 5, 5, 0.1); padding: 10px; background-color: white; box-shadow: 1px 1px 10px rgba(5, 5, 5, 0.2); min-width: inherit; } li a { float: right; padding-right: 10px; opacity: .3 !important; transition: .2s; } li a:hover { opacity: 1 !important; } input { border: none; border-bottom: 1px solid rgba(5, 5, 5, 0..01); background-color: inherit; } li input[type="text"] { padding: none; border: none; width: 80%; margin-left: 10px; transition: .5s; } .activeTextInput { box-shadow: 1px 1px 10px rgba(5, 5, 5, 0.1); padding: 10px !important; } input[type="text"] { background-color: inherit; border: none; border-bottom: 1px solid rgba(5, 5, 5, 0.01); padding: 0; } input:focus { outline: none; } input:checked+input[type="text"] { text-decoration: line-through; opacity: .5; } .btn { background-color: white !important; border-radius: 0 !important; padding: 0; box-shadow: 1px 1px 10px rgba(5, 5, 5, 0.2); margin-top: -2px !important; font-style: italic; opacity: 0.5; } #clearAll { margin-top: -21px !important; } .hidden { display: none !important; background-color: red !important; }
<link href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" rel="stylesheet" /> <body> <div class="container"> <h1 class="text-center">List+</h1> <div class="row list-head"> <div class="col-md-12"> <input type="text" placeholder="Enter a List Item" style="width: 100%" id="todoTextInput" onkeyup="handlers.addTodo(event)"> </div> </div> <div class="row list-container"> <div class="col-md-12"> <ul id="todoList"> </ul> </div> </div> <div class="row"> <div class="col-md-12"> <button class="btn" style="width: 100%" id="clearAll">Clear All</button> <button class="btn" style="width: 100%">Clear Selected</button> </div> </div> <div class="row"> <div class="col-md-12"> <p class="text-center"><i>Created by Connor Beam</i></p> </div> </div> </div> <script src="js/main.js"></script> </body>
I'm building a todo list in vanilla JavaScript. 我正在使用普通JavaScript构建待办事项列表。 I'm trying to get the 'edit' option to function properly. 我正在尝试使“编辑”选项正常运行。 When I click the 'edit' button, the corresponding text input should be enabled, and auto-selected, then the user should be able to press 'enter' to submit changes. 当我单击“编辑”按钮时,应启用并自动选择相应的文本输入,然后用户应能够按“输入”来提交更改。
However, no matter which 'edit' button is clicked, he first text input is always selected, while still changing the correct item when submitted. 但是,无论单击哪个“编辑”按钮,始终都会选择第一个文本输入,同时在提交时仍会更改正确的项目。
Here's a working link to the most recent version: http://vanillajstodo.surge.sh/ 这是最新版本的有效链接: http : //vanillajstodo.surge.sh/
I believe the problem is that all 'todoLiText' inputs are being created with the same id; 我认为问题在于所有“ todoLiText”输入都使用相同的ID创建; however, I'm not sure how to fix that. 但是,我不确定该如何解决。
Let me know if more info is needed. 让我知道是否需要更多信息。
Thanks 谢谢
Take a look at this solution: 看一下这个解决方案:
https://codepen.io/anon/pen/YQQovp?editors=1010 https://codepen.io/anon/pen/YQQovp?editors=1010
let input = document.getElementById(position).childNodes[1];
Your mistake is that you should never have multiple elements with the same id on the same page. 您的错误是,在同一页面上永远不要有多个具有相同ID的元素。 Instead you should use the same class in that situation. 相反,在这种情况下,您应该使用相同的类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.