【问题标题】:How to make the checkbox working properly in following scenario?如何使复选框在以下情况下正常工作?
【发布时间】:2013-09-04 11:45:57
【问题描述】:

我的网站使用 PHP、Smarty 和 jQuery。在一个聪明的模板中,我正在处理几个复选框。以下是我关于复选框的聪明代码 sn-p 供您参考。

<table cellpadding="5" cellspacing="0" border="0" id="groups_listing" style="{if $data.show_group=='on'}display:{else}display:none;{/if}">
     <tr>
     {if $all_groups}
     {assign var='i' value=0}
     {foreach from=$all_groups item="group"}
       {if $i%4 == 0}</tr><tr>{/if}
         <td valign="top" align="left" width="200">
           <table cellpadding="5" cellspacing="0" border="0">
             <tr>
               <td>
               <input type="checkbox" name="parent_groups[]" id="{$group.parent_id}" id="{$group.parent_id}" onchange="check_subgroups(this.id, 'class_{$group.parent_id}');" value="{$group.parent_id}" {foreach from=$user_groups item=user_grp} {if $user_grp== $group.parent_id} checked="checked" {/if}{/foreach}>
               <label><strong>{$group.parent_name} </strong></label>
               <input type="hidden" name="main_groups[]" id="main_groups[]" value="{$group.parent_id}">
               </td>
             </tr>                       
             {foreach from=$group.subgroups item=subgroup}
             <tr>
               <td>
               <input type="checkbox" name="groups_{$group.parent_id}[]" class="class_{$group.parent_id}" onchange="uncheck_main_group('{$group.parent_id}'); return false;" value="{$subgroup.group_id}" style="margin-left:20px;" {foreach from=$user_groups item=user_grp} {$user_grp} {if $user_grp==$subgroup.group_id} checked="checked" {/if}{/foreach}> <label>{$subgroup.group_name}</label>
               </td>
             </tr>
             {/foreach}
           </table>  
           {assign var='i' value=$i+1}
         {/foreach}
       {/if}
    </td>
  </tr>
  </table>

javascript函数如下:

function show_groups(check_box_id) 
{
    if ($(check_box_id).is(':checked')) {

        $('#groups_listing').show();

        } else {

        $('#groups_listing').hide();
        }
}

function check_subgroups(parent_id, class_name) { 
        var chk = document.getElementById(parent_id).checked;
        if(chk == true) 
            $('.'+jQuery.trim(class_name)).attr('checked', true);
        else
            $('.'+jQuery.trim(class_name)).attr('checked', false);
    }

第一个名为 show_groups() 的 javascript 函数运行良好,没有问题。我的问题在于名为 check_subgroups() 的第二个函数。它最初在页面加载后也可以正常工作,但后来如果我取消选中并再次检查父复选框,它就不起作用了。此外,当我检查所有子复选框时,预计父子框应自动被选中,反之亦然。这在当前情况下不起作用。你能帮我实现这个功能吗?供您参考,我附上了带有此问题的复选框的屏幕截图。您可以在问题中看到我已检查父 Course 下的所有子复选框,但父复选框未自动检查。提前致谢。

【问题讨论】:

  • Use prop 在处理检查状态时代替 attr。该链接解释更多。当然,这可能不是问题的根源。

标签: php javascript jquery html checkbox


【解决方案1】:

我希望您不介意,但我创建了一个 jsFiddle Abstraction 以确保所有被检查的子级都将父级切换为已检查,而不是完全修改您的代码以让您了解可能使用的一种方法。

<div class="parentDiv">
    <input type="checkbox" class="parent"/>
    <div class="childGroup">
        <input type="checkbox" class="child"/>
        <input type="checkbox" class="child"/>
        <input type="checkbox" class="child"/>
    </div>
</div>

然后您可以使用此 jQuery 来确保您的父级在子组更改时选择/取消选择。

$('.child').on('change', function () {

    var $parent = $(this).closest('.parentDiv').find('input.parent'),
    $childCheckboxes = $(this).closest('.childGroup').find('.child');

    if ( $childCheckboxes.length === $childCheckboxes.filter(':checked').length ) {
        $parent.prop('checked', true);
    } else {
        $parent.prop('checked', false);
    }

});

toggle all children on parent toggle:

$('.parent').on('change', function () {

    var $children = $(this).closest('.parentDiv').find('.child');

    $children.prop('checked', $(this).is(':checked'));

});

根据您的要求,我已尝试将其放入您的 check_subgroups 函数的上下文中:

function check_subgroups(parent_id, class_name) { 

    $parent = $('#' + parent_id);

    $childCheckboxes = $('.' + $.trim(class_name));

    $childCheckboxes.prop('checked', $parent.is(':checked')); 

}

并在选择所有子项时切换父项:

function uncheck_main_group(parent_id) {

    var $parent = $('#' + parent_id);

    var $children = $('.class_' + $.trim(parent_id));

    if ( $children.length === $children.filter(':checked').length ) {
        $parent.prop('checked', true);   
    } else {
        $parent.prop('checked', false);   
    }

}

【讨论】:

  • 感谢您的回答。它工作正常。但是当我检查父复选框时,它所有相应的子复选框都没有被选中。只有这个问题存在,否则它工作正常。您能否即兴发挥您的解决方案以实现这一目标。
  • 这是答案中最底层的一组javascript,也是我链接到的第二个fiddle
  • 我要求您将您的代码转换为 javascript,以便我可以写入函数函数 check_subgroups(parent_id, class_name)。请问可以转换吗?
  • 明白了,我已经尝试在最后用一个块更新我的答案,但正如答案中提到的 - 如果这不起作用,请用你的代码重新创建一个 jsFiddle,这样我就可以得到任何问题更容易。
  • :非常感谢罗斯。我无话可说谢谢你。您的 javascript 代码运行良好,但反之亦然,即在手动选择子复选框后,父复选框不会自动检查。那么你能相应地修改你的功能代码吗?
【解决方案2】:

代替

$('.'+jQuery.trim(class_name)).attr('checked', false);

使用

$('.'+jQuery.trim(class_name)).removeAttr('checked');

checked 属性的值是什么并不重要。如果它存在,则选中该复选框。

【讨论】:

  • :感谢您的回答,但我认为您没有清楚地了解我的问题。我想在手动检查所有子框后自动检查父复选框,反之亦然。你能帮我实现这个目标吗?
  • 这是选中/取消选中主复选框的代码,当下面的所有复选框都处于相同状态时。 if($('.'+jQuery.trim(class_name)).not(':checked').size() == 0) { $("#"+parent_id).attr('checked', 'checked' ); } else if($('.'+jQuery.trim(class_name)+':checked').size() == 0) { $("#"+parent_id).removeAttr('checked'); }
  • 感谢您的帮助,但无法正常工作。它正在锁定父复选框,因此我无法选中父复选框。
猜你喜欢
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多