There is default spacing between my edit and delete buttons in the HTML. However, when I append a new list item with JavaScript that has the same exact structure and class names, there is no spacing between these buttons.
Desired Behavior To have the appended buttons appear the same as the "default" buttons in the HTML markup.
HTML
<ul id="list">
<li class="item">
<div>Milk</div>
<button class="edit-button">edit</button>
<button class="delete-button">X</button>
</li>
<li class="item">
<div>Cheerios</div>
<button class="edit-button">edit</button>
<button class="delete-button">X</button>
</li>
<li class="item">
<div>Cheese</div>
<button class="edit-button">edit</button>
<button class="delete-button">X</button>
</li>
</ul>
CSS
.title {
text-align: center;
}
.main {
border: 1px solid black;
width: 50%;
margin: auto;
}
#add-item {
border: 1px solid black;
}
.input {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.label {
margin: 10px;
}
#list {
flex-direction: column;
display: flex;
}
#list > li{
list-style-type: none;
margin: 10px auto;
}
#list div {
margin-bottom: 10px;
text-align: center;
}
/* #list button {
margin: 0px 4px;
} */
Javascript
// TODO: Grab the list
const shoppingList = document.getElementById("list")
// TODO: Grab the input field
const titleInput = document.getElementById("title")
// TODO: Grab the buttons.
const submitButton = document.getElementById("submit-item")
// const editButtons = document.querySelectorAll(".edit-button")
// const delButtons = document.querySelectorAll(".delete-button")
// TODO: Add click event to the button.
submitButton.addEventListener('click', (e) => {
e.preventDefault()
addItem(titleInput.value)
});
// TODO: Create a function to add item.
// ! Requirement: Must have:
// ! - item text
// ! - edit button
// ! - delete button
// ! - input field
// ! Requirement: Add event listeners to buttons
// TODO: Edit button must get pass the Parent node.
function addItem(title) {
console.log("Running addItem")
let newItem = document.createElement("li")
newItem.classList.add("item")
let newTitle = document.createElement("div")
newTitle.textContent = title
let editBtn = document.createElement("button")
editBtn.classList.add("edit-button")
editBtn.innerText = "edit"
let delBtn = document.createElement("button")
delBtn.classList.add("delete-button")
delBtn.innerText = "X"
editBtn.addEventListener('click', (e) => {
console.log("Pressed the edit button", e)
editItem(e.target.parentElement)
});
newItem.appendChild(newTitle)
newItem.appendChild(editBtn)
newItem.appendChild(delBtn)
shoppingList.appendChild(newItem)
}
// TODO: Create a function to edit item.
// ! Requirement: Parent Node (Element) parameter
// TODO: Remove the Edit, Delete buttons.
// TODO: Grab text content of the div and assign to variable.
// TODO: Add an input element to the parent node.
// TODO: Set input's value to the variable with the text content.
// TODO: Add the save button.
function editItem(listItem) {
let title;
listItem.childNodes.forEach(element => {
console.log(element.tagName)
if(element.tagName === "DIV") {
title = element.innerText
}
});
listItem.innerHTML = ""
let editInput = document.createElement("input")
editInput.value = title
let saveBtn = document.createElement("button")
saveBtn.classList.add("save-button")
saveBtn.innerText = "save"
listItem.append(editInput, saveBtn)
saveBtn.addEventListener('click', (e) => {
saveItem(e.target.parentNode)
});
}
// TODO: Create a function to save item.
// ! Requirement: Parent Node (Element) parameter
// TODO: Get the value of the input field and assign to variable
// TODO: Remove the input and save button.
// TODO: Create the div, edit, and delete buttons.
// TODO: Set the div's text content to the variable with the input's value.
// TODO: Add all those elements to the parent element.
function saveItem(listItem) {
let titleEdit;
listItem.childNodes.forEach(element => {
if(element.tagName === "INPUT") {
titleEdit = element.value
}
});
listItem.innerHTML = "";
let changedTitle = document.createElement("div");
changedTitle.textContent = titleEdit;
let editBtn = document.createElement("button");
editBtn.classList.add("edit-button");
editBtn.innerText = "edit";
let delBtn = document.createElement("button");
delBtn.classList.add("delete-button");
delBtn.innerText = "X";
listItem.appendChild(changedTitle);
listItem.appendChild(editBtn);
listItem.appendChild(delBtn);
}
// TODO: Create a function to delete item.
// ! Requirement: Parent Node (Element) paramter
// I believe you can figure this one out yourself. <3 :)
StackOverflow Articles I've Looked At (I tried linking these but it said these links made my question appear like "Spam" - so, here's the titles.)
Why are initial CSS styles not visible on DOM element style field?
This is talking about an issue accessing a style's CSS property, versus accessing the fully rendered CSS properties. This isn't really applicable since there are not any styles by default in this example.
Appended Element with Missing Styles
Styles are not missing, they're applied, but the same style is applied differently between the appended elements.
Remove Blank Spaces Between Buttons in HTML CSS
I did a CSS reset, and the issue was still happening. Additionally, this is horizontal and not vertical spacing.
Can I use a DIV inside a List Item?
Checking to see if the HTML structure was valid, and HTML specifications say that I can have divs and other block level elements inside the li.
Appended Content do not get the proper css effect
This person had an issue where the div was appended inside of the UL element, and was causing things to break. This is not my issue.
Appending Elements to DOM with Indentation Spacing
This particular question was having issues with the appended DIV's HTML structure not being in the correct format. I am not having this issue either. My HTML structure appears to be exactly the same in the Dev Tools.
Strange Error When Appending Elements in JavaScript
This particular issue is encountering a type error. There are no errors in the console. It appears to be a strange formatting / CSS bug.
None of these articles seemed to apply to this particluar issue. I am not sure if this is a bug or not but, considering this is mostly default styling, persistent across browsers, and persists even when styles are added. I'm at a loss.
Your problem is how whitespace characters like newlines (\n
) are handled in JavaScript. When you build the buttons with plain string concatenation, a newline character (when you hit Enter in your code editor) will appear inbetween the buttons. You were right in assuming there was a hidden character, but it's literally the Enter key, which you might not have suspected - but that is what is rendering the extra spacing in the HTML.
To fix this, you'll want to use template literals - it's cleaner, and you don't have to worry about accidental whitespace.
Try replacing your "addItem" code with this:
function addItem(title) {
let newItem = document.createElement("li");
newItem.classList.add("item");
newItem.innerHTML = `
<div>${title}</div>
<button class="edit-button">edit</button>
<button class="delete-button">X</button>
`;
shoppingList.appendChild(newItem);
}
Here's your CodePen with the changes