Skip to content

Instantly share code, notes, and snippets.

@AndrewRayCode
Created September 25, 2012 19:53
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save AndrewRayCode/3784055 to your computer and use it in GitHub Desktop.
Save AndrewRayCode/3784055 to your computer and use it in GitHub Desktop.
jQuery plugin for shift + click to select multiple checkboxes
// Usage: $form.find('input[type="checkbox"]').shiftSelectable();
// replace input[type="checkbox"] with the selector to match your list of checkboxes
$.fn.shiftSelectable = function() {
var lastChecked,
$boxes = this;
$boxes.click(function(evt) {
if(!lastChecked) {
lastChecked = this;
return;
}
if(evt.shiftKey) {
var start = $boxes.index(this),
end = $boxes.index(lastChecked);
$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
.attr('checked', lastChecked.checked)
.trigger('change');
}
lastChecked = this;
});
};
@rmariuzzo
Copy link

Nice! I have wrote a jQuery plugin with that feature and some others: http://rmariuzzo.github.io/checkboxes.js/ Maybe it would be nice to work on together on it.

@getnoel
Copy link

getnoel commented Oct 2, 2013

Thanks for this cool piece of code. I am using it together with jquery tablesorter. After sorting the table, range selector goes weird. How can I reset it so that I could run shiftSelectable() again after sorting? Thanks again.

@getnoel
Copy link

getnoel commented Oct 2, 2013

Got it, insert this code on line 7:
$boxes.off('click');

I then run initialize the code as callback every time I sort the table.

@abhishekgithub
Copy link

var chkboxes = $('.chkbox');
chkboxes.click(function(e) {
if(!lastChecked) {
lastChecked = this;
return;
}

        if(e.shiftKey) {
            var start = $chkboxes.index(this);
            var end = $chkboxes.index(lastChecked);

            $chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).attr('checked', lastChecked.checked);

        }

        lastChecked = this;
    });

What about this one?

@MazeChaZer
Copy link

For the latest jQuery versions, you need to use .prop() instead of .attr() in line 18 to make this work properly, see http://api.jquery.com/attr/

The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

@puppyceceyoyo
Copy link

I was unable to shift+check the checkboxes again after range select once. After changed to .prop() , it works well now... I use it together with gridview, after sorting, it still can range select very well too.. : ) Thanks for this cool JS codes..

@vkoves
Copy link

vkoves commented Jun 2, 2015

For anyone looking for how to do it with tablesorter based on @noelpur:

$(document).ready(function() 
{ 
    $("#listCont").tablesorter(); 
    $("#listCont").find('input[type="checkbox"]').shiftSelectable();

    $("table").bind("sortEnd",function()
    { 
        $("#listCont").find('input[type="checkbox"]').shiftSelectable();
    })
});


// Usage: $form.find('input[type="checkbox"]').shiftSelectable();
// replace input[type="checkbox"] with the selector to match your list of checkboxes

$.fn.shiftSelectable = function() {
    var lastChecked,
        $boxes = this;
        $boxes.off('click');

    $boxes.click(function(evt) 
    {
        if(!lastChecked) 
        {
            lastChecked = this;
            return;
        }

        if(evt.shiftKey) 
        {
            var start = $boxes.index(this),
                end = $boxes.index(lastChecked);
            //console.log("START: " + start + " END: " + end);

            $boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                .attr('checked', lastChecked.checked)
                .trigger('change');
        }

        lastChecked = this;
    });
};

@nicolasfranck
Copy link

$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                .attr('checked', lastChecked.checked)
                .trigger('change');

often doesn't work (I tested in Chrome)

This does:

$boxes.slice(Math.min(start, end), Math.max(start, end) + 1).each(function(){
  this.checked = lastChecked.checked;
  $(this).trigger('change');
});

@zergius-eggstream
Copy link

https://gist.github.com/zergius-eggstream/bea51020b471886bafe1b2baef9817b8
almost the same but with live collections support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment