Added checkbox support for multi select

Resolving issues found from failed test. Was not returning selected items properly

Adding sort to both repeater options

Fixing frozen columns, actions, multi select to work with list_columnSizing and list_columnSyncing.
Fixes #1411 Repeater actions to have pointer cursor.
Fixes #1311 adds checkbox support for multi select

Fix broken test due to change of width property in actions option

remove unneeded width property from repeater

Fixes Actions function to string
- removing 'multi-selected' and making everything 'selected'
- removing fuelux icons from index example

Found issue in test with way returning selected items. Was also selecting the frozen column since it had the selected class. Had to change to specifically look for only the main table items.

Removing data-initialize of the checkboxes
This commit is contained in:
Ben Davis
2015-06-10 16:31:25 -04:00
parent add62c4b2d
commit a8a972b223
5 changed files with 220 additions and 76 deletions

View File

@@ -45,16 +45,4 @@
.example-pill-class {
font-style: italic;
font-weight: bold;
}
#myRepeater[data-currentview="list.frozen"] table thead tr th, #myRepeater[data-currentview="list.frozen"] .repeater-list-heading {
width: 400px;
}
#myRepeaterActions table thead tr th, #myRepeaterActions .repeater-list-heading {
width: 400px;
}
#myRepeaterActions table.table-actions .repeater-list-heading {
width: 100%;
}

View File

