0

I'd like to change the value of a label depending on the status of its checkbox

function private() {
  var checkBox = document.getElementById("private");// Get the checkbox
  var text = document.querySelector('label[for="private"]');// Get the output text

  if (checkBox.checked == true)
  {
    text.innerHTML = "Public";
  } else {
    text.innerHTML = "Private";
  }
}
<label class="switch">
  <input id="private" type="checkbox" onclick="private()" />
  <span class="slider"></span>
</label>
<label for="private"></label>

Why doesn't this work?

  • 1
    Does this answer your question? [What do querySelectorAll and getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) – Heretic Monkey Mar 06 '20 at 20:59
  • @HereticMonkey it helps but it doesn't work anyway –  Mar 06 '20 at 21:02

3 Answers3

1

querySelectorAll returns a nodelist, so you need to specify the element you want like:

function private() {
  var checkBox = document.getElementById("private");// Get the checkbox
  var text = document.querySelectorAll('label[for="private"]')[0];// Get the output text

  if (checkBox.checked == true)
  {
    text.innerHTML = "Public";
  } else {
    text.innerHTML = "Private";
  }
}
<label class="switch">
  <input id="private" type="checkbox" onclick="private()" />
  <span class="slider"></span>
</label>
<label for="private"></label>

Or maybe just use querySelector instead which only returns the first match:

function private() {
  var checkBox = document.getElementById("private");// Get the checkbox
  var text = document.querySelector('label[for="private"]');// Get the output text

  if (checkBox.checked == true)
  {
    text.innerHTML = "Public";
  } else {
    text.innerHTML = "Private";
  }
}
<label class="switch">
  <input id="private" type="checkbox" onclick="private()" />
  <span class="slider"></span>
</label>
<label for="private"></label>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • I have done it but nothing changed... Have you modified anything else to make it work? –  Mar 06 '20 at 21:02
  • @Fox Nope, you can see the complete working code examples right in my answer. Have you checked your browser's console for errors? Is that code you posted in your question an accurate and complete representation of your issue? – j08691 Mar 06 '20 at 21:03
  • console says: "private is not a function" –  Mar 06 '20 at 21:04
  • @Fox Sounds like a typo somewhere – j08691 Mar 06 '20 at 21:06
  • of course... but I checked it and there's no typo! Can a function conflict with a *id* name? –  Mar 06 '20 at 21:08
  • @Fox Yes but as you can see from the answers and code examples that's not the case here. Are you using a framework of some kind? – j08691 Mar 06 '20 at 21:09
  • no frameworks... I'm a complete beginner in JS so there shouldn't be strange settings which alter the result –  Mar 06 '20 at 21:11
  • @Fox Is the code you say isn't working much different from what you've posted? – j08691 Mar 06 '20 at 21:12
  • Solved by changing the name of the function with something else... Maybe *private* is a forbidden keyword as used for class members' scope –  Mar 06 '20 at 21:17
1

You need to use querySelector() not querySelectorAll(). By getting all elements, you would have to iterate through the list of items (even though there is only 1).

function private() {
  var checkBox = document.getElementById("private");// Get the checkbox
  var text = document.querySelector('label[for="private"]');// Get the output text

  if (checkBox.checked == true)
  {
    text.innerHTML = "Public";
  } else {
    text.innerHTML = "Private";
  }
}
<label class="switch">
  <input id="private" type="checkbox" onclick="private()" />
  <span class="slider"></span>
</label>
<label for="private"></label>
Jeremy Harris
  • 24,318
  • 13
  • 79
  • 133
  • Then you have some other issue going on. Check your console logs. You can clearly see in the code snippet here that it is functioning. – Jeremy Harris Mar 06 '20 at 21:03
  • it says `Uncaught TypeError: private is not a function at HTMLInputElement.onclick` –  Mar 06 '20 at 21:05
  • @Fox that is unrelated to the question you posted which this correctly answers and it's a dupe to boot. If you have another question, ask another question. – Jared Smith Mar 06 '20 at 21:12
0

There are three things that I would suggest that will solve your problem:

  • Pass the event object to your function. This contains everything about the click event, including what element was clicked on. This means you don't have to scour the DOM.
  • Do not wrap a form control with a label. This is not how labels were intended to work. Instead use something like a section tag.
  • Form controls and their labels are automatically connected when a for attribute is provided. The other can be found through control.labels[0] or label.htmlFor. This is particularly why you want to adhere to the standard of not wrapping controls with labels

With these adjustments, and the addition of a ternary condition statement to determine what text to display, the code will look like this:

<section class="switch">
  <input id="private" type="checkbox" onclick="private(event)" />
  <span class="slider"></span>
</section>

<label for="private"></label>

function private(e) {
  var checkBox = e.currentTarget,
  label = checkBox.labels[0];

  label.textContent = checkBox.checked ? "Public" : "Private";
}

Example:

function private(e) {
  var checkBox = e.currentTarget,
  label = checkBox.labels[0];
  
  label.textContent = checkBox.checked ? "Public" : "Private";
}
<section class="switch">
  <input id="private" type="checkbox" onclick="private(event)" />
  <span class="slider"></span>
</section>

<label for="private"></label>
zfrisch
  • 8,474
  • 1
  • 22
  • 34