Option name | Type | Description |
---|---|---|
el | Element | |
params | Object |
Table constructor.
var Table = function(el, params) {
if (!el) {
return;
}
this._setParams(this.defaults, true);
this._setParams(params || {});
this._cacheElements(el);
this._parseParams();
this._bindEventListenerCallbacks();
this._addEventListeners();
this._initRows();
if (this.isSpreadsheet || this.isEditRows) {
this._deactivateAllInputs();
}
if (this.isResizable) {
this._initResize();
}
this._disableRowsColumnsCells();
this._initExpands();
};
var noop = function() {};
Table.prototype = {
Include common functionality.
_setParams: Base.setParams,
_hasClass: Base.hasClass,
_toggleClass: Base.toggleClass,
_triggerEvent: Base.triggerEvent,
_addClass: Base.addClass,
_removeClass: Base.removeClass,
_getElementMatchingParent: Base.getElementMatchingParent,
_getChildIndex: Base.getChildIndex,
_getSiblingBefore: Base.getSiblingBefore,
_getSiblingAfter: Base.getSiblingAfter,
_elementMatches: Base.elementMatches,
Whitelisted parameters which can be set on construction.
_whitelistedParams: ['isSpreadsheet', 'isEditRows', 'isResizable', 'confirmDeleteCallback', 'onRowSave', 'onRowDelete'],
Default values for internal properties we will be setting.
These are set on each construction so we don't leak properties
into the prototype chain.
defaults: {
el: null,
tableEl: null,
isSpreadsheet: null,
isEditRows: null,
isResizable: null,
onRowSave: null,
onRowDelete: null,
confirmDeleteCallback: null,
_changePaused: false,
_expands: null,
_keyCodes: {
ENTER: 13,
UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,
ESCAPE: 27
},
_editingCount: 0,
_lastClickTime: 0,
_lastClickEl: null,
_lastScreenX: 0,
_touchStartTime: 0,
_touchStartEl: null,
_resizeEls: null,
_resizingEl: null,
_sizeColumnsRun: false,
_onClickBound: null,
_onChangeBound: null,
_onFocusBound: null,
_onBlurBound: null,
_onKeydownBound: null,
_onTouchstartBound: null,
_onTouchendBound: null,
_onMouseDownBound: null,
_onMouseMoveBound: null,
_onMouseUpBound: null
},
Option name | Type | Description |
---|---|---|
el | Element |
Disable the form field in a table cell.
disableCell: function(el) {
el.disabled = true;
this._addClass(this._getElementMatchingParent(el, 'td'), 'spark-table__disabled-cell');
},
Option name | Type | Description |
---|---|---|
el | Element |
Enable the form field in a table cell.
enableCell: function(el) {
el.disabled = false;
this._removeClass(this._getElementMatchingParent(el, 'td'), 'spark-table__disabled-cell');
},
Option name | Type | Description |
---|---|---|
el | Element |
Disable a row and all the cells inside of it.
disableRow: function(el) {
this._addClass(el, 'spark-table__disabled-row');
each(el.querySelectorAll('input, button, a'), function(i) {
i.disabled = true;
});
},
Option name | Type | Description |
---|---|---|
el | Element |
Enable a row and all the cells inside of it.
enableRow: function(el) {
this._removeClass(el, 'spark-table__disabled-row');
each(el.querySelectorAll('input, button, a'), function(i) {
i.disabled = false;
});
},
Option name | Type | Description |
---|---|---|
el | Element |
Disable a column and all the cells inside of it.
disableColumn: function(el) {
var index = this._getChildIndex(el.parentNode.children, el);
each(this.tableEl.querySelectorAll('tbody tr'), function(row) {
this.disableCell(row.children[index].querySelector('input'));
}.bind(this));
this._addClass(el, 'spark-table__disabled-column');
},
Option name | Type | Description |
---|---|---|
el | Element |
Enable a column and all the cells inside of it.
enableColumn: function(el) {
var index = this._getChildIndex(el.parentNode.children, el);
each(this.tableEl.querySelectorAll('tbody tr'), function(row) {
this.enableCell(row.children[index].querySelector('input'));
}.bind(this));
this._removeClass(el, 'spark-table__disabled-column');
},
Option name | Type | Description |
---|---|---|
leaveElement | Boolean | Leave the element intact. |
Remove the table anc cleanup.
remove: function(leaveElement) {
each(this._expands, function(e) {
e.remove(leaveElement);
});
Base.remove.apply(this, arguments);
},
Option name | Type | Description |
---|---|---|
row | Number, Element |
Activate a row.
activateRow: function(row) {
row = typeof row === 'number' ? this.tableEl.querySelectorAll('tbody tr')[row] : row;
if (!row) return;
this._makeRowActive(row);
},
Option name | Type | Description |
---|---|---|
rows | Array |
Activate multiple rows.
activateRows: function(rows) {
each(rows, this.activateRow.bind(this));
},
Option name | Type | Description |
---|---|---|
row | Number, Element |
Deactivate a row.
deactivateRow: function(row) {
row = typeof row === 'number' ? this.tableEl.querySelectorAll('tbody tr')[row] : row;
if (!row) return;
this._makeRowInActive(row);
},
Option name | Type | Description |
---|---|---|
rows | Array |
Deactivate multiple rows.
deactivateRows: function(rows) {
each(rows, this.deactivateRow.bind(this));
},
Get an array of currently active rows.
getActiveRows: function() {
var arr = [];
each(this.el.querySelectorAll('tbody tr.active'), function(tr) {
arr.push(tr);
});
return arr;
},
Option name | Type | Description |
---|---|---|
el | Element |
Store a reference to the tabs list, each tab and each panel.
Set which tab is active, or use the first.
_cacheElements: function(el) {
this.el = el;
this.tableEl = el.querySelector('table');
},
Parse parameters from the elements.
_parseParams: function() {
if (!this.tableEl) {
return;
}
this.isSpreadsheet = this.isSpreadsheet !== null ? this.isSpreadsheet : (this._hasClass(this.el, 'spark-table--spreadsheet') ? true : false);
this.isEditRows = this.isEditRows !== null ? this.isEditRows : (this._hasClass(this.el, 'spark-table--edit-rows') ? true : false);
this.isResizable = this.isResizable !== null ? this.isResizable : (this._hasClass(this.el, 'spark-table--resizable') ? true : false);
},
Create bound versions of event listener callbacks and store them.
Otherwise we can't unbind from these events later because the
function signatures won't match.
_bindEventListenerCallbacks: function() {
this._onClickBound = this._onClick.bind(this);
this._onChangeBound = this._onChange.bind(this);
this._onFocusBound = this._onFocus.bind(this);
this._onBlurBound = this._onBlur.bind(this);
this._onTouchstartBound = this._onTouchstart.bind(this);
this._onTouchendBound = this._onTouchend.bind(this);
this._onKeydownBound = this._onKeydown.bind(this);
this._onMouseDownBound = this._onMouseDown.bind(this);
this._onMouseMoveBound = this._onMouseMove.bind(this);
this._onMouseUpBound = this._onMouseUp.bind(this);
},
Add event listeners for DOM events.
_addEventListeners: function() {
this.el.addEventListener('click', this._onClickBound, false);
this.el.addEventListener('change', this._onChangeBound, false);
this.el.addEventListener('focus', this._onFocusBound, true);
this.el.addEventListener('blur', this._onBlurBound, true);
if (this.isSpreadsheet) {
this.el.addEventListener('touchstart', this._onTouchstartBound, false);
this.el.addEventListener('touchend', this._onTouchendBound, false);
this.el.addEventListener('keydown', this._onKeydownBound, false);
}
if (this.isResizable) {
this.tableEl.addEventListener('mousedown', this._onMouseDownBound, false);
}
},
Remove event listeners for DOM events..
_removeEventListeners: function() {
this.el.removeEventListener('click', this._onClickBound);
this.el.removeEventListener('change', this._onChangeBound);
this.el.removeEventListener('focus', this._onFocusBound);
this.el.removeEventListener('blur', this._onBlurBound);
this.el.removeEventListener('touchstart', this._onTouchstartBound);
this.el.removeEventListener('touchend', this._onTouchendBound);
this.el.removeEventListener('keydown', this._onKeydownBound);
this.tableEl.removeEventListener('mousedown', this._onMouseDownBound);
this._removeResizeListeners();
},
Add listeners for mousemove and mouseup events.
_addResizeListeners: function() {
window.addEventListener('mousemove', this._onMouseMoveBound, false);
window.addEventListener('mouseup', this._onMouseUpBound, false);
},
Remove listeners for mosuemove and mouseup.
_removeResizeListeners: function() {
window.removeEventListener('mousemove', this._onMouseMoveBound);
window.removeEventListener('mouseup', this._onMouseUpBound);
},
Option name | Type | Description |
---|---|---|
row | Object |
Toggle the active state on a row.
_toggleRowActive: function(row) {
if (this._hasClass(row, 'active')) {
this._makeRowInActive(row);
this._uncheckSelectAll();
} else {
this._makeRowActive(row);
}
},
Option name | Type | Description |
---|---|---|
row | Element |
Make a row active
_makeRowActive: function(row) {
this._addClass(row, 'active');
var checkbox = row.querySelector('input[type="checkbox"]:not([disabled])');
if (checkbox && checkbox.checked !== true) {
checkbox.checked = true;
this._changePaused = true;
this._triggerEvent(checkbox, 'change');
this._changePaused = false;
}
},
Option name | Type | Description |
---|---|---|
row | Element |
Make a row active
_makeRowInActive: function(row) {
this._removeClass(row, 'active');
var checkbox = row.querySelector('input[type="checkbox"]:not([disabled])');
if (checkbox && checkbox.checked !== false) {
checkbox.checked = false;
this._changePaused = true;
this._triggerEvent(checkbox, 'change');
this._changePaused = false;
}
},
Option name | Type | Description |
---|---|---|
rows | NodeList | |
active | Boolean |
Toggle active on each row.
_toggleRowsActive: function(rows, active) {
var func = active ? '_makeRowActive' : '_makeRowInActive';
var i = 0;
var len = rows.length;
for (; i < len; i++) {
this[func](rows[i]);
}
},
Option name | Type | Description |
---|---|---|
el | Element |
Toggle whether everything should be selected. Find the checkbox input inside of the
given element and invert its state.
_toggleSelectAll: function(el) {
var checkbox = el.querySelector('input[type="checkbox"]');
if (!checkbox) {
return;
}
this._toggleRowsActive(this.el.querySelectorAll('tbody tr'), !checkbox.checked);
checkbox.checked = !checkbox.checked;
},
Uncheck the select all checkboxes.
_uncheckSelectAll: function() {
var checkboxes = this.el.querySelectorAll('.spark-table__select-all input[type="checkbox"]');
var i = 0;
var len = checkboxes.length;
for (; i < len; i++) {
checkboxes[i].checked = false;
}
},
Deactivate editing in all input fields.
_deactivateAllInputs: function() {
if (!this.tableEl) {
return;
}
this._deactivateInputs(this.tableEl);
},
Option name | Type | Description |
---|---|---|
el | Element |
Deactivate all the inputs inside an element
_deactivateInputs: function(el) {
var inputs = el.querySelectorAll('input:not([type="checkbox"])');
var i = 0;
var len = inputs.length;
for (; i < len; i++) {
this._deactivateInput(inputs[i]);
}
},
Option name | Type | Description |
---|---|---|
input | Element |
Make an input field readonly.
_deactivateInput: function(input) {
input.setAttribute('readonly', '');
this._removeClass(input.parentNode, 'editing');
},
Option name | Type | Description |
---|---|---|
el | Element |
Activate all the inputs inside an element
_activateInputs: function(el) {
var inputs = el.querySelectorAll('input:not([type="checkbox"])');
var i = 0;
var len = inputs.length;
for (; i < len; i++) {
this._activateInput(inputs[i]);
}
},
Option name | Type | Description |
---|---|---|
input | Element |
Make an input field readable.
_activateInput: function(input) {
input.removeAttribute('readonly');
this._addClass(input.parentNode, 'editing');
if (input.type !== 'checkbox' && input.type !== 'radio') {
setCaret(input, -1);
}
},
Option name | Type | Description |
---|---|---|
input | Element |
Activate an input, unless it's already enabled in which case
the focus should move down a row.
_activateInputOrFocusDown: function(input) {
// Currently readonly
if (input.getAttribute('readonly') === '') {
this._activateInput(input);
return;
}
this._focusDown(input, true);
},
Find all the rows, columns and cells that should be disabled.
_disableRowsColumnsCells: function() {
each(this.tableEl.querySelectorAll('td input[disabled]'), this.disableCell.bind(this));
each(this.tableEl.querySelectorAll('.spark-table__disabled-row'), this.disableRow.bind(this));
each(this.tableEl.querySelectorAll('.spark-table__disabled-column'), this.disableColumn.bind(this));
},
Option name | Type | Description |
---|---|---|
input | Element | |
force | Boolean | Force the move even if the element is active. |
Move our focus up a row from the given element.
_focusUp: function(input, force) {
return this._focusUpDown(input, 'up', force);
},
Option name | Type | Description |
---|---|---|
input | Element | |
force | Boolean | Force the move even if the element is active. |
Move our focus down a row from the given element.
_focusDown: function(input, force) {
return this._focusUpDown(input, 'down', force);
},
Option name | Type | Description |
---|---|---|
input | Element | |
direction | String | up|down |
force | Boolean | Force the move even if the element is active. |
Focus on a row up or down from the given element.
_focusUpDown: function(input, direction, force) {
// If we're not being told to force and the item is not read only
if (!force && input.getAttribute('readonly') === null) {
return;
}
this._deactivateInput(input);
var td = this._getElementMatchingParent(input, 'td', this.el);
if (!td) {
return;
}
var index = this._getChildIndex(td.parentNode.children, td);
var nextRow = this[direction === 'up' ? '_getSiblingBefore' : '_getSiblingAfter'](td.parentNode, 'tr');
if (!nextRow) {
return;
}
var newTd = nextRow.children[index];
if (!newTd) {
return;
}
var newInput = newTd.querySelector('input:not([type="checkbox"]), select');
if (newInput) {
if (newInput.disabled) {
this._focusUpDown(newInput, direction, force);
} else {
newInput.focus();
}
}
},
Option name | Type | Description |
---|---|---|
input | Element | |
force | Boolean | Force the move even if the element is active. |
Move our focus left a cell from the given element.
_focusLeft: function(input, force) {
return this._focusLeftRight(input, 'left', force);
},
Option name | Type | Description |
---|---|---|
input | Element | |
force | Boolean | Force the move even if the element is active. |
Move our focus right a cell from the given element.
_focusRight: function(input, force) {
return this._focusLeftRight(input, 'right', force);
},
Option name | Type | Description |
---|---|---|
input | Element | |
direction | String | up|down |
force | Boolean | Force the move even if the element is active. |
Focus on a cell left or down from the given element.
_focusLeftRight: function(input, direction, force) {
// If we're not being told to force and the item is not read only
if (!force && input.getAttribute('readonly') === null) {
return;
}
this._deactivateInput(input);
var td = this._getElementMatchingParent(input, 'td', this.el);
if (!td) {
return;
}
var newTd = this[direction === 'left' ? '_getSiblingBefore' : '_getSiblingAfter'](td, 'td');
if (!newTd) {
return;
}
var newInput = newTd.querySelector('input:not([type="checkbox"]), select');
if (newInput) {
if (newInput.disabled) {
this._focusLeftRight(newInput, direction, force);
} else {
newInput.focus();
}
}
},
Option name | Type | Description |
---|---|---|
el | Element |
Check for two click events on the same element in short succession.
_checkDoubleClick: function(el) {
var now = Date.now();
var lastTime = this._lastClickTime;
var lastEl = this._lastClickEl;
this._lastClickTime = now;
this._lastClickEl = el;
if (el === lastEl && now - 500 < lastTime) {
return true;
}
return false;
},
Unset the last clicked element.
_clearClicked: function() {
this._lastClickEl = null;
},
Option name | Type | Description |
---|---|---|
row | Element |
Enable editing on a row.
_editRow: function(row) {
if (!row) {
return;
}
this._editingCount++;
this._activateInputs(row);
formData.store(row);
this._addClass(row, 'editing');
this._updateBindings();
},
Option name | Type | Description |
---|---|---|
row | Element |
Cancel editing a row.
_cancelRow: function(row) {
if (!row) {
return;
}
this._editingCount--;
this._deactivateInputs(row);
formData.restore(row);
this._removeClass(row, 'editing');
this._updateBindings();
},
Option name | Type | Description |
---|---|---|
row | Element |
Save a row.
_saveRow: function(row) {
if (!row) {
return;
}
this._editingCount--;
this._deactivateInputs(row);
formData.clear(row);
this._removeClass(row, 'editing');
this._updateBindings();
(this.onRowSave || noop)(this._getChildIndex(row.parentNode.children, row), row);
},
Option name | Type | Description |
---|---|---|
row | Element |
Delete a row.
_deleteRow: function(row) {
if (!row) {
return;
}
(this.onRowDelete || noop)(this._getChildIndex(row.parentNode.children, row), row);
row.parentNode.removeChild(row);
},
Option name | Type | Description |
---|---|---|
row | Element |
Confirm the deletion of a row.
_confirmDelete: function(row) {
if (!this.confirmDeleteCallback || typeof this.confirmDeleteCallback !== 'function') {
this._deleteRow(row);
} else {
this.confirmDeleteCallback(row, this._deleteRow);
}
},
Update data bindings.
_updateBindings: function() {
this._toggleClass(this.el, 'editing', this._editingCount);
},
Add handles to the header that can be grabbed for resizing.
_initResize: function() {
this._resizeEls = [];
var ths = this.tableEl.querySelectorAll('thead th');
each(ths, function(th) {
th.innerHTML = '<span class="spark-table__resize spark-table__resize--left"></span>' + th.innerHTML + '<span class="spark-table__resize spark-table__resize--right"></span>';
this._resizeEls.push(th);
}.bind(this));
},
Initialize rows active states.
_initRows: function() {
each(this.tableEl.querySelectorAll('td.spark-table__checkbox input:checked'), function(c) {
this._makeRowActive(this._getElementMatchingParent(c, 'tr'));
}.bind(this));
},
Option name | Type | Description |
---|---|---|
unit | String | Optional |
force | Boolean | Optional |
Set the size of each column as a percentage so it can be adjusted
while cells are resized.
_sizeColumns: function(unit, force) {
unit = unit || '%';
if (this._sizeColumnsRun && !force) {
return;
}
var width = this.tableEl.offsetWidth;
each(this.tableEl.querySelectorAll('thead th'), function(th) {
if (unit === '%')
th.style.width = (Math.round(th.offsetWidth / width * 100000) / 100000) * 100 + '%';
else
th.style.width = th.offsetWidth + 'px';
}.bind(this));
this._sizeColumnsRun = true;
},
Initialize expand/collapse rows.
_initExpands: function() {
var expands = this.tableEl.querySelectorAll('.spark-table-expand');
this._expands = [];
each(expands, function(e) {
this._expands.push(new Expand(e, {
onBeforeExpand: this._onBeforeExpand.bind(this)
}));
}.bind(this));
},
Before an expand is called, size all the columns so that
the expand does cause width changes.
_onBeforeExpand: function() {
this._sizeColumns();
},
Option name | Type | Description |
---|---|---|
e | Object |
When we are clicked determine the proper action to take.
_onClick: function(e) {
var target = e.target || e.srcElement;
var row;
var selectAll;
var actionTaken = false;
var clearClicked = true;
// Select all rows checkbox
if ((selectAll = this._getElementMatchingParent(target, '.spark-table__select-all', this.el)) && !this._elementMatches(target, 'input[type="checkbox"]')) {
this._toggleSelectAll(selectAll);
actionTaken = true;
}
// Editable field
else if (this._elementMatches(target, 'input:not([type="checkbox"]), select')) {
if (!target.disabled) {
// Listen for double clicks on a spreadsheet
if (this.isSpreadsheet) {
clearClicked = false;
if (this._checkDoubleClick(target)) {
clearClicked = true;
this._activateInput(target);
}
}
actionTaken = true;
}
}
// Edit button
else if (this._elementMatches(target, '.spark-table__edit-row')) {
this._editRow(this._getElementMatchingParent(target, 'tr', this.el));
actionTaken = true;
}
// Delete button
else if (this._elementMatches(target, '.spark-table__delete-row')) {
this._confirmDelete(this._getElementMatchingParent(target, 'tr', this.el));
actionTaken = true;
}
// Save button
else if (this._elementMatches(target, '.spark-table__edit-row-save')) {
this._saveRow(this._getElementMatchingParent(target, 'tr', this.el));
actionTaken = true;
}
// Cancel button
else if (this._elementMatches(target, '.spark-table__edit-row-cancel')) {
this._cancelRow(this._getElementMatchingParent(target, 'tr', this.el));
actionTaken = true;
}
// Select a row
else if (!this._getElementMatchingParent(target, 'button, a', this.el) && !this._elementMatches(target, 'input[type="checkbox"]') && (row = this._getElementMatchingParent(target, 'tbody tr', this.el))) {
if (!(row.querySelector('input[type="checkbox"]') || {}).disabled) {
this._toggleRowActive(row);
actionTaken = true;
}
}
if (clearClicked) {
this._clearClicked();
}
if (actionTaken) {
e.preventDefault();
}
},
Option name | Type | Description |
---|---|---|
e | Object |
When the change event fires on our element.
_onChange: function(e) {
if (this._changePaused) {
return;
}
var target = e.target || e.srcElement;
var row;
var selectAll;
// Select all rows checkbox. We have to invert the checked value here because it
// get toggled back in the select all call.
if ((selectAll = this._getElementMatchingParent(target, '.spark-table__select-all', this.el))) {
target.checked = !target.checked;
this._toggleSelectAll(selectAll);
}
// Checkbox for a row
else if (this._elementMatches(target, 'input[type="checkbox"]') && (row = this._getElementMatchingParent(target, 'tbody tr', this.el))) {
this._toggleRowActive(row);
}
},
Option name | Type | Description |
---|---|---|
e | Object |
If this is a spreadsheet, whenever a field gains focus, highlight its parent.
_onFocus: function(e) {
var target = e.target || e.srcElement;
if (!this.isSpreadsheet || !this._elementMatches(target, 'input:not([type="checkbox"]), select')) {
return;
}
var td = this._getElementMatchingParent(target, 'td', this.el);
this._addClass(td, 'focus');
},
Option name | Type | Description |
---|---|---|
e | Object |
If this is a spreadsheet, whenever a field gains focus, highlight its parent.
_onBlur: function(e) {
if (!this.isSpreadsheet) {
return;
}
var target = e.target || e.srcElement;
var td = this._getElementMatchingParent(target, 'td', this.el);
this._removeClass(td, 'focus');
this._deactivateInput(target);
},
Option name | Type | Description |
---|---|---|
e | Object |
When a key is pressed, if this is a spreadsheet then we should detect
enter or arrow keys.
_onKeydown: function(e) {
var target = e.target || e.srcElement;
if (!this.isSpreadsheet || !this._elementMatches(target, 'input:not([type="checkbox"]), select')) {
return;
}
var code = e.keyCode || e.which;
switch (code) {
case this._keyCodes.ENTER:
this._activateInputOrFocusDown(target);
break;
case this._keyCodes.ESCAPE:
this._deactivateInput(target);
break;
case this._keyCodes.DOWN:
this._focusDown(target);
break;
case this._keyCodes.UP:
this._focusUp(target);
break;
case this._keyCodes.LEFT:
this._focusLeft(target);
break;
case this._keyCodes.RIGHT:
this._focusRight(target);
break;
}
},
Option name | Type | Description |
---|---|---|
e | Object |
Listen for a touch and hold on an input.
_onTouchstart: function(e) {
var target = e.target || e.srcElement;
if (!this.isSpreadsheet || !this._elementMatches(target, 'input:not([type="checkbox"])')) {
return;
}
this._touchStartEl = target;
this._touchStartTime = Date.now();
this._touchStartTimer = setTimeout(this._onTouchHold.bind(this), 1000);
},
Option name | Type | Description |
---|---|---|
e | Object |
Listen for the end of a touch to cancel the hold timer.
_onTouchend: function(e) {
var target = e.target || e.srcElement;
if (!this._touchStartEl || target !== this._touchStartEl) {
return;
}
this._touchStartEl = null;
this._touchStartTime = null;
clearTimeout(this._touchStartTimer);
},
When the user has held on an input for the defined amount of time.
_onTouchHold: function() {
this._activateInput(this._touchStartEl);
this._touchStartEl = null;
this._touchStartTime = null;
clearTimeout(this._touchStartTimer);
},
Option name | Type | Description |
---|---|---|
e | Object |
When the mouse is depressed.
_onMouseDown: function(e) {
var target = e.target || e.srcElement;
if (!this.isResizable || !this._elementMatches(target, '.spark-table__resize')) {
return;
}
e.preventDefault();
this._lastScreenX = e.screenX;
this._sizeColumns('px', true);
this._resizingEl = target.parentNode;
var index = this._resizeEls.indexOf(this._resizingEl);
if (this._hasClass(target, 'spark-table__resize--left')) {
this._resizingEl = this._resizeEls[index - 1];
}
if (!this._resizingEl) {
return;
}
this._addResizeListeners();
},
Option name | Type | Description |
---|---|---|
e | Object |
When the mouse moves after being depressed, resize the columns.
_onMouseMove: function(e) {
var x = e.screenX;
var d = x - this._lastScreenX;
// No delta change
if (!d) {
return;
}
e.preventDefault();
var w = this._resizingEl.offsetWidth;
var tW = this.tableEl.offsetWidth;
var newW = w + d;
var newTW = tW + d;
this._resizingEl.style.width = newW + 'px';
this.tableEl.style.width = newTW + 'px';
// Size was not affected because we're too small
if (this._resizingEl.offsetWidth === w || this.tableEl.offsetWidth < this.tableEl.parentNode.offsetWidth) {
this._resizingEl.style.width = w + 'px';
this.tableEl.style.width = tW + 'px';
}
this._lastScreenX = x;
},
Option name | Type | Description |
---|---|---|
e | Object |
When the mouse is released, stop tracking mouse move events and
convert table sizes to percentages.
_onMouseUp: function() {
this._sizeColumns('%', true);
this.tableEl.style.width = (this.tableEl.offsetWidth / this.tableEl.parentNode.offsetWidth * 100) + '%';
this._removeResizeListeners();
}
};
Base.exportjQuery(Table, 'Table');
return Table;
}));