Check one, check all Javascript
Ever since getting "ever so involved" with the DOM in the beginning of this year, I've had the aching habit of going through all my old "copy & paste" scripts and rewriting them myself. So, this entry is only a fraction of the outcome of what has been happening to me thus far.The Scenario
A form with tabularized items generated from a database. Each item has a checkbox in it's particular row holding an array name for its name attribute and a unique ID for its value. At the top of the form is a stand-alone checkbox which triggers a "check all - check none" event. To top it all off, we need some server side action goin’ on to remove the items that are checked.The old way
Before moving ahead I thought it would a good idea to show the previous script which I was borrowing from Invision Power Board. This involved two functions that worked together very nicely. Right about now would be a good time to set the style sheet view to "UnDesigned," and if of course you like to jump ahead to the demo, I'll let you do that.Invisionboard Checkall Functions
//==========================================
// Check All boxes
//==========================================
function CheckAll(fmobj) {
for (var i=0;i<fmobj.elements.length;i++) {
var e = fmobj.elements[i];
if ( (e.name != 'allbox') && (e.type=='checkbox') && (!e.disabled) ) {
e.checked = fmobj.allbox.checked;
}
}
}
//==========================================
// Check all or uncheck all?
//==========================================
function CheckCheckAll(fmobj) {
var TotalBoxes = 0;
var TotalOn = 0;
for (var i=0;i<fmobj.elements.length;i++) {
var e = fmobj.elements[i];
if ((e.name != 'allbox') && (e.type=='checkbox')) {
TotalBoxes++;
if (e.checked) {
TotalOn++;
}
}
}
if (TotalBoxes==TotalOn) {
fmobj.allbox.checked=true;
}
else {
fmobj.allbox.checked=false;
}
}
Okay, so as you can see, it really isn't all that bad. A solid group of functions. One for the checkAll, and one for the body of generated items.
Here is how I revised it, or better yet, came up with by the best of my ability.
Revised CheckAll Function
function checkAll(ref) {
var chkAll = document.getElementById('checkAll');
var checks = document.getElementsByName('del[]');
var removeButton = document.getElementById('removeChecked');
var boxLength = checks.length;
var allChecked = false;
var totalChecked = 0;
if ( ref == 1 ) {
if ( chkAll.checked == true ) {
for ( i=0; i < boxLength; i++ ) {
checks[i].checked = true;
}
}
else {
for ( i=0; i < boxLength; i++ ) {
checks[i].checked = false;
}
}
}
else {
for ( i=0; i < boxLength; i++ ) {
if ( checks[i].checked == true ) {
allChecked = true;
continue;
}
else {
allChecked = false;
break;
}
}
if ( allChecked == true ) {
chkAll.checked = true;
}
else {
chkAll.checked = false;
}
}
for ( j=0; j < boxLength; j++ ) {
if ( checks[j].checked == true ) {
totalChecked++;
}
}
removeButton.value = "Remove ["+totalChecked+"] Selected";
}
Basically, I combined both functions into one with the only difference being a number that gets passed into the function as an argument. For the main checkAll checkNone button (at the top or bottom of your form), you pass in the number "1", and for everything else, you could pass in whatever you want, as long as it's not 1. Preferably something like "2" would suffice.
You'll also notice in my nifty function that I added a "Remove totalChecked Selected" feature which displays the amount of checked boxes. I suppose if you wanted you could add in another conditional statement which asks if they're all checked and display "Remove All" instead of displaying a number.
Removing Records with PHP
This part I knew I could definitely improve on. Previously, without the flexibility of putting in unique values for the value="" attribute, this is how I managed to get them out of the database.PHP Drop Record Database call
<?php
if ( isset($_POST['remove_selected']) ) {
$q = mysql_query('select id from table');
while ( $r = mysql_fetch_array($q) ) {
$message_id = 'msgid_'.$r['id'];
if ( $$message_id == "yes" ) {
$del_id = $r['id'];
$drop_sql = mysql_query(
"DELETE FROM table
WHERE id = '$del_id'
LIMIT 1");
if ( ! @$drop_sql ) {
die ('Unable to Execute the drop query '.mysql_error());
}
}
}
}
?>
Boy that's ugly. Notice the second mysql_query() encapsulated within the while() loop. Mhmm, not good. Anytime you're running loops that send off queries is a potential cause for a database disaster. If you had 50 items to delete, then count on 50 queries being sent to the database server. Fortunately in my case I've never had to delete so many items at once. However even 5 queries is too much...and dare I say, even 2 is too much.
The case is IN
With the javascript now being able to intake the database ID's directly into the value attribute of the checkbox, we can now rewrite our drop script as follows:Using the SQL 'IN' clause to run faster queries
<?php
if ( isset($_POST['remove_selected']) ) {
$postCount = count($_POST['delAnn']);
for ( $i=0; $i < $postCount; $i++ ) {
$deleteIds .= $_POST['del'][$i].',';
}
$deleteIds = rtrim($deleteIds,',');
mysql_query('delete from table where id in ('.$deleteIds.')');
}
?>
Yep. It really is that easy. Not that you've already been doing this already. Sometimes I just tend to be a little behind the times. I used to think the longer and more complicated the script was, the better programmer I would be reveered for. *Cough B.S.*
With the above function, all you're doing is gathering the ids, storing them in a comma delimitted string (not array), remove the last comma with rtrim(), then using mysql's keyword "IN" to delete specific id's.
With all this said and done, view the JS CheckAll demo to play around with yourself.
recent
- Matador: The Obvious MVC Framework for Node
- Sandboxing JavaScript
- Crouching Ender, hidden command
- Ender.js - The open submodule library
- Qwery - The Tiny Selector Engine
- Klass
- Smallest DOMReady code, ever.
- $script.js - Another JavaScript loader
- About that slowness on Twitter...
- Autocomplete Fuzzy Matching
- JavaScript Cache Provider
- JavaScript Animate
- Asynchronous method queue chaining in JavaScript
- Something changed
- Unofficial Twitter Widget Documentation
i am dustin diaz

