Mark all checkbox with pure js

Asked

Viewed 662 times

2

I put a Function to mark all checkboxes, in a script that Isac developed in a previous question, but it does not work in conjunction with Function, only in a static html.

function all_check(marcar) {
    var itens = document.getElementsByTagName('checkbox');

    if (marcar) {
        document.getElementById('acao').innerHTML = 'Desmarcar Todos';
    } else {
        document.getElementById('acao').innerHTML = 'Marcar Todos';
    }

    var i = 0;
    for (i = 0; i < itens.length; i++) {
        itens[i].checked = marcar;
    }

}

var json = [{
    nome: 'Pedro',
    data: '13/09/2017'
  },
  {
    nome: 'Lucas',
    data: '13/09/2017'
  },
]

var mydiv = document.getElementById("lista");
mydiv.innerHTML = "";
var ul = document.createElement("ul");
mydiv.appendChild(ul);

var escolhidas = [];
json.forEach(function(obj) {
  var li = document.createElement("li");
  ul.appendChild(li);
  Object.keys(obj).forEach(function(chave) {
    var div = document.createElement("div");
    div.classList.add(chave);
    div.textContent = obj[chave];
    li.appendChild(div);
  });
  var checkbox = document.createElement("input");
  checkbox.type = 'checkbox';
  checkbox.name = 'checkbox';
  checkbox.addEventListener('change', function() {
    this.closest('li').classList.toggle('selecionado', this.checked);
    if (this.checked) escolhidas.push(obj);
    else escolhidas = escolhidas.filter(function(el) {
      return el != obj;
    });
    console.log(escolhidas);
  });
  li.appendChild(checkbox);
});
.selecionado {
  background-color: #efe;
}
<input type="checkbox" onclick="all_check(this.checked);">
                <span id="acao">Marcar</span> <br>

<div id="lista">
</div>

  • 'Cause I can’t thank you when in my post ?

  • Thanking a person is the least you can do, it’s not blah blah, it’s just a few words

  • So read this link to understand why we remove greetings and thanks here

  • I understand, I find it a little "cold" to start without a good day/good night and end without thanking you, but ok.

  • I understand you perfectly, I also questioned it when I came in, but then you understand. And since the site is for "who speaks Portuguese" your "good morning" can be "good afternoon" or "night" for who is reading, anyway, gives a read on the link I sent, he explains better the reasons, alias was this link q helped me to better understand this.

  • I took a look, now gave to understand better, thank you.

Show 1 more comment

1 answer

4


The problem is in getting the elements to mark as checked, here:

function all_check(marcar) {
    var itens = document.getElementsByTagName('checkbox');

He’s trying to get all the tags <checkbox>, but checkboxes are actually tags <input type="checkbox"> so you can’t get them.

Changing this line to:

var itens = document.querySelectorAll('input[type=checkbox]');

It already works, because now get the elements based on a css selector, where if specified labels <input> like checkbox.

To ensure that the array escolhidas is built correctly you need to make some changes. The first is just catch the right checkboxes doing:

var itens = document.querySelectorAll('input[type=checkbox]:not(.todas)');

That picks up all checkboxes except the one with the class todas, not to try to store the corresponding one in the array escolhidas. This implies applying a different class to the checkbox which is to mark all:

<input class="todas" type="checkbox" onclick="all_check(this.checked);">

In order to apply the same logic to mark all and mark each individually I chose to create a function just to do this:

function alterarCheck(checkbox, marcar, objetoJson) {
  if (marcar) {
    checkbox.closest('li').classList.add('selecionado'); //agora com add

    //apenas adiciona ao array se ainda não existir
    if (escolhidas.filter(x => (x.nome == objetoJson.nome && x.data == objetoJson.data)).length == 0) {
      escolhidas.push(objetoJson);
    }
  } else {
    checkbox.closest('li').classList.remove('selecionado'); //agora com remove
    escolhidas = escolhidas.filter(el => el != objetoJson);
  }
}

Now this function will be used in both cases. Note that now instead of toggle the selection class it has to be added with add or removed with remove based on the value of the check. This is because you can manually select the elements and then select them all, even if they were already, which would cause you to deselect the CSS class.

Example:

function alterarCheck(checkbox, marcar, objetoJson) {
  if (marcar) {
    checkbox.closest('li').classList.add('selecionado');
    if (escolhidas.filter(x => (x.nome == objetoJson.nome && x.data == objetoJson.data)).length == 0) {
      escolhidas.push(objetoJson);
    }
  } else {
    checkbox.closest('li').classList.remove('selecionado');
    escolhidas = escolhidas.filter(el => el != objetoJson);
  }
}

function all_check(marcar) {
  const itens = document.querySelectorAll('input[type=checkbox]:not(.todas)');

  if (marcar) {
    document.getElementById('acao').innerHTML = 'Desmarcar Todos';
  } else {
    document.getElementById('acao').innerHTML = 'Marcar Todos';
  }

  for (let i = 0; i < itens.length; i++) {
    itens[i].checked = marcar;
    alterarCheck(itens[i], marcar, json[i]);
  }

  console.log(escolhidas);
}

var json = [{
    nome: 'Pedro',
    data: '13/09/2017'
  },
  {
    nome: 'Lucas',
    data: '13/09/2017'
  },
]

var mydiv = document.getElementById("lista");
mydiv.innerHTML = "";
var ul = document.createElement("ul");
mydiv.appendChild(ul);

var escolhidas = [];
json.forEach(function(obj) {
  var li = document.createElement("li");
  ul.appendChild(li);
  Object.keys(obj).forEach(function(chave) {
    var div = document.createElement("div");
    div.classList.add(chave);
    div.textContent = obj[chave];
    li.appendChild(div);
  });
  var checkbox = document.createElement("input");
  checkbox.type = 'checkbox';
  checkbox.name = 'checkbox';
  checkbox.addEventListener('change', function() {
    //aqui chama agora também o alterarCheck passando os valores necessários
    alterarCheck(checkbox, checkbox.checked, obj);
    console.log(escolhidas);
  });
  li.appendChild(checkbox);
});
.selecionado {
  background-color: #efe;
}
<input class="todas" type="checkbox" onclick="all_check(this.checked);">
<span id="acao">Marcar</span> <br>

<div id="lista">
</div>

Documentation for querySelectorAll

  • It works, but as I do it to have the same effect of clicking one by one, I need you to save the value to an equal array when I click to just one, thanks

  • @Planetwar "same effect of clicking one by one", can elaborate this statement ? I didn’t get it very well

  • In the code of the post when clicking only one it saves the value and changes the background color, at the same time it displays in the console the value of the name marked, now when clicking on mark all does not happen the same.

  • @Planetwar Just seeing this code specifically, because you must be doing something specific that prevents you from considering the correct ones.

  • The code is in the post, click on some checkbox and you will see that the background changes to give the selected effect, and at the same time save the value in an array

  • Okay thanks for the help.

  • I tested with the change you made and put a console log at the end of Return el != obj; });, it saves to the array but the value is empty, and the background is not yet changing to mean it is selected

  • @Planetwar Right, I’ve already edited the answer to accommodate those details you indicated. Confirm you’re as you were supposed to be

Show 3 more comments

Browser other questions tagged

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