You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
7.0 KiB
JavaScript
225 lines
7.0 KiB
JavaScript
2 years ago
|
/*! © Nick Adkinson, SpryMedia Ltd - datatables.net/license */
|
||
|
|
||
1 year ago
|
import jQuery from 'jquery';
|
||
2 years ago
|
import DataTable from 'datatables.net';
|
||
|
|
||
1 year ago
|
// Allow reassignment of the $ variable
|
||
|
let $ = jQuery;
|
||
|
|
||
2 years ago
|
/**
|
||
|
* @summary SlidingChild
|
||
|
* @description Show / Hide row child plugin
|
||
|
* @version 2.1.0
|
||
|
* @author [Nick Adkinson](https://github.com/data-handler)
|
||
|
* @copyright Copyright 2018 Nick Adkinson
|
||
|
*
|
||
|
* This feature plug-in provides functionality for showing and hiding row child
|
||
|
* information in DataTables. This can be particularly useful for displaying
|
||
|
* hierarchical data as a drill-down, or where you wish to convey more information
|
||
|
* about a row than there is space for in the host table.
|
||
|
*
|
||
|
* @example
|
||
|
* $('#myTable').DataTable({
|
||
|
* slidingChild: {
|
||
|
* source: function(parent, response) {
|
||
|
* $.get('/Child/GetByParentId/' + parent.data('id'), response);
|
||
|
* }
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
*/
|
||
|
var SlidingChild = function (dt, options) {
|
||
|
var that = this;
|
||
|
dt.on('draw', function () {
|
||
|
that._updateFadedRows();
|
||
|
});
|
||
|
var table = dt.table();
|
||
|
var sliderElement = document.createElement('div');
|
||
|
sliderElement.className = 'slider';
|
||
|
this.s = $.extend({}, {
|
||
|
dt: dt,
|
||
|
table: $(table.node()),
|
||
|
slider: $(sliderElement),
|
||
|
}, SlidingChild.defaults, options);
|
||
|
this._bind();
|
||
|
};
|
||
|
SlidingChild.prototype._bind = function () {
|
||
|
var that = this;
|
||
|
var settings = that.s;
|
||
|
$(settings.table, '> tbody').on('click', settings.selector, function () {
|
||
|
var $this = $(this);
|
||
|
var tr = $this.is('tr') ? $this : $this.closest('tr');
|
||
|
if (!tr.is('tr')) {
|
||
|
return;
|
||
|
} // throw error?
|
||
|
var dtRow = settings.dt.row(tr);
|
||
|
that._toggleChild(dtRow);
|
||
|
});
|
||
|
};
|
||
|
SlidingChild.prototype._toggleChild = function (dtRow) {
|
||
|
var settings = this.s;
|
||
|
if (dtRow.child.isShown()) {
|
||
|
this._hideChild(dtRow, function () { });
|
||
|
}
|
||
|
else {
|
||
|
var existingShownDtRow = settings.dt.row('.shown');
|
||
|
if (existingShownDtRow.length && settings.toggle) {
|
||
|
this._hideChild(existingShownDtRow, this._showChildCallback(dtRow));
|
||
|
}
|
||
|
else {
|
||
|
this._showChild(dtRow);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
SlidingChild.prototype._showChildCallback = function (dtRow) {
|
||
|
return function (dtRow) {
|
||
|
this._showChild(dtRow);
|
||
|
}.bind(this, dtRow);
|
||
|
};
|
||
|
SlidingChild.prototype._showChild = function (dtRow) {
|
||
|
var $tr = $(dtRow.node());
|
||
|
if (this.s.displayLoadingIndicator) {
|
||
|
this._addLoadingIndicator($tr);
|
||
|
}
|
||
|
this.s.source($tr, this._response(dtRow));
|
||
|
};
|
||
|
SlidingChild.prototype._response = function (dtRow) {
|
||
|
return function (dtRow, childData) {
|
||
|
this.__showChild(dtRow, childData);
|
||
|
}.bind(this, dtRow);
|
||
|
};
|
||
|
SlidingChild.prototype.__showChild = function (dtRow, data) {
|
||
|
var settings = this.s;
|
||
|
var slider = settings.slider;
|
||
|
var $tr = $(dtRow.node());
|
||
|
if (settings.displayLoadingIndicator) {
|
||
|
$('.' + this.s.loadingIndicatorClass).remove();
|
||
|
}
|
||
|
slider.append(data);
|
||
|
dtRow.child(slider, settings.childClass).show();
|
||
|
$tr.toggleClass('shown');
|
||
|
this._updateFadedRows();
|
||
|
if (settings.animateShow) {
|
||
|
this._showChildWithAnimation(dtRow);
|
||
|
}
|
||
|
else {
|
||
|
this._showChildWithoutAnimation(dtRow);
|
||
|
}
|
||
|
};
|
||
|
SlidingChild.prototype._showChildWithAnimation = function (dtRow) {
|
||
|
var settings = this.s;
|
||
|
$(settings.slider, dtRow.child()).slideDown(settings.animationSpeed, function () {
|
||
|
settings.onShown(dtRow);
|
||
|
});
|
||
|
};
|
||
|
SlidingChild.prototype._showChildWithoutAnimation = function (dtRow) {
|
||
|
var settings = this.s;
|
||
|
$(settings.slider, dtRow.child()).show();
|
||
|
settings.onShown(dtRow);
|
||
|
};
|
||
|
SlidingChild.prototype._hideChild = function (dtRow, callback) {
|
||
|
var settings = this.s;
|
||
|
$(dtRow.node()).toggleClass('shown');
|
||
|
this._updateFadedRows();
|
||
|
if (settings.animateHide) {
|
||
|
this._hideChildWithAnimation(dtRow, callback);
|
||
|
}
|
||
|
else {
|
||
|
this._hideChildWithoutAnimation(dtRow, callback);
|
||
|
}
|
||
|
};
|
||
|
SlidingChild.prototype._hideChildWithAnimation = function (dtRow, callback) {
|
||
|
var settings = this.s;
|
||
|
var slider = settings.slider;
|
||
|
$(slider, dtRow.child()).slideUp(settings.animationSpeed, function () {
|
||
|
dtRow.child.remove();
|
||
|
slider.empty();
|
||
|
settings.onHidden(dtRow);
|
||
|
callback();
|
||
|
});
|
||
|
};
|
||
|
SlidingChild.prototype._hideChildWithoutAnimation = function (dtRow, callback) {
|
||
|
var settings = this.s;
|
||
|
var slider = settings.slider;
|
||
|
$(slider, dtRow.child()).hide();
|
||
|
dtRow.child.remove();
|
||
|
slider.empty();
|
||
|
settings.onHidden(dtRow);
|
||
|
callback();
|
||
|
};
|
||
|
SlidingChild.prototype._updateFadedRows = function () {
|
||
|
if (this.s.fadeNonShowingRows) {
|
||
|
this._fadeNonShowingRows();
|
||
|
this._removeFadeFromShowingRows();
|
||
|
}
|
||
|
else {
|
||
|
this._removeFadeFromRows();
|
||
|
}
|
||
|
};
|
||
|
SlidingChild.prototype._fadeNonShowingRows = function () {
|
||
|
if (this.s.dt.rows('.shown:visible').count()) {
|
||
|
this.s.dt
|
||
|
.rows(':visible:not(.shown):not(.faded)')
|
||
|
.nodes()
|
||
|
.to$()
|
||
|
.css('opacity', this.s.fadeOpacity)
|
||
|
.addClass('faded');
|
||
|
}
|
||
|
else {
|
||
|
this._removeFadeFromRows();
|
||
|
}
|
||
|
};
|
||
|
SlidingChild.prototype._removeFadeFromShowingRows = function () {
|
||
|
this.s.dt
|
||
|
.rows('.shown.faded:visible')
|
||
|
.nodes()
|
||
|
.to$()
|
||
|
.css('opacity', 1)
|
||
|
.removeClass('faded');
|
||
|
};
|
||
|
SlidingChild.prototype._removeFadeFromRows = function () {
|
||
|
this.s.dt.rows('.faded').nodes().to$().css('opacity', 1).removeClass('faded');
|
||
|
};
|
||
|
SlidingChild.prototype._addLoadingIndicator = function ($tr) {
|
||
|
var position = $tr.position();
|
||
|
var indicator = $(this.s.loadingIndicatorContent);
|
||
|
indicator.addClass(this.s.loadingIndicatorClass);
|
||
|
indicator.css('top', position.top);
|
||
|
indicator.css('left', position.left);
|
||
|
indicator.css('height', $tr.height());
|
||
|
$tr.append(indicator);
|
||
|
};
|
||
|
const options = {
|
||
|
selector: 'tr',
|
||
|
childClass: 'child',
|
||
|
source: function () { },
|
||
|
toggle: true,
|
||
|
animateShow: true,
|
||
|
animateHide: true,
|
||
|
fadeNonShowingRows: false,
|
||
|
fadeOpacity: 0.4,
|
||
|
animationSpeed: 200,
|
||
|
onShown: function () { },
|
||
|
onHidden: function () { },
|
||
|
displayLoadingIndicator: false,
|
||
|
loadingIndicatorClass: 'loading-indicator',
|
||
|
loadingIndicatorContent: '<div style="background: black; color: white; display: flex; align-items: center; justify-content: center; opacity: 0.5; position: absolute; width: 100%; z-index: 100;">Loading...</div>',
|
||
|
};
|
||
|
SlidingChild.defaults = options;
|
||
|
DataTable.SlidingChild = SlidingChild;
|
||
|
// Automatic initialisation listener
|
||
|
$(document).on('init.dt', function (e, settings) {
|
||
|
if (e.namespace !== 'dt') {
|
||
|
return;
|
||
|
}
|
||
|
var api = new DataTable.Api(settings);
|
||
|
if ($(api.table().node()).hasClass('slidingChild') ||
|
||
|
settings.oInit.slidingChild ||
|
||
|
DataTable.defaults.slidingChild) {
|
||
|
new SlidingChild(api, settings.oInit.slidingChild);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
export default DataTable;
|