Built files from Bizgaze WebServer
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.

responsive_layout.js 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /* Tabulator v4.8.2 (c) Oliver Folkerd */
  2. var ResponsiveLayout = function ResponsiveLayout(table) {
  3. this.table = table; //hold Tabulator object
  4. this.columns = [];
  5. this.hiddenColumns = [];
  6. this.mode = "";
  7. this.index = 0;
  8. this.collapseFormatter = [];
  9. this.collapseStartOpen = true;
  10. this.collapseHandleColumn = false;
  11. };
  12. //generate resposive columns list
  13. ResponsiveLayout.prototype.initialize = function () {
  14. var self = this,
  15. columns = [];
  16. this.mode = this.table.options.responsiveLayout;
  17. this.collapseFormatter = this.table.options.responsiveLayoutCollapseFormatter || this.formatCollapsedData;
  18. this.collapseStartOpen = this.table.options.responsiveLayoutCollapseStartOpen;
  19. this.hiddenColumns = [];
  20. //detemine level of responsivity for each column
  21. this.table.columnManager.columnsByIndex.forEach(function (column, i) {
  22. if (column.modules.responsive) {
  23. if (column.modules.responsive.order && column.modules.responsive.visible) {
  24. column.modules.responsive.index = i;
  25. columns.push(column);
  26. if (!column.visible && self.mode === "collapse") {
  27. self.hiddenColumns.push(column);
  28. }
  29. }
  30. }
  31. });
  32. //sort list by responsivity
  33. columns = columns.reverse();
  34. columns = columns.sort(function (a, b) {
  35. var diff = b.modules.responsive.order - a.modules.responsive.order;
  36. return diff || b.modules.responsive.index - a.modules.responsive.index;
  37. });
  38. this.columns = columns;
  39. if (this.mode === "collapse") {
  40. this.generateCollapsedContent();
  41. }
  42. //assign collapse column
  43. for (var _iterator = this.table.columnManager.columnsByIndex, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  44. var _ref;
  45. if (_isArray) {
  46. if (_i >= _iterator.length) break;
  47. _ref = _iterator[_i++];
  48. } else {
  49. _i = _iterator.next();
  50. if (_i.done) break;
  51. _ref = _i.value;
  52. }
  53. var col = _ref;
  54. if (col.definition.formatter == "responsiveCollapse") {
  55. this.collapseHandleColumn = col;
  56. break;
  57. }
  58. }
  59. if (this.collapseHandleColumn) {
  60. if (this.hiddenColumns.length) {
  61. this.collapseHandleColumn.show();
  62. } else {
  63. this.collapseHandleColumn.hide();
  64. }
  65. }
  66. };
  67. //define layout information
  68. ResponsiveLayout.prototype.initializeColumn = function (column) {
  69. var def = column.getDefinition();
  70. column.modules.responsive = { order: typeof def.responsive === "undefined" ? 1 : def.responsive, visible: def.visible === false ? false : true };
  71. };
  72. ResponsiveLayout.prototype.initializeRow = function (row) {
  73. var el;
  74. if (row.type !== "calc") {
  75. el = document.createElement("div");
  76. el.classList.add("tabulator-responsive-collapse");
  77. row.modules.responsiveLayout = {
  78. element: el,
  79. open: this.collapseStartOpen
  80. };
  81. if (!this.collapseStartOpen) {
  82. el.style.display = 'none';
  83. }
  84. }
  85. };
  86. ResponsiveLayout.prototype.layoutRow = function (row) {
  87. var rowEl = row.getElement();
  88. if (row.modules.responsiveLayout) {
  89. rowEl.appendChild(row.modules.responsiveLayout.element);
  90. this.generateCollapsedRowContent(row);
  91. }
  92. };
  93. //update column visibility
  94. ResponsiveLayout.prototype.updateColumnVisibility = function (column, visible) {
  95. var index;
  96. if (column.modules.responsive) {
  97. column.modules.responsive.visible = visible;
  98. this.initialize();
  99. }
  100. };
  101. ResponsiveLayout.prototype.hideColumn = function (column) {
  102. var colCount = this.hiddenColumns.length;
  103. column.hide(false, true);
  104. if (this.mode === "collapse") {
  105. this.hiddenColumns.unshift(column);
  106. this.generateCollapsedContent();
  107. if (this.collapseHandleColumn && !colCount) {
  108. this.collapseHandleColumn.show();
  109. }
  110. }
  111. };
  112. ResponsiveLayout.prototype.showColumn = function (column) {
  113. var index;
  114. column.show(false, true);
  115. //set column width to prevent calculation loops on uninitialized columns
  116. column.setWidth(column.getWidth());
  117. if (this.mode === "collapse") {
  118. index = this.hiddenColumns.indexOf(column);
  119. if (index > -1) {
  120. this.hiddenColumns.splice(index, 1);
  121. }
  122. this.generateCollapsedContent();
  123. if (this.collapseHandleColumn && !this.hiddenColumns.length) {
  124. this.collapseHandleColumn.hide();
  125. }
  126. }
  127. };
  128. //redraw columns to fit space
  129. ResponsiveLayout.prototype.update = function () {
  130. var self = this,
  131. working = true;
  132. while (working) {
  133. var width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
  134. var diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
  135. if (diff < 0) {
  136. //table is too wide
  137. var column = self.columns[self.index];
  138. if (column) {
  139. self.hideColumn(column);
  140. self.index++;
  141. } else {
  142. working = false;
  143. }
  144. } else {
  145. //table has spare space
  146. var _column = self.columns[self.index - 1];
  147. if (_column) {
  148. if (diff > 0) {
  149. if (diff >= _column.getWidth()) {
  150. self.showColumn(_column);
  151. self.index--;
  152. } else {
  153. working = false;
  154. }
  155. } else {
  156. working = false;
  157. }
  158. } else {
  159. working = false;
  160. }
  161. }
  162. if (!self.table.rowManager.activeRowsCount) {
  163. self.table.rowManager.renderEmptyScroll();
  164. }
  165. }
  166. };
  167. ResponsiveLayout.prototype.generateCollapsedContent = function () {
  168. var self = this,
  169. rows = this.table.rowManager.getDisplayRows();
  170. rows.forEach(function (row) {
  171. self.generateCollapsedRowContent(row);
  172. });
  173. };
  174. ResponsiveLayout.prototype.generateCollapsedRowContent = function (row) {
  175. var el, contents;
  176. if (row.modules.responsiveLayout) {
  177. el = row.modules.responsiveLayout.element;
  178. while (el.firstChild) {
  179. el.removeChild(el.firstChild);
  180. }contents = this.collapseFormatter(this.generateCollapsedRowData(row));
  181. if (contents) {
  182. el.appendChild(contents);
  183. }
  184. }
  185. };
  186. ResponsiveLayout.prototype.generateCollapsedRowData = function (row) {
  187. var self = this,
  188. data = row.getData(),
  189. output = [],
  190. mockCellComponent;
  191. this.hiddenColumns.forEach(function (column) {
  192. var value = column.getFieldValue(data);
  193. if (column.definition.title && column.field) {
  194. if (column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters) {
  195. mockCellComponent = {
  196. value: false,
  197. data: {},
  198. getValue: function getValue() {
  199. return value;
  200. },
  201. getData: function getData() {
  202. return data;
  203. },
  204. getElement: function getElement() {
  205. return document.createElement("div");
  206. },
  207. getRow: function getRow() {
  208. return row.getComponent();
  209. },
  210. getColumn: function getColumn() {
  211. return column.getComponent();
  212. }
  213. };
  214. output.push({
  215. title: column.definition.title,
  216. value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params)
  217. });
  218. } else {
  219. output.push({
  220. title: column.definition.title,
  221. value: value
  222. });
  223. }
  224. }
  225. });
  226. return output;
  227. };
  228. ResponsiveLayout.prototype.formatCollapsedData = function (data) {
  229. var list = document.createElement("table"),
  230. listContents = "";
  231. data.forEach(function (item) {
  232. var div = document.createElement("div");
  233. if (item.value instanceof Node) {
  234. div.appendChild(item.value);
  235. item.value = div.innerHTML;
  236. }
  237. listContents += "<tr><td><strong>" + item.title + "</strong></td><td>" + item.value + "</td></tr>";
  238. });
  239. list.innerHTML = listContents;
  240. return Object.keys(data).length ? list : "";
  241. };
  242. Tabulator.prototype.registerModule("responsiveLayout", ResponsiveLayout);