jeudi 27 avril 2017

Why can I not change the 'checked' status of a checkbox in Javascript?

Intended behaviour

I have a checkbox inside of a div element. I want both the box and the div to be clickable.

  • When the checkbox is clicked by the user, a class is added to the div to change its background colour. This class is then removed if the checkbox is clicked again.
  • When the div itself is clicked, the class with the background colour is added or removed as appropriate and the checkbox is ticked or unticked too

Currently, I have most of this working using plain javascript:

function boxPress(markNumber) {
  var checkbox = "mark" + markNumber;
  var element = document.getElementById(checkbox);
  var markbox = "markbox" + markNumber;
  if (element.getAttribute("checked") == null) {
    element.setAttribute("checked", "true");
    document.getElementById(markbox).classList.add('checked');
  } else {
    element.removeAttribute("checked");
    document.getElementById(markbox).classList.remove('checked');
  }
}
.mark {
  margin-bottom: 5px;
  margin-top: 5px;
  background-color: #FFFFFF;
  border-width: 2px;
  border-radius: 0px 5px 5px 0px;
  border-left-style: solid;
  border-left-width: 10px;
  border-color: lime;
  overflow: auto;
  padding: 2%;
  transition: background-color 0.5s linear 0s;
  cursor: pointer;
}

.checked {
  background-color: #66ff66;
}

.mark:hover {
  background-color: #fffcaf;
}

.checked:hover {
  background-color: #b3ffb3;
}

.flex-container {
  display: -webkit-flex;
  display: flex;
  align-items: center;
  margin: 0px;
  padding: 0px;
}

.flex-mark {
  width: 85%;
  margin: 0px;
}

.flex-tick {
  width: 15%;
  margin: 0px;
  text-align: center;
}

.flex-tick input {
  width: 40px;
  height: 40px;
}
<div class="mark col-12 col-m-6" id="markbox0" onclick="boxPress(0)">
  <div class="flex-container">
    <div class="flex-mark">
      <p>Candidate introduces themself by first name, surname and role</p>
    </div>
    <div class="flex-tick"><input type="checkbox" id="mark0"></div>
  </div>
</div>

This works perfectly, apart from where the user first interacts with the checkbox, then later with the div element.

Steps to reproduce the problem in the above snippet:

  1. Click the div. The background changes and the checkbox is ticked.
  2. Click the div again. The changes are reversed as expected.
  3. Click the checkbox. The background change is applied.
  4. Click the checkbox again. The change is reversed as expected.
  5. Now click the div again. The background changes happen but the checkbox remains unticked

Even more interestingly, the HTML of the checkbox reads:

<input type="checkbox" id="mark0" checked="true">

Yet the browser doesn't render the box as checked.

Why is this happening, and why is it only a problem when the div click comes after the box click? It happens in both Chrome and Edge.




Aucun commentaire:

Enregistrer un commentaire