How can I shift-select multiple checkboxes like GMail?

后端 未结 13 981
野趣味
野趣味 2020-11-30 17:33

In GMail, the user can click on one checkbox in the email list, hold down the Shift key, and select a second checkbox. The JavaScript will then select/unselect the checkboxe

相关标签:
13条回答
  • 2020-11-30 17:58

    Recently, I wrote a jQuery plugin that provide that feature and more.

    After including the plugin you just need to initialize the context of checkboxes with the following code snippet:

    $('#table4').checkboxes({ range: true });
    

    Here is the link to the documentation, demo & download: http://rmariuzzo.github.io/checkboxes.js/

    0 讨论(0)
  • 2020-11-30 18:02

    This is jquery solution that I wrote and use:

    • All checkboxes have same class named chksel
    • For faster individual selection a class will carry the order named chksel_index
    • Also each checkbox has an attribute named rg that contain same index

      var chksel_last=-1;
      $('.chksel').click(function(ev){
         if(ev.shiftKey){var i=0;
            if(chksel_last >=0){
              if($(this).attr('rg') >= chksel_last){
               for(i=chksel_last;i<=$(this).attr('rg');i++){$('.chksel_'+i).attr('checked','true')}}
              if($(this).attr('rg') <= chksel_last){for(i=$(this).attr('rg');i<=chksel_last;i++){$('.chksel_'+i).attr('checked','true')}}
            }  
            chksel_last=$(this).attr('rg');
         }else{chksel_last=$(this).attr('rg');}
      

      })

    0 讨论(0)
  • 2020-11-30 18:07

    I took the jQuery version from @BC. and transformed it into an ES6 version, since the code is actually pretty elegantly solving the problem, in case anyone still stumbles across this...

    function enableGroupSelection( selector ) {
      let lastChecked = null;
      const checkboxes = Array.from( document.querySelectorAll( selector ) );
    
      checkboxes.forEach( checkbox => checkbox.addEventListener( 'click', event => {
        if ( !lastChecked ) {
          lastChecked = checkbox;
    
          return;
        }
    
        if ( event.shiftKey ) {
          const start = checkboxes.indexOf( checkbox );
          const end   = checkboxes.indexOf( lastChecked );
    
          checkboxes
            .slice( Math.min( start, end ), Math.max( start, end ) + 1 )
            .forEach( checkbox => checkbox.checked = lastChecked.checked );
        }
    
        lastChecked = checkbox;
      } ) );
    }
    
    0 讨论(0)
  • 2020-11-30 18:08

    Well, the post is quite old but here is a solution I've just come across: jQuery Field Plug-In

    0 讨论(0)
  • 2020-11-30 18:08

    Inspired by the fine answers provided, here's a plain JavaScript version using Array.prototype to coerce nodelists to use array functions, rather than for loops.

    (function () { // encapsulating variables with IIFE
      var lastcheck = null // no checkboxes clicked yet
    
      // get desired checkboxes
      var checkboxes = document.querySelectorAll('div.itemslist input[type=checkbox]')
    
      // loop over checkboxes to add event listener
      Array.prototype.forEach.call(checkboxes, function (cbx, idx) {
        cbx.addEventListener('click', function (evt) {
    
          // test for shift key, not first checkbox, and not same checkbox
          if ( evt.shiftKey && null !== lastcheck && idx !== lastcheck ) {
    
            // get range of checks between last-checkbox and shift-checkbox
            // Math.min/max does our sorting for us
            Array.prototype.slice.call(checkboxes, Math.min(lastcheck, idx), Math.max(lastcheck, idx))
              // and loop over each
              .forEach(function (ccbx) {
                ccbx.checked = true
            })
          }
          lastcheck = idx // set this checkbox as last-checked for later
        })
      })
    }())
    <div class="itemslist">
      <input type="checkbox" name="one"   value="1">
      <input type="checkbox" name="two"   value="2">
      <input type="checkbox" name="three" value="3">
      <input type="checkbox" name="four"  value="4">
      <input type="checkbox" name="five"  value="5">
    </div>

    0 讨论(0)
  • 2020-11-30 18:08

    this solution works for me, also ajax based for DataTables https://jsfiddle.net/6ouhv7bw/4/

    <table id="dataTable">
    
    <tbody>
    <tr>
    <td><input type="checkbox"></td>
    </tr>
    
    <tr>
    <td><input type="checkbox"></td>
    </tr>
    
    <tr>
    <td><input type="checkbox"></td>
    </tr>
    
    <tr>
    <td><input type="checkbox"></td>
    </tr>
    </tbody>
    </table>
    
    <script>
    $(document).ready(function() {
       var $chkboxes = $('#dataTable');
    var $range = '#dataTable tbody';
    var $first = false;
    var $indexWrapp = 'tr';
    var lastChecked = null;
    var $checkboxes = 'input[type="checkbox"]';
    
    $chkboxes.on('click',$checkboxes,function(e) {
    
        if ($first===false) {
    
            lastChecked = $(this).closest($indexWrapp).index();
            lastCheckedInput = $(this).prop('checked');
            $first=true;
            return;
        }
    
        if (e.shiftKey) {
    
            var start = lastChecked;
            var end =  $(this).closest($indexWrapp).index();
    
           $( $range+' '+$indexWrapp).each(function() {
              $currIndex=$(this).index();
              if( $currIndex>=start && $currIndex<=end ){
                  $(this).find($checkboxes).prop('checked', lastCheckedInput);
              }
    
           })
        }
    
         lastCheckedInput = $(this).prop('checked');
         lastChecked = $(this).closest($indexWrapp).index();
    });
    </script>
    
    0 讨论(0)
提交回复
热议问题