Mark all checkboxes with pure js

2

I put a function to mark all the checkboxes, in a script that Isac has developed in an earlier doubt, but it does not work in conjunction with the 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>
    
asked by anonymous 13.10.2017 / 10:00

1 answer

5

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

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

You are trying to fetch all <checkbox> tags, but the checkboxes are actually <input type="checkbox"> tags that you can not get.

Switching this line to:

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

It already works, because you now get the elements based on a css selector, where you specified <input> tags with type checkbox .

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

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

It picks up all the checkboxes except the class todas , so do not try to save the corresponding option in the escolhidas array. This implies applying a different class to the checkbox that is to mark all:

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

In order to apply the same logic in marking all and marking each one individually, I chose to create a function only 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 must be added with add or removed with remove based on the check value. This is because you can manually select the elements and then select all of them, even if they already exist, 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

    
13.10.2017 / 11:40