【问题标题】:Select all checkboxes JS toggle issue选择所有复选框JS切换问题
【发布时间】:2011-09-19 02:32:54
【问题描述】:

希望有人能帮助我克服对 Javascript 的无知。

我有一个包含复选框的表单,还有一个 JS 可以切换选择/取消选择所有框。到目前为止,一切都按预期进行。

工作中的关键是我在此表单中有多组复选框,我想按组选择/取消选择,而不是表单中的所有复选框。这是 php 和 html 的示例。如您所见,表单位于表格中,并且在标题行中有一个执行操作的复选框。 'resources_req' 是表单中复选框元素的名称

<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> 

这里是被调用的 JS:

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

尽我所能,脚本调用中的“this”指的是表单。我想如果我可以将这些组中的每一个放入他们自己的 div 类中,然后我可以以某种方式引用它,但现在我迷路了。任何帮助或建议表示赞赏!

编辑:我征求建议,有人建议我只发布 html:

<form method="post" name="add_reservation"> 
    <div class="group_A">
        <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="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> 

【问题讨论】:

  • 我不知道其他人的想法,但就我而言,如果我不必尝试将您的 PHP 翻译成 HTML,那么提供帮助会容易得多它呈现。
  • @patrick-dw:听从你的建议;查看帖子编辑
  • 只是一个建议:你可能会发现 jQuery 在做这类事情时非常有用。

标签: javascript html forms


【解决方案1】:

我改变了一些东西:

首先,我没有传递name 的值,而是传递'input'tagName

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

然后在toggle()函数中,我选择source元素的parentNode,并做一个getElementsByTagName(),这样我就只能得到本地div中的input元素。

另外,我将for-in 循环更改为标准for 循环,这是迭代索引元素的正确循环类型。 for-in 实际上会带来一些问题。

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

现场示例: http://jsfiddle.net/37mT2/


替代方案:

代替parentNode,选择祖先&lt;div&gt;元素,为其分配一个ID,并将其传递给您的toggle()函数。

<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;
    }
}

或者你可以遍历父节点直到你到达你的第一个&lt;div&gt;元素:

<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;
    }
}

或者您可以为该级别的&lt;div&gt; 元素指定一个通用类名并向上遍历父节点,直到您到达该类。在下面的代码中,您的 &lt;div&gt; 元素类是“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;
    }
}

编辑:修正了一个错字。我有getElementsById 而不是getElementById

【讨论】:

  • @patrick-dw:非常感谢你的想法——我想这可能是我在不知不觉中寻找的东西。但是我仍然无法使其工作,可能是因为在我过度简化 html 时,我遗漏了表格元素。我会更新它以反映,但我认为 parentNode 正在键入它,而不是本地 div。我可以只命名本地 div 吗?
  • @Stace:是的,您需要为每个本地 &lt;div&gt; 提供一个 ID,并将该 ID 传递给您的 toggle() 函数,然后使用 document.getElementById() 根据其 ID 选择它。 (ID 在页面上必须是唯一的。)另一种方法是向上遍历父节点,直到到达 &lt;div&gt; 元素。只要没有您不想选择的中间&lt;div&gt;,这将起作用。如果有,那么你可以给&lt;div&gt; 一个类,然后寻找它。我将更新这些解决方案中的每一个。
  • @patrick-dw:哇,真快!我刚刚更新了我的帖子以添加表格元素。似乎指定 div 可能是要走的路,而不是向上遍历。在现实世界中,这一切都是在循环中生成的,并且 div 类无论如何都是动态生成的(参见我的代码顶部附近)。谢谢!
  • @Stace:是的,如果您可以在服务器端轻松地为每个人分配一个唯一的 ID,那将是最简单的。我更新了 3 个示例。第一个假设您传递给toggle() 的唯一ID。第二个遍历直到到达div 元素,第三个可能不起作用,因为每个div 上已经有不同的类名。我可以让它工作,但听起来其他两种解决方案之一会更好。
  • @Stace:我修正了一个错字,我拼错了 getElementById 函数名称。
【解决方案2】:

尽我所能,脚本调用中的“this”指的是表单。我想如果我可以将这些组中的每一个放入他们自己的 div 类中,然后我可以以某种方式引用它,但现在我迷路了。任何帮助或建议表示赞赏!

http://jsfiddle.net/JG4uf/

JavaScript Loops: for...in vs for

【讨论】:

    猜你喜欢
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2020-08-28
    相关资源
    最近更新 更多