简体   繁体   中英

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. 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/

I believe the problem is that all 'todoLiText' inputs are being created with the same 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

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. Instead you should use the same class in that situation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM