2017-09-07 8 views
1

私はCheetahテンプレートでダイナミックチェックボックスのセットを作成しています(これはPython辞書を使って作成しています)。動的な作成時のチェックボックスの不確定プロパティをHTMLで動的に設定する

jQueryのonChange関数を関連付けることによって、これらのチェックボックスのトライステート動作をエミュレートしました。ページが読み込まれると正しく動作します。しかし、それはページの最初の読み込みのために働くことができません。例えば、サブグループでチェックボックスが選択されている場合、親は不確定状態に設定されません。同様に、すべてのチェックボックスが選択されている場合、「すべて選択」オプションはチェックされません。

動的作成でこの機能を起動するにはどうすればよいですか?

$(document).ready(function() { 
 
    //jQuery functions to handle all actions for the widget 
 
    //This code handles enabling the checkboxes for children belonging to 
 
    //a particular parent based on the attribute "group". The parent checkbox 
 
    //behavior is emulated for children. 
 
    $('input[type="checkbox"]').on('change', function() { 
 
    if ($(this).attr("group").indexOf("group") >= 0) { 
 
     groupid = $(this).attr("group").split("_")[1] 
 
     if ($(this).is(':checked')) { 
 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
 
      $(this).prop("checked", true); 
 
     }); 
 
     } else { 
 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
 
      $(this).prop("checked", false); 
 
     }); 
 
     } 
 
    } else if ($(this).attr("group").indexOf("child") >= 0) { 
 
     //Implementation for tristate behavior for inner level children list. 
 
     //The parent checkbox's state is changed according to child's state change. 
 
     //It can be one of the following:selected, unselected and indeterminate. 
 
     var checkboxlength = $(this).parent().parent().find(
 
      '.childCheckbox').length, 
 
     checkall2 = $(this).parent().parent().parent().find('.parent').find(
 
      '.parentCheckbox'), 
 
     selcheckboxlength = $(this).parent().parent().find(
 
      '.childCheckbox:checkbox:checked').length; 
 

 
     checkall2.prop("checked", false); 
 
     checkall2.prop("indeterminate", false); 
 

 
     checkall2.prop("checked", checkboxlength == selcheckboxlength); 
 
     checkall2.prop("indeterminate", checkboxlength != selcheckboxlength && selcheckboxlength > 0); 
 
    } else { 
 
     return; 
 
    } 
 
    
 
    //Handle the tristate behavior for select all function (including parents and children). 
 
    var checkall = $('#select_all'), 
 
     allParentCheckboxlength = $(document).find('input.parentCheckbox') 
 
     .length, 
 
     selParentcheckboxlength = $(document).find(
 
     'input.parentCheckbox:checked').length; 
 
     indetrmntParentlength = $(document).find(
 
     'input.parentCheckbox:indeterminate').length; 
 
     //alert(indetrmntParentlength); 
 
     checkall.prop("checked", false); 
 
     checkall.prop("indeterminate", false); 
 

 
     checkall.prop("checked", allParentCheckboxlength == selParentcheckboxlength); 
 
     checkall.prop("indeterminate", indetrmntParentlength != 0 || allParentCheckboxlength != selParentcheckboxlength && selParentcheckboxlength != 0);   
 
    }); 
 
}); 
 

 
//Expand or collapse the div according to arrow click for children of a particular parent. 
 
$(document).on('click', '.deviceArrow.closedDiv', function() { 
 
    $(this).parent().parent().find(".childContainer").show(); 
 
    $(this).removeClass("closedDiv").addClass('openedDiv'); 
 
}); 
 
$(document).on('click', '.deviceArrow.openedDiv', function() { 
 
    $(this).parent().parent().find(".childContainer").hide(); 
 
    $(this).removeClass("openedDiv").addClass('closedDiv'); 
 
}); 
 

 
//Collapse all collapses all children divs open and displays only parent. 
 
$(document).on('click', '.collapseAll', function() { 
 
    $(document).find(".fileGroupTable").each(function() { 
 
    $(this).find(".childContainer").hide(); 
 
    $(this).find(".parent .deviceArrow").removeClass("openedDiv").addClass(
 
     'closedDiv'); 
 
    }); 
 
}); 
 

 
//Expand all expands children of each parent. 
 
$(document).on('click', '.expandAll', function() { 
 
    $(document).find(".fileGroupTable").each(function() { 
 
    $(this).find(".childContainer").show(); 
 
    $(this).find(".parent .deviceArrow").removeClass("closedDiv").addClass(
 
     'openedDiv'); 
 
    }); 
 
}); 
 

 
//Reset unchecks every checkbox contained in the div. 
 
