如果在Jquery手风琴中选中所有复选框,则更改h3 bg

时间:2016-05-13 16:18:15

标签: jquery css3 accordion

我已经仔细阅读了许多其他问题,没有什么比这个问题更重要了。我有一个Jquery手风琴,有5个标签。每个选项卡内有几个复选框,如果选中了所有复选框,我需要div顶部的h3来改变颜色。因此,当它折叠时,用户可以轻松识别哪些标签仍然需要注意。

我尝试过的当前Jquery是

function changeH3(){
$('h3').on('click',function(){
    var boxes = $('.checkbox[type="checkbox"]');
    if ( boxes.length === boxes.filter(':checked').length ) {
        $(this).closest('h3')
        .toggleClass('bg-warning')
        .toggleClass('bg-success'); 

    }
});
}

如果它刚刚发生而不是需要onclick会更好。

顶部面板看起来像这样,其余部分几乎相同。它的所有Bootstrap CSS

 <div id= "acc1" >
   <form role="form" action="run.php" method="post" name='details'>

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="1"   onClick="checkval(this)" <?php echo $boxes[1] ? 'checked = "checked"' : '' ?>>Inspected 
     </fieldset>  

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="2" onClick="checkval(this)"<?php echo $boxes[2] ? 'checked = "checked"' : '' ?>>All 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="3" onClick="checkval(this)"<?php echo $boxes[3] ? 'checked = "checked"' : '' ?>>All 
     </fieldset>

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="4" onClick="checkval(this)"<?php echo $boxes[4] ? 'checked = "checked"' : '' ?>>aligns 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="5" onClick="checkval(this)"<?php echo $boxes[5] ? 'checked = "checked"' : '' ?>>and 
     </fieldset>

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="6" onClick="checkval(this)"<?php echo $boxes[6] ? 'checked = "checked"' : '' ?>> match 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="7" onClick="checkval(this)"<?php echo $boxes[7] ? 'checked = "checked"' : '' ?>>free 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="8" onClick="checkval(this)"<?php echo $boxes[8] ? 'checked = "checked"' : '' ?>>Front 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="9" onClick="checkval(this)"<?php echo $boxes[9] ? 'checked = "checked"' : '' ?>>Weather 
     </fieldset> 

     <fieldset class="form-horizontal form-group bg-info">  
        <input type="checkbox" class="box " name="checkBox[]" id="10"  onClick="checkval(this)"<?php echo $boxes[10] ? 'checked = "checked"' : '' ?>>Key 
     </fieldset> 

     <textarea class= "form-control notes" name="notes[]" data-num="1" onChange="getVal(this)" placeholder = "If any of the above items were , etc."><?php echo $notes[1] ? $notes[1] : '' ?></textarea>

</div> 

2 个答案:

答案 0 :(得分:1)

我会考虑在复选框的点击中触发此操作。点击后,您可以横向选中复选框的父容器,然后从中选择所有复选框。检查选择器.length将给出该面板中总共有多少个复选框。然后,选中以下所有复选框:已选中。比较两个.length结果,您可以确定h3是否需要更改类。

$('input[type="checkbox"]').click(function (event) {
  $target = $(this);
  $parent = $target.closest('.panel') // this selector may be incorrect
  $h3 = $target.find('h3');
  $checkboxes = $parent.find('input[type="checkbox"]');
  $checked = $parent.find('input[type="checkbox"]:checked');

 if ($checked.length == $checkboxes.length) {
    $h3.addClass('bg-success'); 
    $h3.removeClass('bg-warning'); 
  } else {
   $h3.removeClass('bg-success'); 
   $h3.addClass('bg-warning');
  }
});

答案 1 :(得分:1)

我建议采用以下方法:

&#13;
&#13;
// caching the <input> elements of 'type=checkbox':
var checkboxes = $('input[type=checkbox]');

