mark a checkbox and uncheck the others

3

Depending on the Snippet below, when clicking on a checkbox , the others should be deselected, but only happens if you click them from right to left, if I click them from left to right, nothing happens.

Does anyone know what's going on?

Explanation:

When I select a checkbox , I'll apply an X filter to a Y field. There are already other Radio Button in use, and my upper one wants the checkbox to be used.

var d = document.getElementById('dinheiro');
    var p = document.getElementById('porcentagem');
    var h = document.getElementById('hora');

    function marcaDesmarca() {
        if (d.checked) {
            document.getElementById('porcentagem').checked = false;
            document.getElementById('hora').checked = false;
        } else if (p.checked) {
            document.getElementById('dinheiro').checked = false;
            document.getElementById('hora').checked = false;
        } else if (h.checked) {
            document.getElementById('dinheiro').checked = false;
            document.getElementById('porcentagem').checked = false;
        }
    }
<div style='position: relative;'>
                <input id="dinheiro" name="tipoentrada" type="checkbox" value="D" onclick="marcaDesmarca()"> <label style='display: contents;'>Dinheiro</label>
                <input id="porcentagem" name="tipoentrada" type="checkbox" value="P" onclick="marcaDesmarca()"> <label style='display: contents;'>Porcentagem</label>
                <input id='hora'  name="tipoentrada" type="checkbox" value="H" onclick="marcaDesmarca()"> <label style='display: contents;'>Hora/Minuto</label>
            </div>
    
asked by anonymous 08.06.2017 / 19:48

3 answers

7

He's doing it because that's just what the code tells you to do. The best alternative, as already mentioned, would be to use radio buttons .

Since this is not possible, it follows an alternative that simulates their behavior. Note that it is not necessary to do a lot of code, just know what was the checkbox that triggered the event ( caller ) and uncheck all except it.

I followed your development pattern and as you defined the events directly in HTML, using onclick , I changed the method call to pass as parameter the element that triggered the event ( onclick="marcaDesmarca(this)" ).

function marcaDesmarca(caller) {
  var checks = document.querySelectorAll('input[type="checkbox"]');    
  checks.forEach(c => c.checked = (c == caller) );
}
<div style='position: relative;'>
  <input id="dinheiro" name="tipoentrada" type="checkbox" value="D" 
         onclick="marcaDesmarca(this)"> 
  <label style='display: contents;'>Dinheiro</label>
  <input id="porcentagem" name="tipoentrada" type="checkbox" value="P" 
         onclick="marcaDesmarca(this)">
  <label style='display: contents;'>Porcentagem</label>
  <input id='hora'  name="tipoentrada" type="checkbox" value="H" 
         onclick="marcaDesmarca(this)">
  <label style='display: contents;'>Hora/Minuto</label>
</div>

Version to run in any browser.

function marcaDesmarca(caller) {
  var checks = document.querySelectorAll('input[type="checkbox"]');    
  for(let i = 0; i < checks.length; i++) {
    checks[i].checked = checks[i] == caller;   
  }
}
<div style='position: relative;'>
  <input id="dinheiro" name="tipoentrada" type="checkbox" value="D" 
         onclick="marcaDesmarca(this)"> 
  <label style='display: contents;'>Dinheiro</label>
  <input id="porcentagem" name="tipoentrada" type="checkbox" value="P" 
         onclick="marcaDesmarca(this)">
  <label style='display: contents;'>Porcentagem</label>
  <input id='hora'  name="tipoentrada" type="checkbox" value="H" 
         onclick="marcaDesmarca(this)">
  <label style='display: contents;'>Hora/Minuto</label>
</div>
    
08.06.2017 / 19:58
4

Use <input type="radio"> and change the appearance of the element to look like a checkbox :

input[type='radio']{
  -webkit-appearance: checkbox;
     -moz-appearance: checkbox;
      -ms-appearance: checkbox;
          appearance: checkbox
}
<label for='red'>Vermelho</label>
<input id='red' type='radio' name='selection' checked>

<label for='green'>Verde</label>
<input id='green' type='radio' name='selection'>

<label for='blue'>Azul</label>
<input id='blue' type='radio' name='selection'>

Or changing the appearance of "boxes" with images:

/* Esconde o elemento "padrão" do radiobutton. */
input[type='radio']{
  display: none;
}

/* checkbox ñ marcado */
input[type='radio'] + label::before {
  content: '';
  display: inline-block;
  background: url(https://i.stack.imgur.com/vdAsr.png) no-repeat;
  width: 30px;
  height: 30px;
}

/* checkbox marcado */
input[type='radio']:checked + label::before {
  background: url(https://i.stack.imgur.com/hOuFX.png) no-repeat;
}
<input id='red' type='radio' name='selection'>
<label for='red'>Vermelho</label>

<input id='green' type='radio' name='selection'  checked>
<label for='green'>Verde</label>

<input id='blue' type='radio' name='selection'>
<label for='blue'>Azul</label>
    
09.06.2017 / 15:08
2

I still think it would be better to use radio button , but orders are orders ... Here's an alternative, by setting a checkbox is passed the id of the same per parameter to marcaDesmarca(id) ai adjustment is done through id. The problem with your code is that if checkbox money was checked it would always fall on the first if.

var d = document.getElementById('dinheiro');
var p = document.getElementById('porcentagem');
var h = document.getElementById('hora');

function marcaDesmarca(id) {
  if (id == "dinheiro") {
    document.getElementById('porcentagem').checked = false;
    document.getElementById('hora').checked = false;
  } else if (id == "porcentagem") {
    document.getElementById('dinheiro').checked = false;
    document.getElementById('hora').checked = false;
  } else if (id == "hora") {
    document.getElementById('dinheiro').checked = false;
    document.getElementById('porcentagem').checked = false;
  }
}
<div style='position: relative;'>
  <input id="dinheiro" name="tipoentrada" type="checkbox" value="D" onclick="marcaDesmarca(this.id)"> <label style='display: contents;'>Dinheiro</label>
  <input id="porcentagem" name="tipoentrada" type="checkbox" value="P" onclick="marcaDesmarca(this.id)"> <label style='display: contents;'>Porcentagem</label>
  <input id='hora' name="tipoentrada" type="checkbox" value="H" onclick="marcaDesmarca(this.id)"> <label style='display: contents;'>Hora/Minuto</label>
</div>
    
08.06.2017 / 19:53