mirror of
https://github.com/tuxis-ie/nsedit.git
synced 2025-04-20 20:13:40 +03:00
382 lines
16 KiB
JavaScript
382 lines
16 KiB
JavaScript
/************************************************************************
|
|
* SELECTING extension for jTable *
|
|
*************************************************************************/
|
|
(function ($) {
|
|
|
|
//Reference to base object members
|
|
var base = {
|
|
_create: $.hik.jtable.prototype._create,
|
|
_addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
|
|
_addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord,
|
|
_onLoadingRecords: $.hik.jtable.prototype._onLoadingRecords,
|
|
_onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded,
|
|
_onRowsRemoved: $.hik.jtable.prototype._onRowsRemoved
|
|
};
|
|
|
|
//extension members
|
|
$.extend(true, $.hik.jtable.prototype, {
|
|
|
|
/************************************************************************
|
|
* DEFAULT OPTIONS / EVENTS *
|
|
*************************************************************************/
|
|
options: {
|
|
|
|
//Options
|
|
selecting: false,
|
|
multiselect: false,
|
|
selectingCheckboxes: false,
|
|
selectOnRowClick: true,
|
|
|
|
//Events
|
|
selectionChanged: function (event, data) { }
|
|
},
|
|
|
|
/************************************************************************
|
|
* PRIVATE FIELDS *
|
|
*************************************************************************/
|
|
|
|
_selectedRecordIdsBeforeLoad: null, //This array is used to store selected row Id's to restore them after a page refresh (string array).
|
|
_$selectAllCheckbox: null, //Reference to the 'select/deselect all' checkbox (jQuery object)
|
|
_shiftKeyDown: false, //True, if shift key is currently down.
|
|
|
|
/************************************************************************
|
|
* CONSTRUCTOR *
|
|
*************************************************************************/
|
|
|
|
/* Overrides base method to do selecting-specific constructions.
|
|
*************************************************************************/
|
|
_create: function () {
|
|
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
++this._firstDataColumnOffset;
|
|
this._bindKeyboardEvents();
|
|
}
|
|
|
|
//Call base method
|
|
base._create.apply(this, arguments);
|
|
},
|
|
|
|
/* Registers to keyboard events those are needed for selection
|
|
*************************************************************************/
|
|
_bindKeyboardEvents: function () {
|
|
var self = this;
|
|
//Register to events to set _shiftKeyDown value
|
|
$(document)
|
|
.keydown(function (event) {
|
|
switch (event.which) {
|
|
case 16:
|
|
self._shiftKeyDown = true;
|
|
break;
|
|
}
|
|
})
|
|
.keyup(function (event) {
|
|
switch (event.which) {
|
|
case 16:
|
|
self._shiftKeyDown = false;
|
|
break;
|
|
}
|
|
});
|
|
},
|
|
|
|
/************************************************************************
|
|
* PUBLIC METHODS *
|
|
*************************************************************************/
|
|
|
|
/* Gets jQuery selection for currently selected rows.
|
|
*************************************************************************/
|
|
selectedRows: function () {
|
|
return this._getSelectedRows();
|
|
},
|
|
|
|
/* Makes row/rows 'selected'.
|
|
*************************************************************************/
|
|
selectRows: function ($rows) {
|
|
this._selectRows($rows);
|
|
this._onSelectionChanged(); //TODO: trigger only if selected rows changes?
|
|
},
|
|
|
|
/************************************************************************
|
|
* OVERRIDED METHODS *
|
|
*************************************************************************/
|
|
|
|
/* Overrides base method to add a 'select column' to header row.
|
|
*************************************************************************/
|
|
_addColumnsToHeaderRow: function ($tr) {
|
|
if (this.options.selecting && this.options.selectingCheckboxes) {
|
|
if (this.options.multiselect) {
|
|
$tr.append(this._createSelectAllHeader());
|
|
} else {
|
|
$tr.append(this._createEmptyCommandHeader());
|
|
}
|
|
}
|
|
|
|
base._addColumnsToHeaderRow.apply(this, arguments);
|
|
},
|
|
|
|
/* Overrides base method to add a 'delete command cell' to a row.
|
|
*************************************************************************/
|
|
_addCellsToRowUsingRecord: function ($row) {
|
|
if (this.options.selecting) {
|
|
this._makeRowSelectable($row);
|
|
}
|
|
|
|
base._addCellsToRowUsingRecord.apply(this, arguments);
|
|
},
|
|
|
|
/* Overrides base event to store selection list
|
|
*************************************************************************/
|
|
_onLoadingRecords: function () {
|
|
if (this.options.selecting) {
|
|
this._storeSelectionList();
|
|
}
|
|
|
|
base._onLoadingRecords.apply(this, arguments);
|
|
},
|
|
|
|
/* Overrides base event to restore selection list
|
|
*************************************************************************/
|
|
_onRecordsLoaded: function () {
|
|
if (this.options.selecting) {
|
|
this._restoreSelectionList();
|
|
}
|
|
|
|
base._onRecordsLoaded.apply(this, arguments);
|
|
},
|
|
|
|
/* Overrides base event to check is any selected row is being removed.
|
|
*************************************************************************/
|
|
_onRowsRemoved: function ($rows, reason) {
|
|
if (this.options.selecting && (reason != 'reloading') && ($rows.filter('.jtable-row-selected').length > 0)) {
|
|
this._onSelectionChanged();
|
|
}
|
|
|
|
base._onRowsRemoved.apply(this, arguments);
|
|
},
|
|
|
|
/************************************************************************
|
|
* PRIVATE METHODS *
|
|
*************************************************************************/
|
|
|
|
/* Creates a header column to select/deselect all rows.
|
|
*************************************************************************/
|
|
_createSelectAllHeader: function () {
|
|
var self = this;
|
|
|
|
var $columnHeader = $('<th class=""></th>')
|
|
.addClass('jtable-command-column-header jtable-column-header-selecting');
|
|
this._jqueryuiThemeAddClass($columnHeader, 'ui-state-default');
|
|
|
|
var $headerContainer = $('<div />')
|
|
.addClass('jtable-column-header-container')
|
|
.appendTo($columnHeader);
|
|
|
|
self._$selectAllCheckbox = $('<input type="checkbox" />')
|
|
.appendTo($headerContainer)
|
|
.click(function () {
|
|
if (self._$tableRows.length <= 0) {
|
|
self._$selectAllCheckbox.attr('checked', false);
|
|
return;
|
|
}
|
|
|
|
var allRows = self._$tableBody.find('>tr.jtable-data-row');
|
|
if (self._$selectAllCheckbox.is(':checked')) {
|
|
self._selectRows(allRows);
|
|
} else {
|
|
self._deselectRows(allRows);
|
|
}
|
|
|
|
self._onSelectionChanged();
|
|
});
|
|
|
|
return $columnHeader;
|
|
},
|
|
|
|
/* Stores Id's of currently selected records to _selectedRecordIdsBeforeLoad.
|
|
*************************************************************************/
|
|
_storeSelectionList: function () {
|
|
var self = this;
|
|
|
|
if (!self.options.selecting) {
|
|
return;
|
|
}
|
|
|
|
self._selectedRecordIdsBeforeLoad = [];
|
|
self._getSelectedRows().each(function () {
|
|
self._selectedRecordIdsBeforeLoad.push(self._getKeyValueOfRecord($(this).data('record')));
|
|
});
|
|
},
|
|
|
|
/* Selects rows whose Id is in _selectedRecordIdsBeforeLoad;
|
|
*************************************************************************/
|
|
_restoreSelectionList: function () {
|
|
var self = this;
|
|
|
|
if (!self.options.selecting) {
|
|
return;
|
|
}
|
|
|
|
var selectedRowCount = 0;
|
|
for (var i = 0; i < self._$tableRows.length; ++i) {
|
|
var recordId = self._getKeyValueOfRecord(self._$tableRows[i].data('record'));
|
|
if ($.inArray(recordId, self._selectedRecordIdsBeforeLoad) > -1) {
|
|
self._selectRows(self._$tableRows[i]);
|
|
++selectedRowCount;
|
|
}
|
|
}
|
|
|
|
if (self._selectedRecordIdsBeforeLoad.length > 0 && self._selectedRecordIdsBeforeLoad.length != selectedRowCount) {
|
|
self._onSelectionChanged();
|
|
}
|
|
|
|
self._selectedRecordIdsBeforeLoad = [];
|
|
self._refreshSelectAllCheckboxState();
|
|
},
|
|
|
|
/* Gets all selected rows.
|
|
*************************************************************************/
|
|
_getSelectedRows: function () {
|
|
return this._$tableBody
|
|
.find('>tr.jtable-row-selected');
|
|
},
|
|
|
|
/* Adds selectable feature to a row.
|
|
*************************************************************************/
|
|
_makeRowSelectable: function ($row) {
|
|
var self = this;
|
|
|
|
//Select/deselect on row click
|
|
if (self.options.selectOnRowClick) {
|
|
$row.click(function () {
|
|
self._invertRowSelection($row);
|
|
});
|
|
}
|
|
|
|
//'select/deselect' checkbox column
|
|
if (self.options.selectingCheckboxes) {
|
|
var $cell = $('<td></td>').addClass('jtable-selecting-column');
|
|
var $selectCheckbox = $('<input type="checkbox" />').appendTo($cell);
|
|
if (!self.options.selectOnRowClick) {
|
|
$selectCheckbox.click(function () {
|
|
self._invertRowSelection($row);
|
|
});
|
|
}
|
|
|
|
$row.append($cell);
|
|
}
|
|
},
|
|
|
|
/* Inverts selection state of a single row.
|
|
*************************************************************************/
|
|
_invertRowSelection: function ($row) {
|
|
if ($row.hasClass('jtable-row-selected')) {
|
|
this._deselectRows($row);
|
|
} else {
|
|
//Shift key?
|
|
if (this._shiftKeyDown) {
|
|
var rowIndex = this._findRowIndex($row);
|
|
//try to select row and above rows until first selected row
|
|
var beforeIndex = this._findFirstSelectedRowIndexBeforeIndex(rowIndex) + 1;
|
|
if (beforeIndex > 0 && beforeIndex < rowIndex) {
|
|
this._selectRows(this._$tableBody.find('tr').slice(beforeIndex, rowIndex + 1));
|
|
} else {
|
|
//try to select row and below rows until first selected row
|
|
var afterIndex = this._findFirstSelectedRowIndexAfterIndex(rowIndex) - 1;
|
|
if (afterIndex > rowIndex) {
|
|
this._selectRows(this._$tableBody.find('tr').slice(rowIndex, afterIndex + 1));
|
|
} else {
|
|
//just select this row
|
|
this._selectRows($row);
|
|
}
|
|
}
|
|
} else {
|
|
this._selectRows($row);
|
|
}
|
|
}
|
|
|
|
this._onSelectionChanged();
|
|
},
|
|
|
|
/* Search for a selected row (that is before given row index) to up and returns it's index
|
|
*************************************************************************/
|
|
_findFirstSelectedRowIndexBeforeIndex: function (rowIndex) {
|
|
for (var i = rowIndex - 1; i >= 0; --i) {
|
|
if (this._$tableRows[i].hasClass('jtable-row-selected')) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
},
|
|
|
|
/* Search for a selected row (that is after given row index) to down and returns it's index
|
|
*************************************************************************/
|
|
_findFirstSelectedRowIndexAfterIndex: function (rowIndex) {
|
|
for (var i = rowIndex + 1; i < this._$tableRows.length; ++i) {
|
|
if (this._$tableRows[i].hasClass('jtable-row-selected')) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
},
|
|
|
|
/* Makes row/rows 'selected'.
|
|
*************************************************************************/
|
|
_selectRows: function ($rows) {
|
|
if (!this.options.multiselect) {
|
|
this._deselectRows(this._getSelectedRows());
|
|
}
|
|
|
|
$rows.addClass('jtable-row-selected');
|
|
this._jqueryuiThemeAddClass($rows, 'ui-state-highlight');
|
|
|
|
if (this.options.selectingCheckboxes) {
|
|
$rows.find('>td.jtable-selecting-column >input').prop('checked', true);
|
|
}
|
|
|
|
this._refreshSelectAllCheckboxState();
|
|
},
|
|
|
|
/* Makes row/rows 'non selected'.
|
|
*************************************************************************/
|
|
_deselectRows: function ($rows) {
|
|
$rows.removeClass('jtable-row-selected ui-state-highlight');
|
|
if (this.options.selectingCheckboxes) {
|
|
$rows.find('>td.jtable-selecting-column >input').prop('checked', false);
|
|
}
|
|
|
|
this._refreshSelectAllCheckboxState();
|
|
},
|
|
|
|
/* Updates state of the 'select/deselect' all checkbox according to count of selected rows.
|
|
*************************************************************************/
|
|
_refreshSelectAllCheckboxState: function () {
|
|
if (!this.options.selectingCheckboxes || !this.options.multiselect) {
|
|
return;
|
|
}
|
|
|
|
var totalRowCount = this._$tableRows.length;
|
|
var selectedRowCount = this._getSelectedRows().length;
|
|
|
|
if (selectedRowCount == 0) {
|
|
this._$selectAllCheckbox.prop('indeterminate', false);
|
|
this._$selectAllCheckbox.attr('checked', false);
|
|
} else if (selectedRowCount == totalRowCount) {
|
|
this._$selectAllCheckbox.prop('indeterminate', false);
|
|
this._$selectAllCheckbox.attr('checked', true);
|
|
} else {
|
|
this._$selectAllCheckbox.attr('checked', false);
|
|
this._$selectAllCheckbox.prop('indeterminate', true);
|
|
}
|
|
},
|
|
|
|
/************************************************************************
|
|
* EVENT RAISING METHODS *
|
|
*************************************************************************/
|
|
|
|
_onSelectionChanged: function () {
|
|
this._trigger("selectionChanged", null, {});
|
|
}
|
|
|
|
});
|
|
|
|
})(jQuery);
|