// binding the anonymous function of the on() method as the
// change event-handler:
checkboxes.on('change', function() {

  // checking that the length of the checboxes collection is
  // equal to the length of checked checkboxes:
  let check = checkboxes.length === checkboxes.filter(':checked').length;

  // finding the closest ancestor <div> from amongs the ancestors of
  // the changed check-box element, and finding its direct child(ren)
  // <h3> elements (ideally a more specific selector should be used,
  // such as a class, id or data-* attribute):
  $(this).closest('div').find('>h3')
    // removing both the 'bg-warning' and 'bg-success'
    // classes from that <h3>
    .removeClass('bg-warning bg-success')
    // using a ternary conditional operator to
    // add the 'bg-success' class (if the check is true/truthy)
    // or the 'bg-warning' class (if the check is false/falsey):
    .addClass(check ? 'bg-success' : 'bg-warning');
  // triggering the change event - and thereby causing the change
  // event-handler to fire - on page-load/document-ready:
}).change();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div id="acc1">
  <h3>
  &lt;h3&gt; tag, for demo purposes (omitted from question's) HTML
</h3>
  <form role="form" action="run.php" method="post" name='details'>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="1" />Inspected
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="2" />All
    </fieldset>

    <!-- note that, here, I removed an apparent duplicate 'All' check-box -->

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="4" />aligns
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="5" />and
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="6" />match
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="7" />free
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="8" />Front
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="9" />Weather
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <input type="checkbox" class="box " name="checkBox[]" id="10" />Key
    </fieldset>

    <textarea class="form-control notes" name="notes[]" data-num="1" onChange="getVal(this)" placeholder="If any of the above items were , etc."></textarea>
  </form>
</div>
&#13;
&#13;
&#13;

JS Fiddle demo

此方法将在页面加载/文档就绪时分配正确的类(bg-warning / bg-success)。

顺便提一下,从UI的角度来看,最好将每个<input>的关联文本打包到<label>标记中,或者使用<label>属性关联for

<input id="1" type="checkbox" />
<label for="1">Label for input 1</label>

或简单地将<input>包裹在与其文本相同的<label>中:

<label>
  <input id="1" type="checkbox/>Label for input 1
</label>

这允许用户通过单击其关联文本来更改复选框的状态(这会增加鼠标或触摸交互的有用命中区域):

&#13;
&#13;
// caching the <input> elements of 'type=checkbox':
var checkboxes = $('input[type=checkbox]');

// binding the anonymous function of the on() method as the
// change event-handler:
checkboxes.on('change', function() {

  // checking that the length of the checboxes collection is
  // equal to the length of checked checkboxes:
  let check = checkboxes.length === checkboxes.filter(':checked').length;

  // finding the closest ancestor <div> from amongs the ancestors of
  // the changed check-box element, and finding its direct child(ren)
  // <h3> elements (ideally a more specific selector should be used,
  // such as a class, id or data-* attribute):
  $(this).closest('div').find('>h3')
    // removing both the 'bg-warning' and 'bg-success'
    // classes from that <h3>
    .removeClass('bg-warning bg-success')
    // using a ternary conditional operator to
    // add the 'bg-success' class (if the check is true/truthy)
    // or the 'bg-warning' class (if the check is false/falsey):
    .addClass(check ? 'bg-success' : 'bg-warning');
  // triggering the change event - and thereby causing the change
  // event-handler to fire - on page-load/document-ready:
}).change();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div id="acc1">
  <h3>
  &lt;h3&gt; tag, for demo purposes (omitted from question's) HTML
</h3>
  <form role="form" action="run.php" method="post" name='details'>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="1" />Inspected</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="2" />All</label>
    </fieldset>

    <!-- note that, here, I removed an apparent duplicate 'All' check-box -->

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="4" />aligns</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="5" />and</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="6" />match</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="7" />free</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="8" />Front</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="9" />Weather</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="10" />Key</label>
    </fieldset>
    <textarea class="form-control notes" name="notes[]" data-num="1" placeholder="If any of the above items were , etc."></textarea>
  </form>
</div>
&#13;
&#13;
&#13;

JS Fiddle demo

此外,上面的内容也可以很容易地导出到普通的JavaScript,虽然bootstrap.js确实需要jQuery才能运行,但是如果你不使用bootstrap.js,以及那些希望将来启用此功能的人使用jQuery,以下可能是一个可行的选择:

&#13;
&#13;
// declaring the function to act as the event-handler for the
// change-event; instantiating the opts variable as an Object
// in the event that no opts Object is passed to the function:
function conditionalToggleClass(opts = {}) {

  // defining the default settings for the function:
  let settings = {
    // the default element to style should none be passed-in:
    'targetElement': document.querySelector('body'),
    // the default class if the switch is true/truthy:
    'trueClass': 'success',
    // the default class if the switch is false/falsey:
    'falseClass': 'warning',
    // the default state of the 'switch':
    'switch': true
  };

  // obtaining an Array of keys from the opts Object, using
  // Object.keys(), and iterating over that array of keys using
  // Array.prototype.forEach().
  // Here we use the Arrow syntax to update the settings[key]
  // property value to that held in the opts[key] property-value:
  Object.keys(opts).forEach(key => settings[key] = opts[key]);

  // if we recieve a string in place of a node in the settings.targetElement
  // Object we use document.querySelector() to find the first, if any, matching
  // elements within the document; otherwise we use the node directly:
  let target = 'string' === typeof settings.targetElement ? document.querySelector(settings.targetElement) : settings.targetElement;

  // if the settings.switch is true/truthy we add the settings.trueClass
  // to the node, if it's false/falsey we remove that class:
  target.classList.toggle(settings.trueClass, settings.switch);

  // here we remove the settings.falseClass if the switch is true/truthy
  // by using the ! operator to  invert the switch's state, and add the
  // class if the switch is false:
  target.classList.toggle(settings.falseClass, !settings.switch);
}

// using document.querySelectorAll() to retrieve all <input> elements of
// that type and using Array.from() to convert that nodeList into an Array:
let checkboxes = Array.from(document.querySelectorAll('input[type=checkbox]')),

  // defining a new Event in order to fire that event to
  // set up the background-colour of the <h3> - or associated -
  // element on page-load:
  change = new Event('change');

// iterating over the Array of check-boxes using Array.prototype.forEach()
// to bind the event-handling function with EventTarget.addEventListener();
// to do this we use ES6 Arrow syntax:
checkboxes.forEach(check => check.addEventListener('change', function() {
  // here we call the function, and pass the opts Object:
  conditionalToggleClass({
    // we find the closest ancestor <div> element to the changed
    // node, and then within that node we find the first/only <h3> element
    // (as before the selector should be improved via class or id):
    'targetElement': this.closest('div').querySelector('h3'),

    // we set the class for when the switch is true:
    'trueClass': 'bg-success',
    // and for when the switch is false:
    'falseClass': 'bg-warning',

    // here we pass the switch state itself, by checking that the
    // number of checkboxes is equal to the number of checked check-boxes
    // (using Array.prototype.filter() to retain only the checked check-boxes):
    'switch': checkboxes.length === checkboxes.filter(check => check.checked).length
  });
}));

if (checkboxes.length) {
  checkboxes[0].dispatchEvent(change);
}
&#13;
.success {
  background-color: limegreen;
}
.warning {
  background-color: red;
}
&#13;
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div id="acc1">
  <h3>
  &lt;h3&gt; tag, for demo purposes (omitted from question's) HTML
</h3>
  <form role="form" action="run.php" method="post" name='details'>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="1" />Inspected</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="2" />All</label>
    </fieldset>

    <!-- note that, here, I removed an apparent duplicate 'All' check-box -->

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="4" />aligns</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="5" />and</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="6" />match</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="7" />free</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="8" />Front</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="9" />Weather</label>
    </fieldset>

    <fieldset class="form-horizontal form-group bg-info">
      <label>
        <input type="checkbox" class="box " name="checkBox[]" id="10" />Key</label>
    </fieldset>
    <textarea class="form-control notes" name="notes[]" data-num="1" placeholder="If any of the above items were , etc."></textarea>
  </form>
</div>
&#13;
&#13;
&#13;

JS Fiddle demo

请注意,所有这些方法都使用ES6功能,例如:let,而其他方法(如最后一个)也使用箭头功能Array.from(),以及一些实验性功能,例如Element.closest()找到与给定选择器匹配的最近祖先(然而,这是普通的JavaScript而不是jQuery方法,尽管(几乎)相同的语法和功能)。

参考文献: