mark a checkbox and uncheck the others

Asked

Viewed 1,889 times

3

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


Does anyone have any idea what’s going on?


Explanation:

When selecting a checkbox, I’ll apply an X filter to a Y field. There are already others Radio Button in use, and my superior wants the checkbox.

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>

  • 6

    If you want to mark only one option, radio button would not be more appropriate?

  • Yes, but I need to use the checkbox!

  • 1

    For what exact reason?

  • My superior’s preference and there are already others radio button in use.

  • 8

    If it’s just a visual matter, use radio and define appearance as checkbox (see a example). This way it’ll look like they’re checkbox, but are radio and function as radio. What your superior requested makes no sense and you should guide him not to do.

  • Thank you Anderson!

  • 3

    "What your superior asked for doesn’t make sense and you should guide him not to." , I even joked in the answer but completely according to this placement of @Andersoncarloswoss.

  • I appreciate the answers and the explanations, they will be very useful for me and others too, but as @Mathias answered first and correctly, I will mark his answer as correct!

  • 2

    The answer is correct, but the approach is not good. Of the three best ideas is @Andersoncarloswoss, for sure.

  • It is the least worse, I would say, because even changing the appearance of one element to another is not recommended because it will generate strangeness in the user or see a checkbox and not being able to dial more than one option. Although this strangeness can be circumvented if the auxiliary text of the field makes it very explicit that it will be allowed to select only one item.

  • 1

    @Andersoncarloswoss you should post as a response to your idea of getting radios look like checkbox. It is the least vulnerable way to bugs, perhaps the only one that will not give headaches in the future.

Show 6 more comments

3 answers

7


He’s doing this because that’s exactly what the code says. 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 make a lot of code, just know which was the checkbox that triggered the event (caller) and cancel everyone except him.

I followed your development pattern and how you set the events directly in HTML, using the 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>

  • 3

    I’m still not used to this notation of es6, Voce can explain what the logic within the foreach? you assign c for c.checked and then compare it to the caller?

  • 2

    I can explain yes, but it has nothing to do with ES6. It’s just a simple boolean assignment. See: the property checked of each element will receive the result of the boolean expression c == caller, caller is always who called the event, ie if the element is the same that called the event, the property checked receives true, otherwise she receives false.

  • 1

    @Rafaelacioly Perhaps surrounding the expression with parentheses makes it more readable.

  • Really your code is very clean and easy to understand, I applied in my code. Excellent!!

  • @LINQ with the parentheses managed to understand better! thanks. but the functions Arrows still do not work in all browsers right? soon it would need to be "compiled".

  • 1

    Only the most modern. But that’s secondary detail in the answer, isn’t it? The code can be changed to checks.forEach(function(c) { c.checked = (c == caller) });

Show 1 more comment

4

Use the <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 by 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>

2

I still think it would be better to use radio button, but orders are orders... Follow an alternative, to mark a checkbox is passed the id of the same by parameter to the marcaDesmarca(id) ai adjustment is done through id. The problem of your code is that if the checkbox money was marked 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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.