Skip to content

Commit

Permalink
Enable selection of a range in checkboxes lists
Browse files Browse the repository at this point in the history
Merge PR #1445
  • Loading branch information
dregad committed Mar 12, 2019
2 parents 8bf2f0f + aee22f5 commit 36d18a9
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
77 changes: 77 additions & 0 deletions js/common.js
Expand Up @@ -175,6 +175,83 @@ $(document).ready( function() {
});
}

/**
* Prepare a table where the checkboxes range selection has been applied
* Save row and column index in each cell for easier iteration.
* This assumes no rowspan or colspan is used in the area where the ckecboxes are rendered.
*/
$('table.checkbox-range-selection').each(function(){
$(this).find('tr').each( function(row_index){
$(this).children('th, td').each(function(col_index){
$(this).data('col_index', col_index);
$(this).data('row_index', row_index);
});
});
});

/**
* Enable range selection for checkboxes, inside a container having class "checkbox-range-selection"
* Assumes the bootstrap/ace styled checkboxes:
* <label>
* <input type="checkbox" class="ace">
* <span class="lbl"></span>
* </label>
*/
$('.checkbox-range-selection').on('click', 'label', function (e) {
if( $(this).children('input:checkbox').length == 0 ) {
return;
}
var jcontainer = $(this).closest('.checkbox-range-selection');
var last_clicked = jcontainer.data('checkbox-range-last-clicked');
if (!last_clicked) {
last_clicked = this;
}
if (e.shiftKey) {
// Because shift-click is triggered in a label/span, some browsers
// will activate a text selection. Remove text selection.
window.getSelection().removeAllRanges();
var cb_label_list = jcontainer.find('label').has('input:checkbox');
// The actual input hasn't been changed yet, so we want to set the
// opposite value for all the checkboxes
var clicked_current_st = $(this).find('input:checkbox').first().prop('checked');
// The currently clicked one is also modified, becasue shift-click is not
// recognised correctly by the framework. See #25215
if( jcontainer.is('table') ) {
// Special case for a table container:
// we traverse the table cells for a rectangular area
var cell_1 = $(this).closest('th, td');
var row_1 = cell_1.data('row_index');
var col_1 = cell_1.data('col_index');
var cell_2 = $(last_clicked).closest('th, td');
var row_2 = cell_2.data('row_index');
var col_2 = cell_2.data('col_index');
var row_start = Math.min(row_1, row_2);
var row_end = Math.max(row_1, row_2);
var col_start = Math.min(col_1, col_2);
var col_end = Math.max(col_1, col_2);
for (i = 0 ; i <= cb_label_list.length ; i++) {
var it_td = $(cb_label_list[i]).closest('th, td');
var it_row = it_td.data('row_index');
var it_col = it_td.data('col_index');
if( row_start <= it_row && it_row <= row_end
&& col_start <= it_col && it_col <= col_end ) {
$(cb_label_list[i]).find('input:checkbox').prop('checked', !clicked_current_st);
}
}
} else {
// General case: we traverse the items by their relative index
var start = cb_label_list.index(this);
var end = cb_label_list.index(last_clicked);
var index_start = Math.min(start, end);
var index_end = Math.max(start, end);
for (i = index_start ; i <= index_end ; i++) {
$(cb_label_list[i]).find('input:checkbox').prop('checked', !clicked_current_st);
}
}
}
jcontainer.data('checkbox-range-last-clicked', this);
});

var stopwatch = {
timerID: 0,
startTime: null,
Expand Down
2 changes: 1 addition & 1 deletion manage_config_email_page.php
Expand Up @@ -221,7 +221,7 @@ function get_section_begin_for_email( $p_section_name ) {
echo ' <div class="widget-body">';
echo ' <div class="widget-main no-padding">';
echo ' <div class="table-responsive">';
echo '<table class="table table-striped table-bordered table-condensed">' . "\n";
echo '<table class="table table-striped table-bordered table-condensed checkbox-range-selection">' . "\n";
echo '<thead>' . "\n";
echo '<tr>' . "\n";
echo '<th width="30%" rowspan="2">' . lang_get( 'message' ) . '</th>';
Expand Down
2 changes: 1 addition & 1 deletion view_all_inc.php
Expand Up @@ -152,7 +152,7 @@
</div>

<div class="widget-main no-padding">
<div class="table-responsive">
<div class="table-responsive checkbox-range-selection">
<table id="buglist" class="table table-bordered table-condensed table-hover table-striped">
<thead>
<?php # -- Bug list column header row -- ?>
Expand Down

0 comments on commit 36d18a9

Please sign in to comment.