JavaScript DOM Issue - javascript

I'm having trouble retrieving the textContent of some of my elements. The issue arises from line 88-91. Line 91 retrieves a value of null. I don't understand why this is so. I was able to verify this by setting line 91 to a variable and console.log() to the console and the value was returned as null. Additionally, at line 99 my console is giving me an error of, "Uncaught TypeError: Cannot read property 'firstChild' of undefined". I'm assuming this error is related to the issue I'm having at lines 88-91, but I'm not entirely sure because it says undefined and not null. The HTML elements have text inside of them so I don't know why it would be returning null. I'm not sure what I'm missing. Any insight is greatly appreciated. Thanks in advance for you guys insight!
HTML Markup:
(function(){
const taskList = document.querySelector('ul');
const completedList = document.querySelector('#completed-task');
const editTask = document.querySelector('#edit-task');
const cover = document.querySelector('.cover');
const editedInfo = document.querySelector('#edited-info');
const editedDate = document.querySelector('#edited-date');
const editedName = document.querySelector('edited-item');
let editedListItem;
document.querySelector('button').addEventListener('click', function(e) {
/* Preventing Page Default Page Refresh*/
e.preventDefault();
/* Grabbing User Input */
let userInput = document.querySelector('input').value;
let userDate = document.getElementById('date').value;
let userInfo = document.getElementById('userInfo').value;
/* Creating Elements */
let listItem = document.createElement('li');
let container = document.createElement('div');
let item = document.createElement('span');
let deletebutton = document.createElement('span');
/* Update: February 4, 2019 --> Creating Info Box */
let infoBox = document.createElement('div');
let dueDate = document.createElement('p');
let info = document.createElement('p');
let span = document.createElement('span');
/* Update: February 5, 2019 --> Creating Edit button */
let edit = document.createElement('span');
/* Adding Attributes */
container.setAttribute('class', 'container');
deletebutton.setAttribute('class','delete');
infoBox.setAttribute('class','info');
edit.setAttribute('class', 'edit');
/* Setting User Input */
item.textContent = userInput;
span.textContent = userDate;
info.textContent = userInfo;
deletebutton.textContent = "Discard";
dueDate.textContent = "Due: ";
edit.textContent = "Edit";
/* Adding Elements to List */
taskList.appendChild(listItem);
listItem.appendChild(container);
container.appendChild(item);
container.appendChild(deletebutton);
listItem.appendChild(infoBox);
infoBox.appendChild(dueDate);
infoBox.appendChild(info);
dueDate.appendChild(span);
infoBox.appendChild(edit);
});
document.querySelector('#task-list').addEventListener('click',function(event){
if(event.target.className == 'delete') {
const li = event.target.parentElement;
li.parentElement.removeChild(li);
}
});
/* Update: February 4, 2019 --> Hide Tasks Checkbox */
document.forms['hide-task'].addEventListener('change', function(event){
const checkbox = document.querySelector('input[type="checkbox"]');
if (checkbox.checked === true) {
taskList.style.display = 'none';
} else {
taskList.style.display = 'block';
}
});
taskList.addEventListener('click', function(event){
if (event.target.className == 'complete') {
let parent = event.target.parentElement.parentElement;
completedList.appendChild(parent);
}
/******* ISSUE OCCURS IN THIS CODE BLOCK *************/
if (event.target.className == 'edit') {
event.preventDefault();
editTask.style.display = 'flex';
cover.style.display = 'block';
editedDate.value = event.target.previousSibling.previousSibling.textContent;
editedInfo.value = event.target.previousSibling.textContent;
editedName.value = event.target.parentElement.previousSibling.firstChild.textContent;
editedListItem = event.target.parentElement.parentElement;
}
});
document.querySelector('#change').addEventListener('click', function(event){
editedListItem.firstChild.firstChild.textContent = editedName.value;
editedListItem.lastChild.firstChild.textContent = editedDate.value;
editedListItem.lastChild.lastChild.textContent = editedInfo.value;
editTask.style.display = 'none';
cover.style.display = 'none';
});
})()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>To Do List</title>
</head>
<body>
<div class="cover"></div>
<h1>To do List</h1>
<form>
<div id="input-button">
<input type="text" placeholder="Add an item..." class="item">
<button type="submit" class="add">+</button>
</div>
<div>
<input type="text" placeholder="Due Date..." id="date">
<input type="text" placeholder="About the task..." id="userInfo">
</div>
</form>
<hr>
<ul id="task-list">
<li>
<div class="container">
<span class="title">Example Task</span>
<span class="delete">Discard</span>
</div>
<!-- Update: Feb #, 2019 -->
<div class="info">
<p>Due: <span>January 15, 2019</span></p>
<p>This is some example text that adds additional context or information for the task</p>
<span class="edit">Edit</span>
</div>
</li>
</ul>
<!-- Update: February 5, 2019 -->
<ul id="completed-task">
<li id="title">Completed Tasks</li>
</ul>
<!-- Update: February 4, 2019 -->
<form id="hide-task">
<div>
<input type="checkbox" name="hide-task">
<label for="hide-task">Hide Tasks</label>
</div>
</form>
<form id="edit-task">
<input type="text" placeholder="Edit item..." id="edited-item">
<input type="text" placeholder="Edit Due Date..." id="edited-date">
<input type="text" placeholder="Edit about the task..." id="edited-info">
<button id="change" type="button">Change</button>
</form>
</body>
</html>

After a break and some dinner, I started debugging with a fresh set of eyes and an unfrustrated mind and found the bugs. Everything is now working properly.
1st Issue:
A Typo in the querySelector was responsible for one of the variables to return
textContent error.
Solution:
const editedName = document.querySelector('#edited-item');
2nd Issue:
For the most part previousSibling and previousElementSibling return the element, but
previousSibling will return any kind of sibling. Some browsers add white space around
the elements and so previousSibling will grab the white space around the element
instead, but previousElementSibling always grabs the Element. My initial code was
grabbing the white space around the element.
Solution:
taskList.addEventListener('click', function(event){
if (event.target.className == 'complete') {
let parent = event.target.parentElement.parentElement;
completedList.appendChild(parent);
}
if (event.target.className == 'edit') {
event.preventDefault();
editTask.style.display = 'flex';
cover.style.display = 'block';
editedDate.value = event.target.previousElementSibling.previousElementSibling.firstElementChild.textContent;
editedInfo.value = event.target.previousElementSibling.textContent;
editedName.value = event.target.parentElement.previousElementSibling.firstElementChild.textContent;
editedListItem = event.target.parentElement.parentElement;
}
});
document.querySelector('#change').addEventListener('click', function(event){
editedListItem.firstElementChild.firstElementChild.textContent = editedName.value;
editedListItem.lastElementChild.firstElementChild.firstElementChild.textContent = editedDate.value;
editedListItem.lastElementChild.firstElementChild.nextElementSibling.textContent = editedInfo.value;
editTask.style.display = 'none';
cover.style.display = 'none';
});

Related

Click event only works on the second click

