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 trialMiguel Rivera
21,679 PointsI changed the textContent from "Confirm" to "Confirmed" when the is checked but the checkbox disappeared.Why?
When the checkbox is checked the textContent change to "Confirmed" but the checkbox disappear. Why does it happens?
Jordan Hoover
Python Web Development Techdegree Graduate 59,268 PointsHey guys,
Believe it has to do with him replacing the entire contents of the label.
Here's the code he's looking at (before his changes):
ul.addEventListener('change', (e) => {
const checkbox = event.target;
const checked = checkbox.checked;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = 'responded';
//the task is to change the label to say 'Confirm' when checked. This can be accessed through listItem
} else {
listItem.className = '';
//the task is to change the label to say 'Confirmed?' when checked. This can be accessed through listItem
}
});
My snapshot here: https://w.trhou.se/euc8gxg663
Hope this helps others who are looking for answers.
2 Answers
Robert Cooper
22,704 PointsAs Alex-Christian Lazau mentioned, you need to target the text node within the label element. You can do this by using the .childNodes[0]
property on the label element. The index of 0 refers to the label's text node in this case.
Here is the code I used for this problem:
ul.addEventListener('change', (e) => {
const checkbox = event.target;
const checked = checkbox.checked;
const label = checkbox.parentNode;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = "responded";
label.childNodes[0].textContent = 'Confirmed';
} else {
listItem.className = "";
label.childNodes[0].textContent = 'Confirm';
}
});
You can read more about the .childNodes
property on MDN.
John Stratton
18,726 PointsI ran into the same problem with the checkbox disappearing when I did this:
ul.addEventListener('change', (e) => {
const checkbox = event.target;
const checked = checkbox.checked;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = 'responded';
listItem.children[1].textContent = 'Confirmed';
} else {
listItem.className = '';
listItem.children[1].textContent = 'Confirm'
}
});
Here is my solution:
...
appendToLi('label', 'textContent', 'Confirm')
.appendChild(createElement('input', 'type', 'checkbox'));
...
ul.addEventListener('change', (e) => {
const checkbox = event.target;
const checked = checkbox.checked;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = 'responded';
listItem.children[1].innerHTML = 'Confirmed<input type="checkbox" checked="checked">';
} else {
listItem.className = '';
listItem.children[1].innerHTML = 'Confirm<input type="checkbox">'
}
});
I added the innerHTML instead of the textContent because the textContent was apparently removing the checkbox.
Also if I tried to use
listItem.children[1].textContent = 'Confirmed<input type="checkbox" checked="checked">';
it simply looked like:
Confirmed<input type="checkbox" checked="checked">
on the page.
Using innerHTML resolved that and fixed the issue for me.
alexlazau
10,930 PointstextContent
replaces the whole content of an element with "text/plain", so every child element is removed.
Typing
listItem.children[1].textContent = 'Confirmed<input type="checkbox" checked="checked">';
renders the string as "text/plain", the HTML isn't encoded, whereas innerHTML
replaces the whole content of an element with "text/html". But be aware that this can lead to security issues and I don't recommend using innerHTML
. Also if the label would contain more elements, you would have to rewrite everything, which is inefficient.
Try instead using something like this:
// Find specific text node that contains a substring
// and replace its content with text
function changeTextNode(node, substring, text) {
for(let i = 0; i < node.childNodes.length; i++) {
let currentNode = node.childNodes[i];
if (currentNode.nodeType == Node.TEXT_NODE &&
currentNode.textContent.indexOf(substring) != -1) {
return currentNode.textContent = text;
}
}
};
This looks over every child node of an element and tests if it's a text node and contains the given substring. Then it replaces the textContent
with text
. You can use it like this:
changeTextNode(listItem.querySelector('label'), 'Confirm', 'Confirmed');
I hope this helps!
John Stratton
18,726 PointsI wish I could upvote your reply! Good information!
Robert Cooper
22,704 PointsAlex-Christian Lazau you nailed it. Thanks for posting that solution as it helped me with the same issue.
Jacob Mishkin
23,118 PointsJacob Mishkin
23,118 PointsWe can not help you without looking at your code. It's as simple as that. Once you posted your code in the forum we will be happy to help.