开发者

Select all checkboxes JS toggle issue

Hoping someone can help me overcome my Javascript ignorance.

I've got a form that includes checkboxes and I've got a piece of JS that toggles selecting/deselecting all the boxes. And so far, it all works as expected.

The wrench in the works is that I've got multiple groups of checkboxes in this form and I would like to select/deselect by group, not all the checkboxes in the form. This is a sample of the php and html. As you can see, the form is in a table and there is a checkbox in the header row that performs the action. 'resources_req' is the name of the checkbox element in the form

<form method="post" name="add_reservation"> 
<?php for($x=0; $x<count($groups); $x++) : // make seperate display for each group ?>
    <div class="group_<?php echo $group_label; ?>">
    <table class="res">
        <tr>
<!-- form: checkbox all -->
    <?php if($make_res == 'enter') : // adds checkbox to check all ?>
            <th><input type="checkbox"  onClick="toggle(this, 'resources_req[]')" /></th>
    <?php endif; ?>
<!-- end form: checkbox all -->
        </tr>
...
foreach($resources as $resource) { // for each resource/laptop
    $form_start = '<td>';
        $form_start .= '<input type="checkbox" name="resources_req[]" value="'.$resource['id'].'"';
        $form_start .= ' />';
    $form_start .= '</td>';
}
...
    </table>
    </div>
<?php endfor; // loop for each group ?>
<input type="submit" name="add_reservation" value="Make this reservation"  />
</form> 

Here is the JS being called:

function toggle(source, element) {
    checkboxes = document.getElementsByName(element);
    for(var i in checkboxes)
        checkboxes[i].checked = source.checked;
}

Best I can put together, the 'this' in the script call is referring to the form. I thought if maybe I put each of these groups in to their own div class, I could then somehow refer to just that but now I'm just lost. Any help or suggestions appreciated!

EDIT: I asked for suggestions and it's been suggested I post only the html:

<form method="post" name="add_reservation"> 
    <div class="group_A">
        <table>
            <tr>
             开发者_如何学Python   <th><input type="checkbox"  onClick="toggle(this, 'resources_req[]')" /></th>
                <th>Name</th>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="1" /></td>
                <td>John</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="2" /></td>
                <td>Bill</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="3" /></td>
                <td>Fred</td>
            </tr>
        </table>
    </div>
    <div class="group_b">
        <table>
            <tr>
                <th><input type="checkbox"  onClick="toggle(this, 'resources_req[]')" /></th>
                <th>Name</th>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="4" /></td>
                <td>George</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="5" /></td>
                <td>Tom</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="resources_req[]" value="6" /></td>
                <td>Raymons</td>
            </tr>
        </table>
    </div>
    <input type="submit" name="add_reservation" value="Make this reservation"  />
</form> 


I changed a few things:

First, instead of passing the value of name, I'm passing the tagName of 'input' instead.

<input type="checkbox"  onClick="toggle(this, 'input')" />

Then in the toggle() function, I select the parentNode of the source element, and do a getElementsByTagName() so that I only get the input elements in the local div.

Also, I changed the for-in loop to a standard for loop, which is the proper type of loop to iterate over indexed elements. The for-in can actually give some problems.

function toggle(source, element) {
    var checkboxes = source.parentNode.getElementsByTagName(element);
    for (var i = 0; i < checkboxes.length; i++) {
        checkboxes[i].checked = source.checked;
    }
}

Live Example: http://jsfiddle.net/37mT2/


Alternatives:

Instead of parentNode, select the ancestor <div> element by assigning it an ID, and passing it to your toggle() function.

<input type="checkbox"  onClick="toggle(this, 'input', 'someUniqueId_1')" />

<input type="checkbox"  onClick="toggle(this, 'input', 'someUniqueId_2')" />

function toggle(source, element, id) {
    var checkboxes = document.getElementById( id ).getElementsByTagName('input');
    for (var i = 0; i < checkboxes.length; i++) {
        checkboxes[i].checked = source.checked;
    }
}

Or you could traverse up the parent nodes until you reach your first <div> element:

<input type="checkbox"  onClick="toggle(this, 'input')" />

function toggle(source, element) {

    while( source && source = source.parentNode && source.nodeName.toLowerCase() === 'div' ) {
        ; // do nothing because the logic is all in the expression above
    }
    var checkboxes = source.getElementsByTagName('input');

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

Or you could give the <div> elements at that level a common class name and traverse up the parent nodes until you reach that class. In the code below, your <div> elements class is "someClassName":

<input type="checkbox"  onClick="toggle(this, 'input')" />

function toggle(source, element) {

    while( source && source = source.parentNode && source.className === 'someClassName' ) {
        ; // do nothing because the logic is all in the expression above
    }
    var checkboxes = source.getElementsByTagName('input');

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

EDIT: Fixed a typo. I had getElementsById instead of getElementById.


Best I can put together, the 'this' in the script call is referring to the form. I thought if maybe I put each of these groups in to their own div class, I could then somehow refer to just that but now I'm just lost. Any help or suggestions appreciated!

http://jsfiddle.net/JG4uf/

JavaScript Loops: for...in vs for

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