i hope you guys fine, well..
I'm doing a To Do List, and there is a problem in my code, which I've been trying to solve for a few days, and no effective results was made..
If you guys test in the snippet with me, i am sure, that will be more
clear to understand.
When i click in some list element, my javascript should change or add the className, and add a class call 'selected'.
because, when i will click in the remove button, they will delete all elements with 'selected' classList in the list. (as you can see in the code)
But the className a not being add to the tag in the first click, just works if i click in the element one more time.
i simplified my code, just to show the real problem:
Link to jsfiddle : https://jsfiddle.net/myqrzcs2/
const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click() {
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
};
const completedLine = document.querySelector('ol');
function umClick(event) {
if (event.target.tagName === 'LI') {
const listas = document.querySelectorAll('.lista');
listas.forEach((i) => {
i.addEventListener('click', function semNomeDois() {
listas.forEach((j) => j.classList.remove('selected'));
this.classList.add('selected');
});
});
}
}
completedLine.addEventListener('click', umClick);
function removeSelected() {
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1) {
listaSelected[i].remove();
}
}
.lista:focus {
background: red;
}
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
But how can i make the class be add, just in the first click, not in the second?
I think you got off on the wrong foot in programming this.
Here is the way I use, may it inspire you.
const
textoTarefa = document.getElementById('texto-tarefa')
, criarTarefa = document.getElementById('criar-tarefa')
, removerSelec = document.getElementById('remover-selecionado')
, listaTarefas = document.getElementById('lista-tarefas')
;
var li_selected = null
;
textoTarefa.oninput = () =>
{
criarTarefa.disabled = (textoTarefa.value.trim().length ===0 )
}
criarTarefa.onclick = () =>
{
listaTarefas.appendChild( document.createElement('li')).textContent = textoTarefa.value.trim()
textoTarefa.value = ''
textoTarefa.focus()
criarTarefa.disabled = true
}
listaTarefas.onclick = ({target}) =>
{
if (!target.matches('li')) return
if (!!li_selected && li_selected !== target ) li_selected.classList.remove('listaSelect')
li_selected = target.classList.toggle('listaSelect') ? target : null
removerSelec.disabled = !li_selected
}
removerSelec.onclick = () =>
{
listaTarefas.removeChild(li_selected)
li_selected = null
removerSelec.disabled = true
}
.listaSelect {
background: #ff0000c4;
}
ol#lista-tarefas {
cursor : pointer
}
<input id='texto-tarefa' type="text" value="">
<button id='criar-tarefa' disabled>Add</button>
<button id='remover-selecionado' disabled>Remove Selected</button>
<ol id='lista-tarefas'></ol>
You were unnecessarily adding an event listener to each item in the list.
You can check the updated fiddle here: https://jsfiddle.net/msa9v2nf/
Since you're already checking which target element is clicked, there isn't any need to add an individual listener to each child item in the list.
I updated the umClick function:
function umClick(event) {
if (event.target.tagName === 'LI') {
const listas = document.querySelectorAll('.lista');
listas.forEach((i) => {
listas.forEach((j) => j.classList.remove('selected'));
event.target.classList.add('selected');
});
}
}
The problem is you call the function umClick and call the function to add .selected within a click event in the same function umClick.
What happens is the click event completedLine.addEventListener('click', umClick); happens before the i.addEventListener('click', function semNomeDois() event. This is why you need a first click on the ol tag for only the first time.
To fixes this you have multiple options:
instead of calling click event on ol tag you can call mousedown which happens before click event.
Calling a click event on the li elements on creation, which needs a new function.
Depending on Vektor's answer, you can remove the unnecessary click event inside the first click event.
Also, I've made the red highlight on the .selected class instead of :focus, just to make it clear when the item is selected.
.selected {
background: red;
}
First Solution
const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click() {
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
};
const completedLine = document.querySelector('ol');
function umClick(event) {
if (event.target.tagName === 'LI') {
const listas = document.querySelectorAll('.lista');
listas.forEach((i) => {
i.addEventListener('click', function semNomeDois() {
listas.forEach((j) =>{
if(j != event.target)
j.classList.remove('selected');
});
this.classList.add('selected');
});
});
}
}
completedLine.addEventListener('mousedown', umClick);
function removeSelected() {
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1) {
listaSelected[i].remove();
}
}
.selected {
background: red;
}
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
Second Solution
const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click() {
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
lista.addEventListener('click',function(){
itemClick(this);
});
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
};
function itemClick(item) {
const listas = document.querySelectorAll('.lista');
listas.forEach((j) =>j.classList.remove('selected'));
item.classList.add('selected');
}
function removeSelected() {
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1) {
listaSelected[i].remove();
}
}
.selected {
background: red;
}
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>
</html>
I am not fully understand your problem but,
If you want to add the style when selecting a item, just add the style to
.selected
If you want in focus, and remove the class when there is no focus, you may add an eventlistener to control that.

Error in JavaScript addToDoButton.addEventListener("click", function(){

What have I done wrong? Here is what the result tells me:
Uncaught ReferenceError: addToDoButton is not defined
Here is my JavaScript:
let addToDo = document.getElementById("edit_button");
let toDoContainer = document.getElementById("to_do_container");
let inputField = document.getElementById("inputField");
addToDoButton.addEventListener("click", function(){
var paragraph = document.createElement("p");
paragraph.classList.add("paragraph-styling");
paragraph.innerText = inputField.value;
toDoContainer.appendChild(paragraph);
inputField.value = " ";
paragraph.addEventListener("click", function(){
paragraph.style.textDecoration = "line-through";
})
paragraph.addEventListener("dblclick", function(){
paragraph.removeChild(paragraph)
})
})
Here is my HTML:
<html>
<head>
<link rel="stylesheet", href="style.css">
<h1 class="tdl_header">TO DO LIST</h1>
</head>
<body class="body">
<div class="container">
<input id="inputField" type = "text"
placeholder="add your list">
<button id="addToDo"> + </button>
<div class="to-dos" id="toDoContainer" >
</div>
</div>
<script src="to_do_list.js"></script>
</body>
</html>
let addToDo = document.getElementById("edit_button");
let toDoContainer = document.getElementById("to_do_container");
let inputField = document.getElementById("inputField");
addToDoButton.addEventListener("click", function() {
var paragraph = document.createElement("p");
paragraph.classList.add("paragraph-styling");
paragraph.innerText = inputField.value;
toDoContainer.appendChild(paragraph);
inputField.value = " ";
paragraph.addEventListener("click", function() {
paragraph.style.textDecoration = "line-through";
})
paragraph.addEventListener("dblclick", function() {
paragraph.removeChild(paragraph)
})
})
<html>
<head>
<link rel="stylesheet" , href="style.css">
<h1 class="tdl_header">TO DO LIST</h1>
</head>
<body class="body">
<div class="container">
<input id="inputField" type="text" placeholder="add your list">
<button id="addToDo"> + </button>
<div class="to-dos" id="toDoContainer">
</div>
</div>
<script src="to_do_list.js"></script>
</body>
</html>
You called your variable addToDo but want to add the listener to addToDoButton which doesn't exist.
EDIT:
As #Beriu mentioned, the id of the button also doesn't match the string in the selector.
You have two issues there:
you want to select a button wiht getElementById('edit_button') which doesn't exists
you want to addEventListener to a DOM element which can't be selcted
Solution:
let addToDo = document.getElementById("addToDo");
let toDoContainer = document.getElementById("to_do_container");
let inputField = document.getElementById("inputField");
addToDo.addEventListener("click", function() {
// your code
})
I would suggest you attach your event handler for the click and double click on the "tasks" to the container, then it is easier to use the event.target for the action to take place.
I did some rework of class and id to make them more consistent and match the event handler attachment here also.
I also do not append "blank" tasks.
function handleToDoPlus(event) {
let inputField = document.getElementById("input-field");
let newValue = inputField.value;
let hasValue = newValue.length > 0
event.target.nextElementSibling.innerText = hasValue ? "" : "No Value Entered";
if (hasValue) {
let paragraph = document.createElement("p");
paragraph.classList.add("paragraph-styling");
paragraph.innerText = newValue;
let toDoContainer = document.getElementById("to-do-container");
toDoContainer.appendChild(paragraph);
inputField.value = "";
}
}
function handleDoubleClick(event) {
console.log('double click!');
if (event.target.className === 'paragraph-styling') {
event.currentTarget.removeChild(event.target)
}
}
function handleClickToDone(event) {
console.log('Click!');
if (event.target.className === 'paragraph-styling') {
event.target.style.textDecoration = "line-through";
}
}
let addToDo = document.getElementById("add-to-do");
addToDo.addEventListener("click", handleToDoPlus);
let toDoContainer = document.getElementById("to-do-container");
toDoContainer.addEventListener("dblclick", handleDoubleClick);
toDoContainer.addEventListener("click", handleClickToDone);
//let inputField = document.getElementById("input-field");
.error-message {
color: #FF0000;
}
<div class="container">
<input id="input-field" type="text" placeholder="add your list">
<button id="add-to-do"> + </button> <span class="error-message"></span>
<div id="to-do-container" class="to-dos">
</div>
</div>

Having trouble with ToDo List App with saving to localStorage

Super new to all of this so this might be some beginner troubleshooting. The list seems to be working where I'm adding a list element to the UL with a checkbox and delete button. When checkbox is checked it puts a line through the text and when the delete button is clicked it deletes the list element. The assignment asks to save to localStorage so that when refreshed, the list items still remain, and I'm getting super confused by this. What I have now seems to be saving my list elements to an array but I don't understand how to get them to save and stay on the page.
const form = document.querySelector('form');
const input = document.querySelector('#todoInput');
const newElement = document.querySelector('ul');
const savedToDos = JSON.parse(localStorage.getItem('todos')) || [];
newElement.addEventListener('click', function(e) {
if(e.target.tagName === 'BUTTON') {
e.target.parentElement.remove()
}
})
function addToList(text) {
const li = document.createElement('li');
const checkbox = document.createElement('input');
const button = document.createElement('button');
button.innerText = "Delete";
checkbox.type = 'checkbox';
checkbox.addEventListener('change', function() {
li.style.textDecoration = checkbox.checked ? 'line-through' : 'none';
})
li.innerText = text;
li.insertBefore(checkbox, li.firstChild);
li.appendChild(button);
return li;
};
form.addEventListener('submit', function(e) {
e.preventDefault();
const newListItem = addToList(input.value);
input.value = '';
newElement.append(newListItem);
savedToDos.push(newListItem.innerText);
localStorage.setItem('todos', JSON.stringify(savedToDos));
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ToDo App</title>
<link rel="stylesheet" href="app.css">
</head>
<body>
<div>
<h1>Todo List</h1>
<form action="">
<input type="text" id="todoInput" placeholder="Add To Todo List">
<button class="add-button">Add</button>
</form>
<ul id="todoList">
</ul>
</div>
<script src="app.js"></script>
</body>
</html>
It looks like you're failing to populate the DOM when the page loads.
After you retrieve the items from local storage (which you're already doing), loop through the list and add each of them to the DOM:
// After this line, which you've already written:
const savedToDos = JSON.parse(localStorage.getItem('todos')) || [];
// Loop through savedToDos, and for each one, insert a new list:
savedToDos.forEach(function(value) {
const newListItem = addToList(value);
newElement.append(newListItem);
});
Every browser has local storage where we can store data and cookies. just go to the developer tools by pressing F12, then go to the Application tab. In the Storage section expand Local Storage.
this piece of code might help you
// Store Task
function storeTaskInLocalStorage(task) {
let tasks;
if(localStorage.getItem('tasks') === null){
tasks = [];
} else {
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.push(task);
localStorage.setItem('tasks', JSON.stringify(tasks));
}

Unable to delete multiple li from ul

I'm creating a to-do list for class:
Lab 4: Todo List Let's make a simple todo-list which supports the
following operations: add an item to the list remove an item from the
list mark an item as completed Removed items should disappear
entirely. Completed items should appear at the bottom (or in a
separate list) with a line through them.
I'm unable to remove multiple li from my ul. I get an error after removing the first.
lab-04.js:16 Uncaught DOMException: Failed to execute 'removeChild' on
'Node': The node to be removed is not a child of this node. at
HTMLButtonElement.removeBtn.onclick
(http://127.0.0.1:5500/js/lab-04/lab-04.js:16:18)
Oddly, enough the buttons are removed without much fuss.
The code (js):
let manipulateDom = () => {
let container = document.getElementsByClassName('container')
let toDoList = document.getElementById('to-do')
let removeBtn = document.createElement('button')
content = document.getElementById('userInput').value
listItem = document.createElement('li')
listItem.className = 'list-item'
listItem.textContent = (content)
removeBtn.appendChild(document.createTextNode('remove'))
removeBtn.onclick = function() {
toDoList.removeChild(removeBtn)
toDoList.removeChild(listItem)
}
toDoList.appendChild(listItem)
toDoList.appendChild(removeBtn)
}
(html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lab-04</title>
<script src='/js/lab-04/lab-04.js'></script>
</head>
<body>
<h4>To Do List</h4>
<input type='text' id='userInput' placeholder="item to add">
<input type="submit" onclick="manipulateDom()">
<ul id='to-do'>
</ul>
<ul id='done'>
</ul>
</body>
</html>
Any help is greatly appreciated, ready to pull my hair out
You are putting your listItem in the window scope, and what removeBtn.onclick does is removing the listItem in the window scope, that's why the remove button only works once and only works on the last element created.
Declare listItem in the block scope and it should be working again
let manipulateDom = () => {
let container = document.getElementsByClassName('container');
let toDoList = document.getElementById('to-do');
let removeBtn = document.createElement('button');
let content = document.getElementById('userInput').value;
let listItem = document.createElement('li');
listItem.className = 'list-item';
listItem.textContent = (content);
removeBtn.appendChild(document.createTextNode('remove'))
removeBtn.onclick = function() {
toDoList.removeChild(removeBtn);
toDoList.removeChild(listItem);
};
toDoList.appendChild(listItem);
toDoList.appendChild(removeBtn);
}
<h4>To Do List</h4>
<input type='text' id='userInput' placeholder="item to add">
<input type="submit" onclick="manipulateDom()">
<ul id='to-do'>
</ul>
<ul id='done'>
</ul>

Create Todo list with Javascript. It is an additional question

I received answers regarding the following contents.
Create Todo list with Javascript
If you enter too many characters, the "state" part will be misaligned. Like in the video, I want to expand the width of the "comment" according to the input value. What should I do?
See also the image.
Have already updated my answer to acomodate this additional bit on the same question :). See this and read the comments on the snippets:
https://stackoverflow.com/a/62356950/4650975
document.addEventListener('DOMContentLoaded', function() {
// 必要なDOM要素を取得。
const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0];
const addTaskTarget = document.getElementsByClassName('addTask-target')[0];
const addTaskValue = document.getElementsByClassName('addTask-value')[0];
//ID用のインデックスを定義
let nextId = 0;
const addTask = (task,id) => {
// 表のタグを生成する
const tableItem=document.createElement('thead');
const addButton = document.createElement('button');
const removeButton = document.createElement('button');
addButton.style.margin = "5px"; //<------- Added a style here
removeButton.style.margin ="5px"; //<------- Added a style here
// それぞれ作業中、削除という言葉をボタンに入れる
addButton.innerText = '作業中';
removeButton.innerText = '削除';
//ボタンを押したら以下の作業をする
removeButton.addEventListener('click', () => removeTask(removeButton));
// IDを表示するspan要素を作成して tableItem に追加
const idSpan = document.createElement('span');
idSpan.innerText = id;
idSpan.style.marginRight = "20px"; //<------- Added a style here
tableItem.append(idSpan);
const taskSpan = document.createElement('span');
taskSpan.style.width = "60px"; //<------- Added a style here
taskSpan.style.display = "inline-block"; //<------- Added a style here
taskSpan.style.overflow = "hidden"; // <----- This styling for trimming the text if it exceeds certain width
taskSpan.style.textOverflow = "ellipsis"; // <------- This will append a (...) to the exceeding text
taskSpan.innerText = task;
taskSpan.title = task; //If you hover on the text full text will be displayed. In production code, you might like to use fancy tooltips, say, from bootstrap, for this
tableItem.append(taskSpan); //<------- changed this
//入力タスクを表示
addTaskTarget.appendChild(tableItem);
// 作業中ボタンを追加
tableItem.appendChild(addButton);
// 削除ボタンを追加
tableItem.appendChild(removeButton);
};
// 追加ボタンに対して、タスク登録イベントを設定
addTaskTrigger.addEventListener('click', event => {
const task = addTaskValue.value;
addTask(task,nextId ++);
addTaskValue.value = '';
});
});
<html lang="en">
<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>
<tr>ID コメント 状態</tr>
</thead>
<tbody class ="addTask-target">
<tr>
</tr>
</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>

Categories

Resources