Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Interactive Web Pages with JavaScript Traversing and Manipulating the DOM with JavaScript Perform: Appending and Removing Elements

My input boxes are not lined horizontally and i'm pretty sure there is only one button showing?

So, I looked at his code best I could and I thought I had it right, but my boxes don't line up like his in this video. Also, I think there's only one button showing up. HELP!

https://w.trhou.se/g7lqse18lb

6 Answers

Andrew Chalkley
STAFF
Andrew Chalkley
Treehouse Guest Teacher

Hi Rich Cordero & Dan Whiting

The vertical button issue seems to be an issue in Firefox. Browsers sometimes have different visual quirks. I was able to fix the issue and make it look the same in all browsers by modifying the CSS on line 31 setting the button width to 59pxrather than 60px.

button {
  background: none;
  border: 0px;
  color: #888;
  font-size: 15px;
  width: 59px;
  margin: 10px 0 0;
  font-family: Lato, sans-serif;
  cursor: pointer;
}

Regards
Andrew

Thanks Andrew! Appreciate you looking into the issue :)

doesnt worrk at all >:(

Craig Watson
Craig Watson
27,930 Points

Hi Dan, I have the completed js file if you want me to give you that to compare and see where you may have gone wrong ?

Let me know :)

Craig

That would be nice to see it for comparison, so I don't have to start and stop the video a billion times to see where I went wrong.

Craig Watson
Craig Watson
27,930 Points

Here you go Dan:

//Problem: User interaction doesn't provide desired results.
//Solution: Add interactivty so the user can manage daily tasks.

var taskInput = document.getElementById("new-task"); //new-task
var addButton = document.getElementsByTagName("button")[0]; //first button
var incompleteTasksHolder = document.getElementById("incomplete-tasks"); //incomplete-tasks
var completedTasksHolder= document.getElementById("completed-tasks"); //completed-tasks

//New Task List Item
var createNewTaskElement = function(taskString) {
  //Create List Item
  var listItem = document.createElement("li");

  //input (checkbox)
  var checkBox = document.createElement("input"); // checkbox
  //label
  var label = document.createElement("label");
  //input (text)
  var editInput = document.createElement("input"); // text
  //button.edit
  var editButton = document.createElement("button");
  //button.delete
  var deleteButton = document.createElement("button");

  //Each element needs modifying

  checkBox.type = "checkbox";
  editInput.type = "text";

  editButton.innerText = "Edit";
  editButton.className = "edit";
  deleteButton.innerText = "Delete";
  deleteButton.className = "delete";

  label.innerText = taskString;

  //Each element needs appending
  listItem.appendChild(checkBox);
  listItem.appendChild(label);
  listItem.appendChild(editInput);
  listItem.appendChild(editButton);
  listItem.appendChild(deleteButton);

  return listItem;
}

//Add a new task
var addTask = function() {
  console.log("Add task...");
  //Create a new list item with the text from #new-task:
  var listItem = createNewTaskElement(taskInput.value);
  //Append listItem to incompleteTasksHolder
  incompleteTasksHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);

  taskInput.value = "";
}

//Edit an existing task
var editTask = function() {
  console.log("Edit task...");

  var listItem = this.parentNode;

  var editInput = listItem.querySelector("input[type=text");
  var label = listItem.querySelector("label");

  var containsClass = listItem.classList.contains("editMode");

  //if the class of the parent is .editMode
  if(containsClass) {
    //Switch from .editMode
    //label text become the input's value
    label.innerText = editInput.value;
  } else {
    //Switch to .editMode
    //input value becomes the label's text
    editInput.value = label.innerText;
  }

  //Toggle .editMode on the list item
  listItem.classList.toggle("editMode");

}

//Delete an existing task
var deleteTask = function() {
  console.log("Delete task...");
  var listItem = this.parentNode;
  var ul = listItem.parentNode;

  //Remove the parent list item from the ul
  ul.removeChild(listItem);
}

//Mark a task as complete
var taskCompleted = function() {
  console.log("Task complete...");
  //Append the task list item to the #completed-tasks
  var listItem = this.parentNode;
  completedTasksHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskIncomplete);
}

//Mark a task as incomplete
var taskIncomplete = function() {
  console.log("Task incomplete...");
  //Append the task list item to the #incomplete-tasks
  var listItem = this.parentNode;
  incompleteTasksHolder.appendChild(listItem);
  bindTaskEvents(listItem, taskCompleted);
}

var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
  console.log("Bind list item events");
  //select taskListItem's children
  var checkBox = taskListItem.querySelector("input[type=checkbox]");
  var editButton = taskListItem.querySelector("button.edit");
  var deleteButton = taskListItem.querySelector("button.delete");

  //bind editTask to edit button
  editButton.onclick = editTask;

  //bind deleteTask to delete button
  deleteButton.onclick = deleteTask;

  //bind checkBoxEventHandler to checkbox
  checkBox.onchange = checkBoxEventHandler;
}

var ajaxRequest = function() {
  console.log("AJAX request");
}

//Set the click handler to the addTask function
addButton.addEventListener("click", addTask);
addButton.addEventListener("click", ajaxRequest);

//cycle over incompleteTasksHolder ul list items
for(var i = 0; i < incompleteTasksHolder.children.length; i++) {
  //bind events to list item's children (taskCompleted)
  bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}

//cycle over completedTasksHolder ul list items
for(var i = 0; i < completedTasksHolder.children.length; i++) {
  //bind events to list item's children (taskIncomplete)
  bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}

No copying and pasting the full code mind lol :)

Hope you get it going! Craig

I'd be curious to know whether you found an answer to your problem, Dan. As I'm having the same issue but can't spot the error. Would appreciate it if you could share :)

Actually, I thought maybe it was a browser issue, so I copied and pasted your code into my Workspaces to see if the buttons would render properly. Turns out they don't, even with your code, Craig. Wonder if anyone has any ideas.

I never found the answer :( - I just moved on. It ended up not looking terrible, but I looked at that code over and over and never figured it out. Sorry, Rich.

Thanks, Dan. To be clear, did you try running all of Craig's code? Because when I did, the button/formatting issue is still there. Which seems to me to be one of the most confusing things.

I did try running the entire code and had the same button issues.

Viktor Yakov
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Viktor Yakov
Front End Web Development Techdegree Graduate 15,770 Points

Hello, guys. I had the same problem and I figured it out only on (Chrome). My solution (it's working) is :

In "app.js" under "var listItem" , I added a class to "listItem.classList.add(list);". Now our newly created "li" has it's own class, I changed the float of ".list input { float: none; margin: 3px;}" in style.css . Now my input boxes are lined horizontally. Hope that this will work for you. Happy codding ;).

Parker Brown
Parker Brown
24,308 Points

That patch did the trick Viktor Yakov, thank you!