@@ -542,12 +542,14 @@ define(function (require) {
{
label: 'Common Name',
property: 'commonName',
sortable: true
sortable: true,
width: 600
},
{
label: 'Latin Name',
property: 'latinName',
sortable: true
sortable: true,
width: 600
},
{
label: 'Appearance',
@@ -630,9 +632,7 @@ define(function (require) {
dataSource: function (options, callback) {
list(options, callback);
},
list_selectable: 'multi',
list_columnSizing:false,
list_columnSyncing: false
list_selectable: 'multi'
},
'thumbnail': {
dataSource: function (options, callback) {
@@ -646,8 +646,6 @@ define(function (require) {
dataSource: function (options, callback) {
list(options, callback);
},
list_columnSizing:false,
list_columnSyncing: false,
list_selectable: false, // (single | multi)
list_frozenColumns: 1
}
@@ -750,30 +748,22 @@ define(function (require) {
// initialize the repeater
var repeaterActions = $('#myRepeaterActions');
repeaterActions.repeater({
list_columnSizing:false,
list_columnSyncing: false,
list_noItemsHTML: '<span>foo</span>',
list_highlightSortedColumn: true,
list_actions: {
width: '37px',
width: 37,
items: [
{
name: 'edit',
html: function () {
return '<span class="glyphicon glyphicon-pencil"></span> Edit'
}
html: '<span class="glyphicon glyphicon-pencil"></span> Edit'
},
{
name: 'copy',
html: function () {
return '<span class="glyphicon glyphicon-copy"></span> Copy'
}
html: '<span class="glyphicon glyphicon-copy"></span> Copy'
},
{
name: 'delete',
html: function () {
return '<span class="glyphicon glyphicon-trash"></span> Delete'
},
html: '<span class="glyphicon glyphicon-trash"></span> Delete',
clickAction: function(helpers, callback) {
console.log('hey it worked');
console.log(helpers);
@@ -789,7 +779,6 @@ define(function (require) {
}
initRepeaterActions();
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SCHEDULER
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

View File

@@ -47,7 +47,7 @@
$.fn.repeater.Constructor.prototype.list_getSelectedItems = function () {
var selected = [];
this.$canvas.find('.repeater-list table tbody tr.selected').each(function () {
this.$canvas.find('.repeater-list .repeater-list-wrapper > table tbody tr.selected').each(function () {
var $item = $(this);
selected.push({
data: $item.data('item_data'),
@@ -144,11 +144,17 @@
$.fn.repeater.Constructor.prototype.list_setFrozenColumns = function () {
var frozenTable = this.$canvas.find('.table-frozen');
var $wrapper = this.$element.find('.repeater-canvas');
var $table = this.$element.find('.repeater-list .repeater-list-wrapper > table');
var repeaterWrapper = this.$element.find('.repeater-list');
var numFrozenColumns = this.viewOptions.list_frozenColumns;
var self = this;
if (this.viewOptions.list_selectable === 'multi') {
numFrozenColumns = numFrozenColumns + 1;
$wrapper.addClass('multi-select-enabled');
}
if (frozenTable.length < 1) {
//setup frozen column markup
//main wrapper and remove unneeded columns
@@ -170,6 +176,7 @@
this.$element.find('.repeater-list table.table-frozen tr').each(function (i, elem) {
$(this).height($table.find('tr:eq(' + i + ')').height());
});
var columnWidth = $table.find('td:eq(0)').outerWidth();
this.$element.find('.frozen-column-wrapper, .frozen-thead-wrapper').width(columnWidth);
@@ -186,7 +193,7 @@
var $wrapper = this.$element.find('.repeater-canvas');
var scrollTop = $wrapper.scrollTop();
var scrollLeft = $wrapper.scrollLeft();
var frozenEnabled = this.viewOptions.list_frozenColumns;
var frozenEnabled = this.viewOptions.list_frozenColumns || this.viewOptions.list_selectable === 'multi';
var actionsEnabled = this.viewOptions.list_actions;
var canvasWidth = this.$element.find('.repeater-canvas').outerWidth();
@@ -234,13 +241,13 @@
for (i = 0, l = this.viewOptions.list_actions.items.length; i < l; i++) {
var action = this.viewOptions.list_actions.items[i];
var html = action.html();
var html = action.html;
actionsHtml += '<li><a data-action="'+ action.name +'" class="action-item"> ' + html + '</a></li>';
actionsHtml += '<li><a href="#" data-action="'+ action.name +'" class="action-item"> ' + html + '</a></li>';
}
var selectlist = '<div class="btn-group">' +
'<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">' +
'<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" data-flip="auto" aria-expanded="false">' +
'<span class="caret"></span>' +
'</button>' +
'<ul class="dropdown-menu dropdown-menu-right" role="menu">' +
@@ -249,10 +256,10 @@
if ($actionsTable.length < 1) {
var $actionsColumnWrapper = $('<div class="actions-column-wrapper"></div>').insertBefore($table);
var $actionsColumnWrapper = $('<div class="actions-column-wrapper" style="width: '+ this.list_actions_width +'px"></div>').insertBefore($table);
var $actionsColumn = $table.clone().addClass('table-actions');
$actionsColumn.find('th:not(:lt(1))').remove();
$actionsColumn.find('td:not(:nth-child(n+0):nth-child(-n+1))').remove();
$actionsColumn.find('th:not(:last-child)').remove();
$actionsColumn.find('tr td:not(:last-child)').remove();
// Dont show actions dropdown in header if not multi select
if (this.viewOptions.list_selectable === 'multi') {
@@ -276,10 +283,10 @@
this.$canvas.addClass('actions-enabled');
}
this.$element.find('.repeater-list .actions-column-wrapper, .repeater-list .actions-column-wrapper td, .repeater-list .actions-column-wrapper th')
/* this.$element.find('.repeater-list .actions-column-wrapper, .repeater-list .actions-column-wrapper td, .repeater-list .actions-column-wrapper th')
.css('width', this.list_actions_width);
this.$element.find('.repeater-list .actions-column-wrapper th .repeater-list-heading').css('width', parseInt(this.list_actions_width) + 1 + 'px');
this.$element.find('.repeater-list .actions-column-wrapper th .repeater-list-heading').css('width', this.list_actions_width + 1 + 'px');*/
this.$element.find('.repeater-list table.table-actions tr').each(function (i, elem) {
$(this).height($table.find('tr:eq(' + i + ')').height());
@@ -315,6 +322,40 @@
$actionsTableHeading.outerHeight($table.find('thead th .repeater-list-heading').outerHeight());
};
$.fn.repeater.Constructor.prototype.list_multiSelectInitialize = function () {
var self = this;
var $checkboxes = self.$element.find('.frozen-column-wrapper .checkbox-inline');
//Make sure if row is hovered that it is shown in frozen column as well
this.$element.find('tr.selectable').on('mouseover mouseleave', function(e) {
var index = $(this).index();
index = index + 1;
if (e.type === 'mouseover'){
self.$element.find('.repeater-list-wrapper > table tbody tr:nth-child('+ index +'), ' +
'.frozen-column-wrapper tbody tr:nth-child('+ index +')').addClass('hovered');
}
else {
self.$element.find('.repeater-list-wrapper > table tbody tr:nth-child('+ index +'), ' +
'.frozen-column-wrapper tbody tr:nth-child('+ index +')').removeClass('hovered');
}
});
$checkboxes.checkbox();
this.$element.find('.frozen-thead-wrapper thead .checkbox-inline').on('change', function () {
var $checkboxes = self.$element.find('.frozen-column-wrapper .checkbox-inline');
if ($(this).checkbox('isChecked')){
$checkboxes.checkbox('check');
self.$element.trigger('selected.fu.repeaterList', $checkboxes);
}
else {
$checkboxes.checkbox('uncheck');
self.$element.trigger('deselected.fu.repeaterList', $checkboxes);
}
});
};
//ADDITIONAL DEFAULT OPTIONS
$.fn.repeater.defaults = $.extend({}, $.fn.repeater.defaults, {
list_columnRendered: null,
@@ -349,7 +390,7 @@
initialize: function (helpers, callback) {
this.list_sortDirection = null;
this.list_sortProperty = null;
this.list_actions_width = (this.viewOptions.list_actions.width !== undefined) ? this.viewOptions.list_actions.width : '37px';
this.list_actions_width = (this.viewOptions.list_actions.width !== undefined) ? this.viewOptions.list_actions.width : 37;
callback();
},
resize: function () {
@@ -381,7 +422,7 @@
self.list_positionHeadings();
}
});
if (self.viewOptions.list_frozenColumns || self.viewOptions.list_actions) {
if (self.viewOptions.list_frozenColumns || self.viewOptions.list_actions || self.viewOptions.list_selectable === 'multi') {
helpers.container.on('scroll.fu.repeaterList', function () {
self.list_positionColumns();
});
@@ -389,6 +430,7 @@
helpers.container.append($listContainer);
}
helpers.container.removeClass('actions-enabled actions-enabled multi-select-enabled');
$table = $listContainer.find('table');
renderThead.call(this, $table, helpers.data);
@@ -403,14 +445,8 @@
after: function(){
var $sorted;
if (this.viewOptions.list_columnSyncing) {
this.list_sizeHeadings();
this.list_positionHeadings();
}
if (this.viewOptions.list_frozenColumns) {
if (this.viewOptions.list_frozenColumns || this.viewOptions.list_selectable === 'multi') {
this.list_setFrozenColumns();
}
if (this.viewOptions.list_actions) {
@@ -418,10 +454,19 @@
this.list_sizeActionsTable();
}
if (this.viewOptions.list_frozenColumns || this.viewOptions.list_actions) {
if (this.viewOptions.list_frozenColumns || this.viewOptions.list_actions || this.viewOptions.list_selectable === 'multi') {
this.list_positionColumns();
}
if (this.viewOptions.list_selectable === 'multi') {
this.list_multiSelectInitialize();
}
if (this.viewOptions.list_columnSyncing) {
this.list_sizeHeadings();
this.list_positionHeadings();
}
$sorted = this.$canvas.find('.repeater-list-wrapper > table .repeater-list-heading.sorted');
if ($sorted.length > 0) {
this.list_highlightColumn($sorted.data('fu_item_index'));
@@ -441,7 +486,7 @@
var property = columns[columnIndex].property;
if(this.viewOptions.list_actions !== false && property === '@_ACTIONS_@'){
content = '<div class="repeater-list-actions-placeholder" style="width: ' + this.list_actions_width + '"></div>';
content = '<div class="repeater-list-actions-placeholder" style="width: ' + this.list_actions_width + 'px"></div>';
}
content = (content!==undefined) ? content : '';
@@ -452,6 +497,19 @@
}
$row.append($col);
if (this.viewOptions.list_selectable === 'multi' && columns[columnIndex].property === '@_CHECKBOX_@') {
var checkBoxMarkup = '<label class="checkbox-custom checkbox-inline body-checkbox">' +
'<input class="sr-only" type="checkbox"></label>';
$col.html(checkBoxMarkup);
//Prevent default click action on the actual click of the checkbox because already handled
//with any click anywhere in the row
$col.find('.checkbox-custom').on('click', function(e) {
e.preventDefault();
});
}
if (this.viewOptions.list_columnRendered) {
this.viewOptions.list_columnRendered({
container: $row,
@@ -467,6 +525,8 @@
var chevron = '.glyphicon.rlc:first';
var chevUp = 'glyphicon-chevron-up';
var $div = $('<div class="repeater-list-heading"><span class="glyphicon rlc"></span></div>');
var checkBoxMarkup = '<div class="repeater-list-heading header-checkbox"><label class="checkbox-custom checkbox-inline">' +
'<input class="sr-only" type="checkbox"></label><div class="clearfix"></div></div>';
var $header = $('<th></th>');
var self = this;
var $both, className, sortable, $span, $spans;
@@ -474,7 +534,13 @@
$div.data('fu_item_index', index);
$div.prepend(columns[index].label);
$header.html($div.html()).find('[id]').removeAttr('id');
$header.append($div);
if (columns[index].property !== '@_CHECKBOX_@') {
$header.append($div);
}
else {
$header.append(checkBoxMarkup);
}
$both = $header.add($div);
$span = $div.find(chevron);
@@ -547,31 +613,51 @@
var $row = $('<tr></tr>');
var self = this;
var i, l;
var isMulti = this.viewOptions.list_selectable === 'multi';
if (this.viewOptions.list_selectable) {
$row.addClass('selectable');
$row.attr('tabindex', 0); // allow items to be tabbed to / focused on
$row.data('item_data', rows[index]);
$row.on('click.fu.repeaterList', function () {
var $item = $(this);
if ($item.hasClass('selected')) {
var index = $(this).index();
index = index + 1;
var $frozenRow = self.$element.find('.frozen-column-wrapper tr:nth-child('+ index +')');
var $checkBox = self.$element.find('.frozen-column-wrapper tr:nth-child('+ index +') .checkbox-inline');
if ($item.is('.selected')) {
$item.removeClass('selected');
$item.find('.repeater-list-check').remove();
if (isMulti){
$checkBox.checkbox('uncheck');
$frozenRow.removeClass('selected');
}
else {
$item.find('.repeater-list-check').remove();
}
self.$element.trigger('deselected.fu.repeaterList', $item);
} else {
if (self.viewOptions.list_selectable !== 'multi') {
if (!isMulti) {
self.$canvas.find('.repeater-list-check').remove();
self.$canvas.find('.repeater-list tbody tr.selected').each(function () {
$(this).removeClass('selected');
self.$element.trigger('deselected.fu.repeaterList', $(this));
});
$item.find('td:first').prepend('<div class="repeater-list-check"><span class="glyphicon glyphicon-ok"></span></div>');
$item.addClass('selected');
}
else {
$checkBox.checkbox('check');
$item.addClass('selected');
$frozenRow.addClass('selected');
}
$item.addClass('selected');
$item.find('td:first').prepend('<div class="repeater-list-check"><span class="glyphicon glyphicon-ok"></span></div>');
self.$element.trigger('selected.fu.repeaterList', $item);
}
});
// allow selection via enter key
$row.keyup(function (e) {
if (e.keyCode === 13) {
@@ -647,6 +733,15 @@
if (this.list_firstRender || differentColumns(this.list_columns, columns) || $thead.length === 0) {
$thead.remove();
if (this.viewOptions.list_selectable === 'multi') {
var checkboxColumn = {
label: 'c',
property: '@_CHECKBOX_@',
sortable: false
};
columns.splice(0, 0, checkboxColumn);
}
this.list_columns = columns;
this.list_firstRender = false;
this.$loader.removeClass('noHeader');
@@ -669,6 +764,30 @@
}
$table.prepend($thead);
if (this.viewOptions.list_selectable === 'multi') {
//after checkbox column is created need to get width of checkbox column from
//its css class
var checkboxWidth = this.$element.find('.repeater-list-wrapper .header-checkbox').outerWidth();
var selectColumn = $.grep(columns, function(column){
return column.property === '@_CHECKBOX_@';
})[0];
selectColumn.width = checkboxWidth;
$table.find('.header-checkbox input').on('change', function() {
var checked = $(this).is(':checked') ? true : false;
var bodyCheckboxes = $table.find('.body-checkbox');
if (checked){
bodyCheckboxes.checkbox('check');
bodyCheckboxes.closest('tr').addClass('selected');
}
else {
bodyCheckboxes.checkbox('uncheck');
bodyCheckboxes.closest('tr').removeClass('selected');
}
});
}
sizeColumns.call(this, $tr);
}
}
@@ -676,11 +795,12 @@
function sizeColumns ($tr) {
var auto = [];
var self = this;
var i, l, newWidth, taken;
var i, l, newWidth, taken, total;
if (this.viewOptions.list_columnSizing) {
i = 0;
taken = 0;
total = 0;
$tr.find('th').each(function () {
var $th = $(this);
var isLast = ($th.next('th').length === 0);
@@ -689,17 +809,22 @@
width = self.list_columns[i].width;
$th.outerWidth(width);
taken += $th.outerWidth();
total += $th.outerWidth();
if (!isLast) {
self.list_columns[i]._auto_width = width;
} else {
}
else {
$th.outerWidth('');
}
} else {
var outerWidth = $th.find('.repeater-list-heading').outerWidth();
total += $th.outerWidth();
auto.push({
col: $th,
index: i,
last: isLast
last: isLast,
minWidth: outerWidth
});
}
@@ -707,10 +832,15 @@
});
l = auto.length;
if (l > 0) {
newWidth = Math.floor((this.$canvas.width() - taken) / l);
var canvasWidth = this.$canvas.find('.repeater-list-wrapper').outerWidth();
newWidth = Math.floor((canvasWidth - taken) / l);
for (i = 0; i < l; i++) {
if (!auto[i].last) {
if (auto[i].minWidth > newWidth) {
newWidth = auto[i].minWidth;
}
if (!auto[i].last || total > canvasWidth) {
auto[i].col.outerWidth(newWidth);
this.list_columns[auto[i].index]._auto_width = newWidth;
}

View File

@@ -1,3 +1,5 @@
@mutli-select-enabled-width: 37px;
.fuelux {
.repeater[data-viewtype="list"] {
.repeater-canvas {
@@ -57,10 +59,14 @@
}
&.selectable {
&:hover td {
&:hover td, &.hovered {
background: @selectableHover;
cursor: pointer;
}
.checkbox-custom:before {
margin-top: -4px;
top: 0
}
}
&.selected {
@@ -229,6 +235,7 @@
}
}
}
}
&.actions-enabled {
@@ -346,6 +353,42 @@
}
}
}
&.multi-select-enabled {
.repeater-list {
thead {
tr:first-child {
.repeater-list-heading {
width: @mutli-select-enabled-width;
}
.header-checkbox {
width: @mutli-select-enabled-width;
label {
top: -10px;
left: 4px;
}
}
}
}
tbody {
tr {
.body-checkbox {
left: 4px;
top: -3px;
}
}
}
tr {
&.selected {
td {
&:first-child {
padding-left: 8px;
}
}
}
}
}
}
}
.repeater-loader {

View File

@@ -371,25 +371,19 @@ define(function(require){
var repeaterOptions = {
dataSource: dataSource,
list_actions: {
width: '37px',
width: 37,
items: [
{
name: 'edit',
html: function () {
return '<div class="fuelux-icon fuelux-icon-pencil"></div> Edit';
}
html: '<span class="glyphicon glyphicon-pencil"></span> Edit'
},
{
name: 'copy',
html: function () {
return '<div class="fuelux-icon fuelux-icon-copy"></div> Copy';
}
html: '<span class="glyphicon glyphicon-copy"></span> Copy'
},
{
name: 'delete',
html: function () {
return '<div class="fuelux-icon fuelux-icon-delete"></div> Delete';
},
html: '<span class="glyphicon glyphicon-trash"></span> Delete',
clickAction: function(helpers, callback) {
testClickAction(helpers);
callback();
@@ -414,7 +408,7 @@ define(function(require){
equal($actionsTable.length !== 0 && $actionsTable.length === 1, true, 'Actions table was created and only one');
equal($repeater.find('.actions-column-wrapper').css('width') === repeaterOptions.list_actions.width, true, 'Actions table width set correctly');
equal($repeater.find('.actions-column-wrapper').width() === repeaterOptions.list_actions.width, true, 'Actions table width set correctly');
ok($actionsTable.find('tbody tr:first-child .btn-group').hasClass('open'), 'Actions dropdown opens on click');