Tree.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /**
  2. * 树形表格
  3. */
  4. export default class Tree {
  5. constructor(Helper, opts) {
  6. this.options = $.extend({
  7. button: null,
  8. table: null,
  9. url: '',
  10. perPage: '',
  11. showNextPage: '',
  12. pageQueryName: '',
  13. parentIdQueryName: '',
  14. depthQueryName: '',
  15. showIcon: 'fa-angle-right',
  16. hideIcon: 'fa-angle-down',
  17. loadMoreIcon: '<i class="feather icon-more-horizontal"></i>',
  18. }, opts);
  19. this.helper = Helper;
  20. this.key = this.depth = this.row = this.data = this._req = null;
  21. this._init();
  22. }
  23. // 绑定点击事件
  24. _init () {
  25. var _this = this,
  26. opts = _this.options;
  27. $(opts.button).off('click').click(function () {
  28. if (_this._req) {
  29. return;
  30. }
  31. var $this = $(this),
  32. _i = $("i", this),
  33. shown = _i.hasClass(opts.showIcon);
  34. _this.key = $this.data('key');
  35. _this.depth = $this.data('depth');
  36. _this.row = $this.closest('tr');
  37. if ($this.data('inserted') == '0') {
  38. _this.request(1);
  39. $this.data('inserted', 1);
  40. }
  41. _i.toggleClass(opts.showIcon + ' ' + opts.hideIcon);
  42. var children = [];
  43. _this.helper.getChildren(_this.row.nextAll(), _this.row).forEach(function (v) {
  44. if (_this.helper.getDepth(v) !== (_this.depth + 1)) {
  45. return;
  46. }
  47. children.push(v);
  48. shown ? $(v).show() : $(v).hide();
  49. });
  50. children.forEach(function (v) {
  51. if (shown) {
  52. return
  53. }
  54. var icon = $(v).find('a[data-depth=' + _this.helper.getDepth(v) + '] i');
  55. if (icon.hasClass(opts.hideIcon)) {
  56. icon.parent().click();
  57. }
  58. })
  59. })
  60. }
  61. // 发起请求
  62. request (page, after) {
  63. var _this = this,
  64. row = _this.row,
  65. key = _this.key,
  66. depth = _this.depth,
  67. tableSelector = _this.options.table;
  68. if (_this._req) {
  69. return;
  70. }
  71. _this._req = 1;
  72. Dcat.loading();
  73. var data = {};
  74. data[_this.options.parentIdQueryName] = key;
  75. data[_this.options.depthQueryName] = depth + 1;
  76. data[_this.options.pageQueryName.replace(':key', key)] = page;
  77. $.ajax({
  78. url: _this.options.url,
  79. type: 'GET',
  80. data: data,
  81. headers: {'X-PJAX': true},
  82. success: function (resp) {
  83. after && after();
  84. Dcat.loading(false);
  85. _this._req = 0;
  86. // 获取最后一行
  87. var children = _this.helper.getChildren(row.nextAll(), row);
  88. row = children.length ? $(children.pop()) : row;
  89. var _body = $('<div>'+resp+'</div>'),
  90. _tbody = _body.find(tableSelector + ' tbody'),
  91. lastPage = _body.find('last-page').text(),
  92. nextPage = _body.find('next-page').text();
  93. // 标记子节点行
  94. _tbody.find('tr').each(function (_, v) {
  95. $(v).attr('data-depth', depth + 1)
  96. });
  97. if (
  98. _this.options.showNextPage
  99. && _tbody.find('tr').length == _this.options.perPage
  100. && lastPage >= page
  101. ) {
  102. // 加载更多
  103. let loadMore = $(
  104. `<tr data-depth="${depth + 1}" data-page="${nextPage}">
  105. <td colspan="${row.find('td').length}" align="center" style="cursor: pointer">
  106. <a href="#" style="font-size: 1.5rem">${_this.options.loadMoreIcon}</a>
  107. </td>
  108. </tr>`
  109. );
  110. row.after(loadMore);
  111. // 加载更多
  112. loadMore.click(function () {
  113. var _t = $(this);
  114. _this.request(_t.data('page'), function () {
  115. _t.remove();
  116. });
  117. });
  118. }
  119. // 附加子节点
  120. row.after(_tbody.html());
  121. // 附加子节点js脚本以及触发子节点js脚本执行
  122. _body.find('script').each(function (_, v) {
  123. row.after(v);
  124. });
  125. // 主动触发ready事件,执行子节点附带的js脚本
  126. Dcat.triggerReady();
  127. },
  128. error:function(a, b, c){
  129. after && after();
  130. Dcat.loading(false);
  131. _this._req = 0;
  132. if (a.status != 404) {
  133. Dcat.handleAjaxError(a, b, c);
  134. }
  135. }
  136. });
  137. }
  138. }