Reputation: 8274
I have content being iterated, and then outputted to HTML, from javascript obj data. I am trying to incorporate a check box, that when clicked; will 'select all' or 'check all' of my other checkboxes (these other checkboxes are coming from my JavaScript code, from iterated for loop).
attempt:
function checkAll(checkId){
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox" && inputs[i].id == checkId) {
if(inputs[i].checked == true) {
inputs[i].checked = false ;
} else if (inputs[i].checked == false ) {
inputs[i].checked = true ;
}
}
}
}
JS obj data to the HTML content:
var json =[{
"Name": "zips",
"Type": "Directory",
"DateModified": "6/14/2018 17:22:50",
"Size": "5 KB",
}, {
"Name": "presets",
"Type": "Directory",
"DateModified": "5/11/2018 7:32:10",
"Size": "2 KB",
}, {
"Name": "workflow",
"Type": "Directory",
"DateModified": "6/26/2018 10:29:59",
"Size": "6 KB",
},{
"Name": "software",
"Type": "Directory",
"DateModified": "3/16/2018 10:29:59",
"Size": "16 KB",
},{
"Name": "mmm_data",
"Type": "Directory",
"DateModified": "6/27/2018 1:19:29",
"Size": "3 KB",
},{
"Name": "jobs",
"Type": "Directory",
"DateModified": "4/27/2018 11:59:59",
"Size": "3 KB",
},
];
var string ="";
for (i in json) {
string +='<div class="row"><div class="col-md-15 col-sm-1"><input type="checkbox" name="chk[]"></div><div class="col-md-15 col-sm-4"><span class="folders">'+json[i].Name+'</span></div><div class="col-md-15 col-sm-3"><span class="directory">'+json[i].Type+'</span></div><div class="col-md-15 col-sm-3"><span class="date-stamp">'+json[i].DateModified+'</span></div><div class="col-md-15 col-sm-1"><span class="date-size">'+json[i].Size+'</span></div></div>';
};
document.getElementsByClassName('update-data')[0].innerHTML =string
static HTML:
<div class="data-columns">
<div class="row" id="hd">
<div class="col-md-15 col-sm-1">
<input type="checkbox" onclick="checkAll('chk');" >
</div>
<div class="col-md-15 col-sm-4">
<div id="named" class="sr">Name</div>
</div>
<div class="col-md-15 col-sm-3">
<div id="type" class="sr">Type</div>
</div>
<div class="col-md-15 col-sm-3">
<span id="dated" class="sr">Date Modified</span>
</div>
<div class="col-md-15 col-sm-1">
<span id="size" class="sr">Size</span>
</div>
</div>
<div class="update-data">
</div>
</div>
Upvotes: 1
Views: 6678
Reputation: 178
In your code, you are using inputs[i].id == checkId
to filter your checkboxes. This means only checkboxes with the ID passed in will toggle. However, element ID's must be unique, so this isn't going to work.
Here's what I would do: use a class such as toggleable
that tells your script the box should be changed. You then check for that class on each checkbox when toggling them. Your modified code would look like this:
function checkAll(checkClass){
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox" && inputs[i].classList.contains(checkClass)) {
if(inputs[i].checked == true) {
inputs[i].checked = false ;
} else if (inputs[i].checked == false ) {
inputs[i].checked = true ;
}
}
}
}
You then just need to add the same class to any boxes you want to have be effected, and pass that class name in to your function in place of an id.
Upvotes: 1
Reputation: 4020
There's a few issues in your code :
So, while trying to maintain your logic and existing code, I fixed it by :
inputs[i].id == checkId
condition in your ifFull snippet, except styling :
function checkAll(checkId) {
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].id != checkId) {
if (inputs[i].type == "checkbox") {
if (inputs[i].checked == true) {
inputs[i].checked = false;
} else if (inputs[i].checked == false) {
inputs[i].checked = true;
}
}
}
}
}
var json = [{
"Name": "zips",
"Type": "Directory",
"DateModified": "6/14/2018 17:22:50",
"Size": "5 KB",
}, {
"Name": "presets",
"Type": "Directory",
"DateModified": "5/11/2018 7:32:10",
"Size": "2 KB",
}, {
"Name": "workflow",
"Type": "Directory",
"DateModified": "6/26/2018 10:29:59",
"Size": "6 KB",
}, {
"Name": "software",
"Type": "Directory",
"DateModified": "3/16/2018 10:29:59",
"Size": "16 KB",
}, {
"Name": "mmm_data",
"Type": "Directory",
"DateModified": "6/27/2018 1:19:29",
"Size": "3 KB",
}, {
"Name": "jobs",
"Type": "Directory",
"DateModified": "4/27/2018 11:59:59",
"Size": "3 KB",
}, ];
var string = "";
for (i in json) {
string += '<div class="row"><div class="col-md-15 col-sm-1"><input type="checkbox" name="chk[]"></div><div class="col-md-15 col-sm-4"><span class="folders">' + json[i].Name + '</span></div><div class="col-md-15 col-sm-3"><span class="directory">' + json[i].Type + '</span></div><div class="col-md-15 col-sm-3"><span class="date-stamp">' + json[i].DateModified + '</span></div><div class="col-md-15 col-sm-1"><span class="date-size">' + json[i].Size + '</span></div></div>';
};
document.getElementsByClassName('update-data')[0].innerHTML = string;
<div class="data-columns">
<div class="row" id="hd">
<div class="col-md-15 col-sm-1">
<input type="checkbox" id="chk" onclick="checkAll('chk')" ;>
</div>
<div class="col-md-15 col-sm-4">
<div id="named" class="sr">Name</div>
</div>
<div class="col-md-15 col-sm-3">
<div id="type" class="sr">Type</div>
</div>
<div class="col-md-15 col-sm-3">
<span id="dated" class="sr">Date Modified</span>
</div>
<div class="col-md-15 col-sm-1">
<span id="size" class="sr">Size</span>
</div>
</div>
<div class="update-data">
</div>
</div>
Upvotes: 1
Reputation: 239
Your iteration looks mostly good. However, part of your conditional checks that the input has a specific id. Id's are unique, so at most this could only reach one input. If you remove that part you should be good. Also, this will be buggy if the user has selected one or more boxes before selecting the select all button because all this function does is flip them, so whatever ones they have already checked will be unchecked. I'd do something along the lines of:
function checkAll(checked){ // pass true or false to check or uncheck all
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
inputs[i].checked = checked;
// This way it won't flip flop them and will set them all to the same value which is passed into the function
}
}
}
In summary, your big issue is that you are checking the id in the conditional, and only one element on the page can have that id.
Upvotes: 5