(function (w, $) {
let Dcat = w.Dcat;
/**
* 树状表格
*
* @param opts
* @constructor
*/
function Tree(opts) {
this.options = $.extend({
button: null,
table: null,
url: '',
perPage: '',
showNextPage: '',
pageQueryName: '',
parentIdQueryName: '',
tierQueryName: '',
showIcon: 'fa-angle-right',
hideIcon: 'fa-angle-down',
loadMoreIcon: '',
}, opts);
this.key = this.tier = this.row = this.data = this._req = null;
this._init();
}
Tree.prototype = {
_init: function () {
this._bindClick();
},
_bindClick: function () {
var _this = this,
opts = _this.options;
$(opts.button).off('click').click(function () {
if (_this._req) {
return;
}
var $this = $(this),
_i = $("i", this),
shown = _i.hasClass(opts.showIcon);
_this.key = $this.data('key');
_this.tier = $this.data('tier');
_this.row = $this.closest('tr');
if ($this.data('inserted') == '0') {
_this.request(1);
$this.data('inserted', 1);
}
_i.toggleClass(opts.showIcon + ' ' + opts.hideIcon);
var children = [];
getChildren(_this.row.nextAll(), _this.row).forEach(function (v) {
if (getTier(v) !== (_this.tier + 1)) {
return;
}
children.push(v);
shown ? $(v).show() : $(v).hide();
});
children.forEach(function (v) {
if (shown) {
return
}
var icon = $(v).find('a[data-tier=' + getTier(v) + '] i');
if (icon.hasClass(opts.hideIcon)) {
icon.parent().click();
}
})
})
},
request: function (page, after) {
var _this = this,
row = _this.row,
key = _this.key,
tier = _this.tier,
tableSelector = _this.options.table;
if (_this._req) {
return;
}
_this._req = 1;
Dcat.loading();
var data = {};
data[_this.options.parentIdQueryName] = key;
data[_this.options.tierQueryName] = tier + 1;
data[_this.options.pageQueryName.replace(':key', key)] = page;
$.ajax({
url: _this.options.url,
type: 'GET',
data: data,
headers: {'X-PJAX': true},
success: function (resp) {
after && after();
Dcat.loading(false);
_this._req = 0;
// 获取最后一行
var children = getChildren(row.nextAll(), row);
row = children.length ? $(children.pop()) : row;
var _body = $('
'+resp+'
'),
_tbody = _body.find(tableSelector + ' tbody'),
lastPage = _body.find('last-page').text(),
nextPage = _body.find('next-page').text();
// 标记子节点行
_tbody.find('tr').each(function (_, v) {
$(v).attr('data-tier', tier + 1)
});
if (
_this.options.showNextPage
&& _tbody.find('tr').length == _this.options.perPage
&& lastPage >= page
) {
// 加载更多
let loadMore = $(
`
${_this.options.loadMoreIcon}
|
`
);
row.after(loadMore);
// 加载更多
loadMore.click(function () {
var _t = $(this);
_this.request(_t.data('page'), function () {
_t.remove();
});
});
}
// 附加子节点
row.after(_tbody.html());
// 附加子节点js脚本以及触发子节点js脚本执行
_body.find('script').each(function (_, v) {
row.after(v);
});
// 主动触发ready事件,执行子节点附带的js脚本
Dcat.triggerReady();
},
error:function(a, b, c){
after && after();
Dcat.loading(false);
_this._req = 0;
if (a.status != 404) {
Dcat.handleAjaxError(a, b, c);
}
}
});
}
};
/**
* 可排序功能
*
* @param opts
* @constructor
*/
function Orderable(opts) {
this.options = $.extend({
button: null,
url: '',
}, opts);
this.direction = this.key = this.tier = this.row = this._req = null;
this.init();
}
Orderable.prototype = {
init: function () {
var _this = this;
$(_this.options.button).off('click').click(function () {
if (_this._req) {
return;
}
_this._req = 1;
Dcat.loading();
var $this = $(this);
_this.key = $this.data('id');
_this.direction = $this.data('direction');
_this.row = $this.closest('tr');
_this.tier = getTier(_this.row);
_this.request();
})
},
request: function () {
var _this = this,
key = _this.key,
row = _this.row,
tier = _this.tier,
direction = _this.direction,
prevAll = row.prevAll(),
nextAll = row.nextAll(),
prev = row.prevAll('tr').first(),
next = row.nextAll('tr').first();
$.put({
url: _this.options.url.replace(':key', key),
data: {_orderable: direction},
success: function(data){
Dcat.loading(false);
_this._req = 0;
if (! data.status) {
return data.message && Dcat.warning(data.message);
}
Dcat.success(data.message);
if (direction) {
var prevRow = sibling(prevAll, tier);
if (swapable(prevRow, tier) && prev.length && getTier(prev) >= tier) {
prevRow.before(row);
// 把所有子节点上移
getChildren(nextAll, row).forEach(function (v) {
prevRow.before(v)
});
}
} else {
var nextRow = sibling(nextAll, tier),
nextRowChildren = nextRow ? getChildren(nextRow.nextAll(), nextRow) : [];
if (swapable(nextRow, tier) && next.length && getTier(next) >= tier) {
nextAll = row.nextAll();
if (nextRowChildren.length) {
nextRow = $(nextRowChildren.pop())
}
// 把所有子节点下移
var all = [];
getChildren(nextAll, row).forEach(function (v) {
all.unshift(v)
});
all.forEach(function(v) {
nextRow.after(v)
});
nextRow.after(row);
}
}
},
error: function (a, b, c) {
_this._req = 0;
Dcat.loading(false);
Dcat.handleAjaxError(a, b, c)
}
});
},
};
/**
* 异步加载表格
*
* @param options
* @constructor
*/
function AsyncTable(options) {
options = $.extend({
container: '.table-card',
}, options)
function load(url, box) {
var $this = $(this);
box = box || $this;
url = $this.data('url') || url;
if (! url) {
return;
}
// 缓存当前请求地址
box.attr('data-current', url);
box.loading({background: 'transparent!important'});
Dcat.helpers.asyncRender(url, function (html) {
box.loading(false);
box.html(html);
bind(box);
box.trigger('table:loaded');
});
}
function bind(box) {
function loadLink() {
load($(this).attr('href'), box);
return false;
}
box.find('.pagination .page-link').on('click', loadLink);
box.find('.grid-column-header a').on('click', loadLink);
box.find('form').on('submit', function () {
load($(this).attr('action')+'&'+$(this).serialize(), box);
return false;
});
box.find('.filter-box .reset').on('click', loadLink);
box.find('.grid-selector a').on('click', loadLink);
Dcat.ready(function () {
setTimeout(function () {
box.find('.grid-refresh').off('click').on('click', function () {
load(box.data('current'), box);
return false;
})
}, 10)
})
}
$(options.container).on('table:load', load);
}
function isTr(v) {
return $(v).prop('tagName').toLocaleLowerCase() === 'tr'
}
function getTier(v) {
return parseInt($(v).data('tier') || 0);
}
function isChildren(parent, child) {
return getTier(child) > getTier(parent);
}
function getChildren(all, parent) {
var arr = [], isBreak = false, firstTr;
all.each(function (_, v) {
// 过滤非tr标签
if (! isTr(v) || isBreak) return;
firstTr || (firstTr = $(v));
// 非连续的子节点
if (firstTr && ! isChildren(parent, firstTr)) {
return;
}
if (isChildren(parent, v)) {
arr.push(v)
} else {
isBreak = true;
}
});
return arr;
}
function swapable(_o, tier) {
if (
_o
&& _o.length
&& tier === getTier(_o)
) {
return true
}
}
function sibling(all, tier) {
var next;
all.each(function (_, v) {
if (getTier(v) === tier && ! next && isTr(v)) {
next = $(v);
}
});
return next;
}
Dcat.grid.Tree = function (opts) {
return new Tree(opts);
};
Dcat.grid.Orderable = function (opts) {
return new Orderable(opts);
};
Dcat.grid.AsyncTable =function (opts) {
return new AsyncTable(opts)
}
})(window, jQuery);