$(document).on('click', '#reset', function() { 
 
    $('#select_all').prop("checked", false); 
 
    setCheckBoxes(false); 
 
}); 
 

 
//Change parent and children checkbox state if select all is changes. 
 
$(document).on('change', '#select_all', function() { 
 
    if ($(this).prop("checked") == true) { 
 
    setCheckBoxes(true); 
 
    } else if ($(this).prop("checked") == false) { 
 
    setCheckBoxes(false); 
 
    } 
 
}); 
 

 
//Fucntion to set checkboxes (both parent and children) to a value sent in parameter. 
 
function setCheckBoxes(setValue) { 
 
    $('.fileGroupTable').find('.eachFileGroupDiv .childContainer').each(function() { 
 
    $(this).find('input[type=checkbox]').prop("checked", setValue); 
 
    }); 
 
    $('.fileGroupTable').find('.eachFileGroupDiv .parent').each(function() { 
 
    $(this).find('input[type=checkbox]').prop("checked", setValue); 
 
    }); 
 
}
.child, .child1,.child2,.child3{ 
 
\t padding-left: 40px; 
 
} 
 
.parent{ 
 
\t font-weight:bold; 
 
} 
 
.openedDiv::before { 
 
    content: "V"; 
 
    font-weight: bold; 
 

 
} 
 

 
.body{ 
 
\t padding: 20px; 
 
\t margin-left: 10px; \t 
 
} 
 
.closedDiv::before { 
 
    content: ">"; 
 
    display: inline-block; 
 
} 
 
.openedDiv, .closedDiv { 
 
    cursor: pointer; 
 
    margin: 0 4px; 
 
    vertical-align: baseline; 
 
} 
 
.openedDiv, .closedDiv { 
 
    color: #bbbbbb; 
 
    cursor: pointer; 
 
    display: inline-block; 
 
    margin-top: 4px; 
 
    vertical-align: top; 
 
} 
 
.fileGroupActions{ 
 
\t padding:10px; 
 
\t width:440px; 
 
} 
 

 
.fileGroupTable{ 
 
\t padding:10px; 
 
\t height: auto; 
 
\t width:450px; 
 
\t border: 1px solid black; 
 
} 
 

 
.fileGroupActionsSpan{ 
 
\t margin-left: 13px; 
 
} 
 

 
.expandAll{ 
 
\t padding: 5px; 
 
\t margin-left: 45px; 
 
} 
 

 
.collapseAll{ 
 
\t padding: 5px; 
 
} 
 

 
.reset{ 
 
\t float:right; 
 
} 
 
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="body"> 
 
<div id="file_group_actions" class="fileGroupActions"> 
 
\t <span class="fileGroupActionsSpan fileGroupActions"> 
 
\t \t <input type="checkbox" group="none" id="select_all"> Select All 
 
\t \t <a href="javascript:void(0);" class='expandAll'> Expand All</a> 
 
\t \t <a href="javascript:void(0);" class='collapseAll'> Collapse All</a> 
 
\t \t <input type="button" value="Reset" class="reset" id="reset"> 
 
\t </span> 
 
</div> 
 
<div id="file_group_table" class=fileGroupTable> 
 
\t <div class="eachFileGroupDiv"> 
 
\t \t <div class="parent" id="parent_1"> 
 
\t \t \t <i id="test1" class="deviceArrow openedDiv"></i> 
 
\t \t \t <input group="group_1" id="test1" class="parentCheckbox" type="checkbox"> Archived and compressed 
 
\t \t </div> 
 
\t \t <div id="child_container_1" class="childContainer"> 
 
\t \t \t <div class="child1"> 
 
\t \t \t \t <input group="child_1" class="childCheckbox" type="checkbox" checked="true"> jar 
 
\t \t \t </div> 
 
\t \t \t <div class="child1"> 
 
\t \t \t \t <input group="child_1" class="childCheckbox" type="checkbox"> war 
 
\t \t \t </div> 
 
\t \t \t <div class="child1"> 
 
\t \t \t \t <input group="child_1" class="childCheckbox" type="checkbox"> vsi 
 
\t \t \t </div> 
 
\t \t \t <div class="child1"> 
 
\t \t \t \t <input group="child_1" class="childCheckbox" type="checkbox"> msu 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </div> 
 
\t 
 
\t <div class="eachFileGroupDiv"> 
 
\t \t <div id="parent_2" class="parent" > 
 
\t \t \t <i class="deviceArrow openedDiv"></i> 
 
\t \t \t <input group="group_2" class="parentCheckbox" type="checkbox"> Audio and sound 
 
\t \t </div> 
 
\t \t <div id="child_container_2" class="childContainer"> 
 
\t \t \t <div class="child2"> 
 
\t \t \t \t <input group="child_2" class="childCheckbox" type="checkbox"> wpl 
 
\t \t \t </div> 
 
\t \t \t <div class="child2"> 
 
\t \t \t \t <input group="child_2" class="childCheckbox" type="checkbox"> cda 
 
\t \t \t </div> 
 
\t \t \t <div class="child2"> 
 
\t \t \t \t <input group="child_2" class="childCheckbox" type="checkbox"> wma 
 
\t \t \t </div> 
 
\t \t \t <div class="child2"> 
 
\t \t \t \t <input group="child_2" class="childCheckbox" type="checkbox"> snd 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </div> 
 

 
\t <div class="eachFileGroupDiv"> 
 
\t \t <div id="parent_3" class="parent"> 
 
\t \t \t <i class="deviceArrow openedDiv"></i> 
 
\t \t \t <input group="group_3" class="parentCheckbox" type="checkbox"> Backup 
 
\t \t </div> 
 
\t \t <div id="child_container_3" class="childContainer"> 
 
\t \t \t <div class="child3"> 
 
\t \t \t \t <input group="child_3" class="childCheckbox" type="checkbox"> wbcat 
 
\t \t \t </div> 
 
\t \t \t <div class="child3"> 
 
\t \t \t \t <input group="child_3" class="childCheckbox" type="checkbox"> xlk 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </div> 
 
</div> 
 
</div>

JS Fiddle

私は.trigger("change")を使用してみましたが、それはすべてのチェックボックスをリセットします。

答えて

1

を呼び出すことができる関数に-cod。

function myFunction(e) { 
    if ($(e).attr("group").indexOf("group") >= 0) { 
    groupid = $(e).attr("group").split("_")[1] 
    if ($(e).is(':checked')) { 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
     $(e.target).prop("checked", true); 
     }); 
    } else { 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
     $(e).prop("checked", false); 
     }); 
    } 
    } else if ($(e).attr("group").indexOf("child") >= 0) { 
    //Implementation for tristate behavior for inner level children list. 
    //The parent checkbox's state is changed according to child's state change. 
    //It can be one of the following:selected, unselected and indeterminate. 
    var checkboxlength = $(e).parent().parent().find(
     '.childCheckbox').length, 
     checkall2 = $(e).parent().parent().parent().find('.parent').find(
     '.parentCheckbox'), 
     selcheckboxlength = $(e).parent().parent().find(
     '.childCheckbox:checkbox:checked').length; 

    checkall2.prop("checked", false); 
    checkall2.prop("indeterminate", false); 

    checkall2.prop("checked", checkboxlength == selcheckboxlength); 
    checkall2.prop("indeterminate", checkboxlength != selcheckboxlength && selcheckboxlength > 0); 
    } else { 
    return; 
    } 

    //Handle the tristate behavior for select all function (including parents and children). 
    var checkall = $('#select_all'), 
    allParentCheckboxlength = $(document).find('input.parentCheckbox') 
    .length, 
    selParentcheckboxlength = $(document).find(
     'input.parentCheckbox:checked').length; 
    indetrmntParentlength = $(document).find(
    'input.parentCheckbox:indeterminate').length; 
    //alert(indetrmntParentlength); 
    checkall.prop("checked", false); 
    checkall.prop("indeterminate", false); 

    checkall.prop("checked", allParentCheckboxlength == selParentcheckboxlength); 
    checkall.prop("indeterminate", indetrmntParentlength != 0 || allParentCheckboxlength != selParentcheckboxlength && selParentcheckboxlength != 0); 
} 

次に、このようなdocument.readyにこの関数を呼び出す:あなたがしたい場合

$(document).ready(function() { 
    //jQuery functions to handle all actions for the widget 
    //This code handles enabling the checkboxes for children belonging to 
    //a particular parent based on the attribute "group". The parent checkbox 
    //behavior is emulated for children. 
    $('input[type="checkbox"]:checked').each(function(i, e){ 
    console.log(e) 
    myFunction(e); 
    }) 

    $('input[type="checkbox"]').on('change', function() { 
    myFunction(this); 
    }) 

}); 

今、あなたはあなたの関数を再利用することができます。ここに更新されたリンクへのリンクがありますJSFiddle

+0

私のために働いた!どうもありがとうございます。 – cisnik

+0

あなたは大歓迎です! – Zorken17

+0

マイナーなバグがありました。内部リストの子供の選択は機能しませんでした。更新された[JSFIDDLE](https://jsfiddle.net/u57k1sto/6/) – cisnik

1

ロジックを処理するために設定した関数を使用してください。これを行う1つの方法は、チェックされた各入力に対して2回のクリックだけをトリガすることです。より良い方法は、おそらく単にクラスまたはデータ属性を使用していずれかの入力をクリックしてトリガーする必要がないようにすることです。

ライン54上の例:私は最善の解決策は、 "変更" あなたを抜け出すことだと思いhttps://jsfiddle.net/yrv8v8po/

$(document).ready(function() { 
    //jQuery functions to handle all actions for the widget 
    //This code handles enabling the checkboxes for children belonging to 
    //a particular parent based on the attribute "group". The parent checkbox 
    //behavior is emulated for children. 
    $('input[type="checkbox"]').on('change', function() { 
    if ($(this).attr("group").indexOf("group") >= 0) { 
     groupid = $(this).attr("group").split("_")[1] 
     if ($(this).is(':checked')) { 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
      $(this).prop("checked", true); 
     }); 
     } else { 
     $('.child' + groupid + '> input[type=checkbox]').each(function() { 
      $(this).prop("checked", false); 
     }); 
     } 
    } else if ($(this).attr("group").indexOf("child") >= 0) { 
     //Implementation for tristate behavior for inner level children list. 
     //The parent checkbox's state is changed according to child's state change. 
     //It can be one of the following:selected, unselected and indeterminate. 
     var checkboxlength = $(this).parent().parent().find(
      '.childCheckbox').length, 
     checkall2 = $(this).parent().parent().parent().find('.parent').find(
      '.parentCheckbox'), 
     selcheckboxlength = $(this).parent().parent().find(
      '.childCheckbox:checkbox:checked').length; 

     checkall2.prop("checked", false); 
     checkall2.prop("indeterminate", false); 

     checkall2.prop("checked", checkboxlength == selcheckboxlength); 
     checkall2.prop("indeterminate", checkboxlength != selcheckboxlength && selcheckboxlength > 0); 
    } else { 
     return; 
    } 

    //Handle the tristate behavior for select all function (including parents and children). 
    var checkall = $('#select_all'), 
     allParentCheckboxlength = $(document).find('input.parentCheckbox') 
     .length, 
     selParentcheckboxlength = $(document).find(
     'input.parentCheckbox:checked').length; 
     indetrmntParentlength = $(document).find(
     'input.parentCheckbox:indeterminate').length; 
     //alert(indetrmntParentlength); 
     checkall.prop("checked", false); 
     checkall.prop("indeterminate", false); 

     checkall.prop("checked", allParentCheckboxlength == selParentcheckboxlength); 
     checkall.prop("indeterminate", indetrmntParentlength != 0 || allParentCheckboxlength != selParentcheckboxlength && selParentcheckboxlength != 0);   
    }); 

    $('.childCheckbox').each(function() { 
    if ($(this).prop('checked') === true) { 
     $(this).trigger('click') 
     $(this).trigger('click') 
    } 
    }); 
}); 

//Expand or collapse the div according to arrow click for children of a particular parent. 
$(document).on('click', '.deviceArrow.closedDiv', function() { 
    $(this).parent().parent().find(".childContainer").show(); 
    $(this).removeClass("closedDiv").addClass('openedDiv'); 
}); 
$(document).on('click', '.deviceArrow.openedDiv', function() { 
    $(this).parent().parent().find(".childContainer").hide(); 
    $(this).removeClass("openedDiv").addClass('closedDiv'); 
}); 

//Collapse all collapses all children divs open and displays only parent. 
$(document).on('click', '.collapseAll', function() { 
    $(document).find(".fileGroupTable").each(function() { 
    $(this).find(".childContainer").hide(); 
    $(this).find(".parent .deviceArrow").removeClass("openedDiv").addClass(
     'closedDiv'); 
    }); 
}); 

//Expand all expands children of each parent. 
$(document).on('click', '.expandAll', function() { 
    $(document).find(".fileGroupTable").each(function() { 
    $(this).find(".childContainer").show(); 
    $(this).find(".parent .deviceArrow").removeClass("closedDiv").addClass(
     'openedDiv'); 
    }); 
}); 

//Reset unchecks every checkbox contained in the div. 
$(document).on('click', '#reset', function() { 
    $('#select_all').prop("checked", false); 
    setCheckBoxes(false); 
}); 

//Change parent and children checkbox state if select all is changes. 
$(document).on('change', '#select_all', function() { 
    if ($(this).prop("checked") == true) { 
    setCheckBoxes(true); 
    } else if ($(this).prop("checked") == false) { 
    setCheckBoxes(false); 
    } 
}); 

//Fucntion to set checkboxes (both parent and children) to a value sent in parameter. 
function setCheckBoxes(setValue) { 
    $('.fileGroupTable').find('.eachFileGroupDiv .childContainer').each(function() { 
    $(this).find('input[type=checkbox]').prop("checked", setValue); 
    }); 
    $('.fileGroupTable').find('.eachFileGroupDiv .parent').each(function() { 
    $(this).find('input[type=checkbox]').prop("checked", setValue); 
    }); 
} 
.child, .child1,.child2,.child3{ 
    padding-left: 40px; 
} 
.parent{ 
    font-weight:bold; 
} 
.openedDiv::before { 
    content: "V"; 
    font-weight: bold; 

} 

.body{ 
    padding: 20px; 
    margin-left: 10px; 
} 
.closedDiv::before { 
    content: ">"; 
    display: inline-block; 
} 
.openedDiv, .closedDiv { 
    cursor: pointer; 
    margin: 0 4px; 
    vertical-align: baseline; 
} 
.openedDiv, .closedDiv { 
    color: #bbbbbb; 
    cursor: pointer; 
    display: inline-block; 
    margin-top: 4px; 
    vertical-align: top; 
} 
.fileGroupActions{ 
    padding:10px; 
    width:440px; 
} 

.fileGroupTable{ 
    padding:10px; 
    height: auto; 
    width:450px; 
    border: 1px solid black; 
} 

.fileGroupActionsSpan{ 
    margin-left: 13px; 
} 

.expandAll{ 
    padding: 5px; 
    margin-left: 45px; 
} 

.collapseAll{ 
    padding: 5px; 
} 

.reset{ 
    float:right; 
} 
</style> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="body"> 
<div id="file_group_actions" class="fileGroupActions"> 
    <span class="fileGroupActionsSpan fileGroupActions"> 
     <input type="checkbox" group="none" id="select_all"> Select All 
     <a href="javascript:void(0);" class='expandAll'> Expand All</a> 
     <a href="javascript:void(0);" class='collapseAll'> Collapse All</a> 
     <input type="button" value="Reset" class="reset" id="reset"> 
    </span> 
</div> 
<div id="file_group_table" class=fileGroupTable> 
    <div class="eachFileGroupDiv"> 
     <div class="parent" id="parent_1"> 
      <i id="test1" class="deviceArrow openedDiv"></i> 
      <input group="group_1" id="test1" class="parentCheckbox" type="checkbox"> Archived and compressed 
     </div> 
     <div id="child_container_1" class="childContainer"> 
      <div class="child1"> 
       <input group="child_1" class="childCheckbox" type="checkbox" checked="true"> jar 
      </div> 
      <div class="child1"> 
       <input group="child_1" class="childCheckbox" type="checkbox"> war 
      </div> 
      <div class="child1"> 
       <input group="child_1" class="childCheckbox" type="checkbox"> vsi 
      </div> 
      <div class="child1"> 
       <input group="child_1" class="childCheckbox" type="checkbox"> msu 
      </div> 
     </div> 
    </div> 

    <div class="eachFileGroupDiv"> 
     <div id="parent_2" class="parent" > 
      <i class="deviceArrow openedDiv"></i> 
      <input group="group_2" class="parentCheckbox" type="checkbox"> Audio and sound 
     </div> 
     <div id="child_container_2" class="childContainer"> 
      <div class="child2"> 
       <input group="child_2" class="childCheckbox" type="checkbox"> wpl 
      </div> 
      <div class="child2"> 
       <input group="child_2" class="childCheckbox" type="checkbox"> cda 
      </div> 
      <div class="child2"> 
       <input group="child_2" class="childCheckbox" type="checkbox"> wma 
      </div> 
      <div class="child2"> 
       <input group="child_2" class="childCheckbox" type="checkbox"> snd 
      </div> 
     </div> 
    </div> 

    <div class="eachFileGroupDiv"> 
     <div id="parent_3" class="parent"> 
      <i class="deviceArrow openedDiv"></i> 
      <input group="group_3" class="parentCheckbox" type="checkbox"> Backup 
     </div> 
     <div id="child_container_3" class="childContainer"> 
      <div class="child3"> 
       <input group="child_3" class="childCheckbox" type="checkbox"> wbcat 
      </div> 
      <div class="child3"> 
       <input group="child_3" class="childCheckbox" type="checkbox"> xlk 
      </div> 
     </div> 
    </div> 
</div> 
</div> 
+0

この解決策は私にとっても役立ちました。ありがとうございました。 @ Zorken17の答えは、よりクリーンで、私の現在の実装に近いので、受け入れました。 – cisnik

関連する問題