Skip to content

Instantly share code, notes, and snippets.

@RadGH
Created May 9, 2014 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RadGH/8c35091f975d71c90a1b to your computer and use it in GitHub Desktop.
Save RadGH/8c35091f975d71c90a1b to your computer and use it in GitHub Desktop.
/*
This function allows you to press and drag your mouse over multiple checkboxes to change the state of them all.
It does not toggle, but instead causes any selected values to match the originating element.
Does not support radio buttons or dynamically loaded elements.
Example Usage -- Say you have five checkboxes, with the middle one checked:
[0]
[0]
[1]
[0]
[0]
If you drag starting at #2 until #4, you will end with:
[0]
[1]
[1]
[1]
[0]
This functionality can be restricted to a container, so that you cannot toggle the state of unrelated elements.
The container is passed as a selector. The originating checkbox will look for this container, and only elements within
the container will benefit from the drag/select functionality.
Usage:
Enable for all checkboxes on the page:
init_draggable_group( 'input:checkbox' );
Enable for checkboxes of class "category":
init_draggable_group( 'input.category:checkbox' );
Enable for checkboxes of class "category", without affecting other categories:
init_draggable_group( 'input.category:checkbox', 'div.category' );
*/
function init_draggable_group( checkbox_selector, container_selector ) {
// Support a container that restrict selection to those within the same container
if ( typeof container_selector == 'undefined' ) container_selector = false;
var $container = false;
var $dragging_input = false;
var $blur_handle = false; // Will either be the checkbox, or the label. The element which initiated the drag event.
var drag_state = false;
var hover_out = function(e) {
// Toggle this checkbox, then start dragging
drag_state = !$dragging_input.prop('checked');
$dragging_input.prop('checked', drag_state);
if ( $blur_handle.length > 0 ) $blur_handle.off('mouseout', hover_out);
$blur_handle = false;
// console.log( 'Started dragging', this, $dragging_input.prop('checked') );
jQuery('body').on( 'mouseover', checkbox_selector, drag_over );
jQuery('body').on( 'mouseover', 'label', drag_over_label );
};
var drag_over_label = function(e) {
var $for = jQuery('#' + jQuery(this).attr('for'));
// console.log( 'Dragged over label', this, '#' + jQuery(this).attr('for'), $for[0] );
if ( $for.length > 0 && $for.is( checkbox_selector ) ) $for.trigger('mouseover');
}
var drag_over = function(e) {
// console.log( 'Dragged over element', this );
if ( $container.length > 0 ) {
if ( $container.find(this).length < 1 ) {
// console.log( 'Not part of this group' );
return;
}else{
// console.log( 'Correct parent', $container, $container.find(this) );
}
}else{
// console.log('No container in use', container_selector);
}
jQuery(this).prop('checked', drag_state);
};
var stop_drag = function(e) {
// console.log( 'Stopped dragging', $dragging_input[0] );
jQuery('body').off( 'mouseover', checkbox_selector, drag_over );
jQuery('body').off( 'mouseover', 'label', drag_over_label );
jQuery('body').off( 'mouseup', stop_drag );
$dragging_input = false;
};
jQuery( 'label, ' + checkbox_selector ).off('mousedown').on('mousedown', function(e, triggered_by_label) {
if ( typeof triggered_by_label == 'undefined' ) triggered_by_label = false;
// Allow labels to relay clicks to the checkboxes
if ( jQuery(this).is('label') ) {
var $for = jQuery( '#' + jQuery(this).attr('for') );
if ( $for.length > 0 && $for.is( checkbox_selector ) ) {
$for.trigger('mousedown', jQuery(this));
}
e.preventDefault();
return false;
}
// console.log( 'Waiting to drag', this, jQuery(this).prop('checked') );
$dragging_input = jQuery(this);
if ( triggered_by_label !== false ) $blur_handle = jQuery(triggered_by_label);
else $blur_handle = $dragging_input;
// If container_selector is given
if ( container_selector ) {
$container = $dragging_input.closest( container_selector );
if ( $container.length < 1 ) {
$dragging_input = false;
return;
}
// console.log('Container in use', $container[0], container_selector );
}
// console.log('Blur handle ', $blur_handle);
$blur_handle.on('mouseout', hover_out);
jQuery('body').on( 'mouseup', stop_drag );
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment