Jon Wilson
Jon Wilson

Reputation: 776

finding object in Javascript

I have a form with thousands of checkboxes, and when one is checked, I want to check all the boxes below it. This works:

<html>
<body>
<form name="myform">
<input type="checkbox" name="box1" onClick="redrawboxes(this);">1<br>
<input type="checkbox" name="box2" onClick="redrawboxes(this);">2<br>
...
</form>
</body>
</html>
<script>
function redrawboxes(obj){  
    //check all boxes below 
    var foundit=false;
    for (e=0; e<document.myform.elements.length; e++){
        if (foundit==false){ //search for checked obj
            if(obj == document.myform.elements[e]){ 
                foundit=true;   
            }
        }else{ //continuing below checked box
            if(obj.checked){ //are we checking or unchecking
                    document.myform.elements[e].checked = true;
            }else{
                    document.myform.elements[e].checked = false;
            }
        }
    }
}
</script>

but for more than a few thousand boxes, IE is unacceptably slow. (Firefox works fine.) Is there a better way to find the original box besides iterating through the whole list?

Upvotes: 1

Views: 314

Answers (5)

Svante Svenson
Svante Svenson

Reputation: 12478

Dunno how fast it is, but you could try the jQuery-way, grab jQuery from www.jquery.com and insert the following code on the page:

$(function(){
    $("input:checkbox").click(function(){
        $(this).nextAll("input:checkbox").each(function(){
            this.checked = true;
        });
    });
});

Upvotes: 2

Shog9
Shog9

Reputation: 159708

Both of the jQuery suggestions are pretty good. For DOM wrangling like this, you're really better off using a good library.

And the comment about the dubious wisdom of putting thousands of checkboxes on a form is pretty good as well...

But, on the off-chance that you do have a good reason for doing this, and you can't use jQuery or similar, here's a fast, straight JS method:

function redrawboxes(obj)
{  
    //check all boxes below     
    var next = obj;
    while ( (next = next.nextSibling) )
    {
      if ( next.nodeName.toLowerCase() == "input" 
        && next.type.toLowerCase() == "checkbox" )
        next.checked = obj.checked;
    }
}

tested in FF3, FF3.1, IE6, Chrome 1, Chromium 2

Upvotes: 4

Georg Sch&#246;lly
Georg Sch&#246;lly

Reputation: 126175

You can read out the name of the selected checkbox like this:

function redrawboxes(obj) {
    var name = obj.name;
    var state = obj.checked;

    // get that index
    var index = name.substr(3) * 1; // just to be sure it's a number
    var length = document.myform.elements.length;
    var allElements = document.myform.elements

    // (un)check all elements below
    for (var i = index; i < length; i++) {
        allElements[i].checked = state;
    }
}

You could have sped up your code quite a bit by using local variables and there's an if-statement that can be replaced.

Edit: Actually that one-off-error isn't an error because that specific checkbox was (un)checked by the user himself.

Upvotes: 2

Vincent Robert
Vincent Robert

Reputation: 36150

Advertising inside !

If you are using jQuery, you can try my plugin to make your loop asynchronous, this will allow to run a long loop without freezing the browser.

http://mess.genezys.net/jquery/jquery.async.php

If you don't want to use jQuery, you can download the plugin and modify the code for your own needs, it does not really depend on jQuery.

Upvotes: 2

IAdapter
IAdapter

Reputation: 64885

i might get down voted for this, but try using jquery. it has selectors optimized for that.

Upvotes: 3

Related Questions