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.

group_rows.js 28KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. /* Tabulator v4.8.2 (c) Oliver Folkerd */
  2. //public group object
  3. var GroupComponent = function GroupComponent(group) {
  4. this._group = group;
  5. this.type = "GroupComponent";
  6. };
  7. GroupComponent.prototype.getKey = function () {
  8. return this._group.key;
  9. };
  10. GroupComponent.prototype.getField = function () {
  11. return this._group.field;
  12. };
  13. GroupComponent.prototype.getElement = function () {
  14. return this._group.element;
  15. };
  16. GroupComponent.prototype.getRows = function () {
  17. return this._group.getRows(true);
  18. };
  19. GroupComponent.prototype.getSubGroups = function () {
  20. return this._group.getSubGroups(true);
  21. };
  22. GroupComponent.prototype.getParentGroup = function () {
  23. return this._group.parent ? this._group.parent.getComponent() : false;
  24. };
  25. GroupComponent.prototype.getVisibility = function () {
  26. console.warn("getVisibility function is deprecated, you should now use the isVisible function");
  27. return this._group.visible;
  28. };
  29. GroupComponent.prototype.isVisible = function () {
  30. return this._group.visible;
  31. };
  32. GroupComponent.prototype.show = function () {
  33. this._group.show();
  34. };
  35. GroupComponent.prototype.hide = function () {
  36. this._group.hide();
  37. };
  38. GroupComponent.prototype.toggle = function () {
  39. this._group.toggleVisibility();
  40. };
  41. GroupComponent.prototype._getSelf = function () {
  42. return this._group;
  43. };
  44. GroupComponent.prototype.getTable = function () {
  45. return this._group.groupManager.table;
  46. };
  47. //////////////////////////////////////////////////
  48. //////////////// Group Functions /////////////////
  49. //////////////////////////////////////////////////
  50. var Group = function Group(groupManager, parent, level, key, field, generator, oldGroup) {
  51. this.groupManager = groupManager;
  52. this.parent = parent;
  53. this.key = key;
  54. this.level = level;
  55. this.field = field;
  56. this.hasSubGroups = level < groupManager.groupIDLookups.length - 1;
  57. this.addRow = this.hasSubGroups ? this._addRowToGroup : this._addRow;
  58. this.type = "group"; //type of element
  59. this.old = oldGroup;
  60. this.rows = [];
  61. this.groups = [];
  62. this.groupList = [];
  63. this.generator = generator;
  64. this.elementContents = false;
  65. this.height = 0;
  66. this.outerHeight = 0;
  67. this.initialized = false;
  68. this.calcs = {};
  69. this.initialized = false;
  70. this.modules = {};
  71. this.arrowElement = false;
  72. this.visible = oldGroup ? oldGroup.visible : typeof groupManager.startOpen[level] !== "undefined" ? groupManager.startOpen[level] : groupManager.startOpen[0];
  73. this.component = null;
  74. this.createElements();
  75. this.addBindings();
  76. this.createValueGroups();
  77. };
  78. Group.prototype.wipe = function () {
  79. if (this.groupList.length) {
  80. this.groupList.forEach(function (group) {
  81. group.wipe();
  82. });
  83. } else {
  84. this.element = false;
  85. this.arrowElement = false;
  86. this.elementContents = false;
  87. }
  88. };
  89. Group.prototype.createElements = function () {
  90. var arrow = document.createElement("div");
  91. arrow.classList.add("tabulator-arrow");
  92. this.element = document.createElement("div");
  93. this.element.classList.add("tabulator-row");
  94. this.element.classList.add("tabulator-group");
  95. this.element.classList.add("tabulator-group-level-" + this.level);
  96. this.element.setAttribute("role", "rowgroup");
  97. this.arrowElement = document.createElement("div");
  98. this.arrowElement.classList.add("tabulator-group-toggle");
  99. this.arrowElement.appendChild(arrow);
  100. //setup movable rows
  101. if (this.groupManager.table.options.movableRows !== false && this.groupManager.table.modExists("moveRow")) {
  102. this.groupManager.table.modules.moveRow.initializeGroupHeader(this);
  103. }
  104. };
  105. Group.prototype.createValueGroups = function () {
  106. var _this = this;
  107. var level = this.level + 1;
  108. if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
  109. this.groupManager.allowedValues[level].forEach(function (value) {
  110. _this._createGroup(value, level);
  111. });
  112. }
  113. };
  114. Group.prototype.addBindings = function () {
  115. var self = this,
  116. dblTap,
  117. tapHold,
  118. tap,
  119. toggleElement;
  120. //handle group click events
  121. if (self.groupManager.table.options.groupClick) {
  122. self.element.addEventListener("click", function (e) {
  123. self.groupManager.table.options.groupClick.call(self.groupManager.table, e, self.getComponent());
  124. });
  125. }
  126. if (self.groupManager.table.options.groupDblClick) {
  127. self.element.addEventListener("dblclick", function (e) {
  128. self.groupManager.table.options.groupDblClick.call(self.groupManager.table, e, self.getComponent());
  129. });
  130. }
  131. if (self.groupManager.table.options.groupContext) {
  132. self.element.addEventListener("contextmenu", function (e) {
  133. self.groupManager.table.options.groupContext.call(self.groupManager.table, e, self.getComponent());
  134. });
  135. }
  136. if ((self.groupManager.table.options.groupContextMenu || self.groupManager.table.options.groupClickMenu) && self.groupManager.table.modExists("menu")) {
  137. self.groupManager.table.modules.menu.initializeGroup.call(self.groupManager.table.modules.menu, self);
  138. }
  139. if (self.groupManager.table.options.groupTap) {
  140. tap = false;
  141. self.element.addEventListener("touchstart", function (e) {
  142. tap = true;
  143. }, { passive: true });
  144. self.element.addEventListener("touchend", function (e) {
  145. if (tap) {
  146. self.groupManager.table.options.groupTap(e, self.getComponent());
  147. }
  148. tap = false;
  149. });
  150. }
  151. if (self.groupManager.table.options.groupDblTap) {
  152. dblTap = null;
  153. self.element.addEventListener("touchend", function (e) {
  154. if (dblTap) {
  155. clearTimeout(dblTap);
  156. dblTap = null;
  157. self.groupManager.table.options.groupDblTap(e, self.getComponent());
  158. } else {
  159. dblTap = setTimeout(function () {
  160. clearTimeout(dblTap);
  161. dblTap = null;
  162. }, 300);
  163. }
  164. });
  165. }
  166. if (self.groupManager.table.options.groupTapHold) {
  167. tapHold = null;
  168. self.element.addEventListener("touchstart", function (e) {
  169. clearTimeout(tapHold);
  170. tapHold = setTimeout(function () {
  171. clearTimeout(tapHold);
  172. tapHold = null;
  173. tap = false;
  174. self.groupManager.table.options.groupTapHold(e, self.getComponent());
  175. }, 1000);
  176. }, { passive: true });
  177. self.element.addEventListener("touchend", function (e) {
  178. clearTimeout(tapHold);
  179. tapHold = null;
  180. });
  181. }
  182. if (self.groupManager.table.options.groupToggleElement) {
  183. toggleElement = self.groupManager.table.options.groupToggleElement == "arrow" ? self.arrowElement : self.element;
  184. toggleElement.addEventListener("click", function (e) {
  185. e.stopPropagation();
  186. e.stopImmediatePropagation();
  187. self.toggleVisibility();
  188. });
  189. }
  190. };
  191. Group.prototype._createGroup = function (groupID, level) {
  192. var groupKey = level + "_" + groupID;
  193. var group = new Group(this.groupManager, this, level, groupID, this.groupManager.groupIDLookups[level].field, this.groupManager.headerGenerator[level] || this.groupManager.headerGenerator[0], this.old ? this.old.groups[groupKey] : false);
  194. this.groups[groupKey] = group;
  195. this.groupList.push(group);
  196. };
  197. Group.prototype._addRowToGroup = function (row) {
  198. var level = this.level + 1;
  199. if (this.hasSubGroups) {
  200. var groupID = this.groupManager.groupIDLookups[level].func(row.getData()),
  201. groupKey = level + "_" + groupID;
  202. if (this.groupManager.allowedValues && this.groupManager.allowedValues[level]) {
  203. if (this.groups[groupKey]) {
  204. this.groups[groupKey].addRow(row);
  205. }
  206. } else {
  207. if (!this.groups[groupKey]) {
  208. this._createGroup(groupID, level);
  209. }
  210. this.groups[groupKey].addRow(row);
  211. }
  212. }
  213. };
  214. Group.prototype._addRow = function (row) {
  215. this.rows.push(row);
  216. row.modules.group = this;
  217. };
  218. Group.prototype.insertRow = function (row, to, after) {
  219. var data = this.conformRowData({});
  220. row.updateData(data);
  221. var toIndex = this.rows.indexOf(to);
  222. if (toIndex > -1) {
  223. if (after) {
  224. this.rows.splice(toIndex + 1, 0, row);
  225. } else {
  226. this.rows.splice(toIndex, 0, row);
  227. }
  228. } else {
  229. if (after) {
  230. this.rows.push(row);
  231. } else {
  232. this.rows.unshift(row);
  233. }
  234. }
  235. row.modules.group = this;
  236. this.generateGroupHeaderContents();
  237. if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
  238. this.groupManager.table.modules.columnCalcs.recalcGroup(this);
  239. }
  240. this.groupManager.updateGroupRows(true);
  241. };
  242. Group.prototype.scrollHeader = function (left) {
  243. this.arrowElement.style.marginLeft = left;
  244. this.groupList.forEach(function (child) {
  245. child.scrollHeader(left);
  246. });
  247. };
  248. Group.prototype.getRowIndex = function (row) {};
  249. //update row data to match grouping contraints
  250. Group.prototype.conformRowData = function (data) {
  251. if (this.field) {
  252. data[this.field] = this.key;
  253. } else {
  254. console.warn("Data Conforming Error - Cannot conform row data to match new group as groupBy is a function");
  255. }
  256. if (this.parent) {
  257. data = this.parent.conformRowData(data);
  258. }
  259. return data;
  260. };
  261. Group.prototype.removeRow = function (row) {
  262. var index = this.rows.indexOf(row);
  263. var el = row.getElement();
  264. if (index > -1) {
  265. this.rows.splice(index, 1);
  266. }
  267. if (!this.groupManager.table.options.groupValues && !this.rows.length) {
  268. if (this.parent) {
  269. this.parent.removeGroup(this);
  270. } else {
  271. this.groupManager.removeGroup(this);
  272. }
  273. this.groupManager.updateGroupRows(true);
  274. } else {
  275. if (el.parentNode) {
  276. el.parentNode.removeChild(el);
  277. }
  278. this.generateGroupHeaderContents();
  279. if (this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table") {
  280. this.groupManager.table.modules.columnCalcs.recalcGroup(this);
  281. }
  282. }
  283. };
  284. Group.prototype.removeGroup = function (group) {
  285. var groupKey = group.level + "_" + group.key,
  286. index;
  287. if (this.groups[groupKey]) {
  288. delete this.groups[groupKey];
  289. index = this.groupList.indexOf(group);
  290. if (index > -1) {
  291. this.groupList.splice(index, 1);
  292. }
  293. if (!this.groupList.length) {
  294. if (this.parent) {
  295. this.parent.removeGroup(this);
  296. } else {
  297. this.groupManager.removeGroup(this);
  298. }
  299. }
  300. }
  301. };
  302. Group.prototype.getHeadersAndRows = function (noCalc) {
  303. var output = [];
  304. output.push(this);
  305. this._visSet();
  306. if (this.visible) {
  307. if (this.groupList.length) {
  308. this.groupList.forEach(function (group) {
  309. output = output.concat(group.getHeadersAndRows(noCalc));
  310. });
  311. } else {
  312. if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
  313. if (this.calcs.top) {
  314. this.calcs.top.detachElement();
  315. this.calcs.top.deleteCells();
  316. }
  317. this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
  318. output.push(this.calcs.top);
  319. }
  320. output = output.concat(this.rows);
  321. if (!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
  322. if (this.calcs.bottom) {
  323. this.calcs.bottom.detachElement();
  324. this.calcs.bottom.deleteCells();
  325. }
  326. this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
  327. output.push(this.calcs.bottom);
  328. }
  329. }
  330. } else {
  331. if (!this.groupList.length && this.groupManager.table.options.columnCalcs != "table") {
  332. if (this.groupManager.table.modExists("columnCalcs")) {
  333. if (!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()) {
  334. if (this.calcs.top) {
  335. this.calcs.top.detachElement();
  336. this.calcs.top.deleteCells();
  337. }
  338. if (this.groupManager.table.options.groupClosedShowCalcs) {
  339. this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows);
  340. output.push(this.calcs.top);
  341. }
  342. }
  343. if (!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()) {
  344. if (this.calcs.bottom) {
  345. this.calcs.bottom.detachElement();
  346. this.calcs.bottom.deleteCells();
  347. }
  348. if (this.groupManager.table.options.groupClosedShowCalcs) {
  349. this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows);
  350. output.push(this.calcs.bottom);
  351. }
  352. }
  353. }
  354. }
  355. }
  356. return output;
  357. };
  358. Group.prototype.getData = function (visible, transform) {
  359. var self = this,
  360. output = [];
  361. this._visSet();
  362. if (!visible || visible && this.visible) {
  363. this.rows.forEach(function (row) {
  364. output.push(row.getData(transform || "data"));
  365. });
  366. }
  367. return output;
  368. };
  369. // Group.prototype.getRows = function(){
  370. // this._visSet();
  371. // return this.visible ? this.rows : [];
  372. // };
  373. Group.prototype.getRowCount = function () {
  374. var count = 0;
  375. if (this.groupList.length) {
  376. this.groupList.forEach(function (group) {
  377. count += group.getRowCount();
  378. });
  379. } else {
  380. count = this.rows.length;
  381. }
  382. return count;
  383. };
  384. Group.prototype.toggleVisibility = function () {
  385. if (this.visible) {
  386. this.hide();
  387. } else {
  388. this.show();
  389. }
  390. };
  391. Group.prototype.hide = function () {
  392. this.visible = false;
  393. if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
  394. this.element.classList.remove("tabulator-group-visible");
  395. if (this.groupList.length) {
  396. this.groupList.forEach(function (group) {
  397. var rows = group.getHeadersAndRows();
  398. rows.forEach(function (row) {
  399. row.detachElement();
  400. });
  401. });
  402. } else {
  403. this.rows.forEach(function (row) {
  404. var rowEl = row.getElement();
  405. rowEl.parentNode.removeChild(rowEl);
  406. });
  407. }
  408. this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
  409. this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
  410. } else {
  411. this.groupManager.updateGroupRows(true);
  412. }
  413. this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), false);
  414. };
  415. Group.prototype.show = function () {
  416. var self = this;
  417. self.visible = true;
  418. if (this.groupManager.table.rowManager.getRenderMode() == "classic" && !this.groupManager.table.options.pagination) {
  419. this.element.classList.add("tabulator-group-visible");
  420. var prev = self.getElement();
  421. if (this.groupList.length) {
  422. this.groupList.forEach(function (group) {
  423. var rows = group.getHeadersAndRows();
  424. rows.forEach(function (row) {
  425. var rowEl = row.getElement();
  426. prev.parentNode.insertBefore(rowEl, prev.nextSibling);
  427. row.initialize();
  428. prev = rowEl;
  429. });
  430. });
  431. } else {
  432. self.rows.forEach(function (row) {
  433. var rowEl = row.getElement();
  434. prev.parentNode.insertBefore(rowEl, prev.nextSibling);
  435. row.initialize();
  436. prev = rowEl;
  437. });
  438. }
  439. this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex());
  440. this.groupManager.table.rowManager.checkClassicModeGroupHeaderWidth();
  441. } else {
  442. this.groupManager.updateGroupRows(true);
  443. }
  444. this.groupManager.table.options.groupVisibilityChanged.call(this.table, this.getComponent(), true);
  445. };
  446. Group.prototype._visSet = function () {
  447. var data = [];
  448. if (typeof this.visible == "function") {
  449. this.rows.forEach(function (row) {
  450. data.push(row.getData());
  451. });
  452. this.visible = this.visible(this.key, this.getRowCount(), data, this.getComponent());
  453. }
  454. };
  455. Group.prototype.getRowGroup = function (row) {
  456. var match = false;
  457. if (this.groupList.length) {
  458. this.groupList.forEach(function (group) {
  459. var result = group.getRowGroup(row);
  460. if (result) {
  461. match = result;
  462. }
  463. });
  464. } else {
  465. if (this.rows.find(function (item) {
  466. return item === row;
  467. })) {
  468. match = this;
  469. }
  470. }
  471. return match;
  472. };
  473. Group.prototype.getSubGroups = function (component) {
  474. var output = [];
  475. this.groupList.forEach(function (child) {
  476. output.push(component ? child.getComponent() : child);
  477. });
  478. return output;
  479. };
  480. Group.prototype.getRows = function (compoment) {
  481. var output = [];
  482. this.rows.forEach(function (row) {
  483. output.push(compoment ? row.getComponent() : row);
  484. });
  485. return output;
  486. };
  487. Group.prototype.generateGroupHeaderContents = function () {
  488. var data = [];
  489. this.rows.forEach(function (row) {
  490. data.push(row.getData());
  491. });
  492. this.elementContents = this.generator(this.key, this.getRowCount(), data, this.getComponent());
  493. while (this.element.firstChild) {
  494. this.element.removeChild(this.element.firstChild);
  495. }if (typeof this.elementContents === "string") {
  496. this.element.innerHTML = this.elementContents;
  497. } else {
  498. this.element.appendChild(this.elementContents);
  499. }
  500. this.element.insertBefore(this.arrowElement, this.element.firstChild);
  501. };
  502. Group.prototype.getPath = function () {
  503. var path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  504. path.unshift(this.key);
  505. if (this.parent) {
  506. this.parent.getPath(path);
  507. }
  508. return path;
  509. };
  510. ////////////// Standard Row Functions //////////////
  511. Group.prototype.getElement = function () {
  512. this.addBindingsd = false;
  513. this._visSet();
  514. if (this.visible) {
  515. this.element.classList.add("tabulator-group-visible");
  516. } else {
  517. this.element.classList.remove("tabulator-group-visible");
  518. }
  519. for (var i = 0; i < this.element.childNodes.length; ++i) {
  520. this.element.childNodes[i].parentNode.removeChild(this.element.childNodes[i]);
  521. }
  522. this.generateGroupHeaderContents();
  523. // this.addBindings();
  524. return this.element;
  525. };
  526. Group.prototype.detachElement = function () {
  527. if (this.element && this.element.parentNode) {
  528. this.element.parentNode.removeChild(this.element);
  529. }
  530. };
  531. //normalize the height of elements in the row
  532. Group.prototype.normalizeHeight = function () {
  533. this.setHeight(this.element.clientHeight);
  534. };
  535. Group.prototype.initialize = function (force) {
  536. if (!this.initialized || force) {
  537. this.normalizeHeight();
  538. this.initialized = true;
  539. }
  540. };
  541. Group.prototype.reinitialize = function () {
  542. this.initialized = false;
  543. this.height = 0;
  544. if (Tabulator.prototype.helpers.elVisible(this.element)) {
  545. this.initialize(true);
  546. }
  547. };
  548. Group.prototype.setHeight = function (height) {
  549. if (this.height != height) {
  550. this.height = height;
  551. this.outerHeight = this.element.offsetHeight;
  552. }
  553. };
  554. //return rows outer height
  555. Group.prototype.getHeight = function () {
  556. return this.outerHeight;
  557. };
  558. Group.prototype.getGroup = function () {
  559. return this;
  560. };
  561. Group.prototype.reinitializeHeight = function () {};
  562. Group.prototype.calcHeight = function () {};
  563. Group.prototype.setCellHeight = function () {};
  564. Group.prototype.clearCellHeight = function () {};
  565. //////////////// Object Generation /////////////////
  566. Group.prototype.getComponent = function () {
  567. if (!this.component) {
  568. this.component = new GroupComponent(this);
  569. }
  570. return this.component;
  571. };
  572. //////////////////////////////////////////////////
  573. ////////////// Group Row Extension ///////////////
  574. //////////////////////////////////////////////////
  575. var GroupRows = function GroupRows(table) {
  576. this.table = table; //hold Tabulator object
  577. this.groupIDLookups = false; //enable table grouping and set field to group by
  578. this.startOpen = [function () {
  579. return false;
  580. }]; //starting state of group
  581. this.headerGenerator = [function () {
  582. return "";
  583. }];
  584. this.groupList = []; //ordered list of groups
  585. this.allowedValues = false;
  586. this.groups = {}; //hold row groups
  587. this.displayIndex = 0; //index in display pipeline
  588. };
  589. //initialize group configuration
  590. GroupRows.prototype.initialize = function () {
  591. var self = this,
  592. groupBy = self.table.options.groupBy,
  593. startOpen = self.table.options.groupStartOpen,
  594. groupHeader = self.table.options.groupHeader;
  595. this.allowedValues = self.table.options.groupValues;
  596. if (Array.isArray(groupBy) && Array.isArray(groupHeader) && groupBy.length > groupHeader.length) {
  597. console.warn("Error creating group headers, groupHeader array is shorter than groupBy array");
  598. }
  599. self.headerGenerator = [function () {
  600. return "";
  601. }];
  602. this.startOpen = [function () {
  603. return false;
  604. }]; //starting state of group
  605. self.table.modules.localize.bind("groups|item", function (langValue, lang) {
  606. self.headerGenerator[0] = function (value, count, data) {
  607. //header layout function
  608. return (typeof value === "undefined" ? "" : value) + "<span>(" + count + " " + (count === 1 ? langValue : lang.groups.items) + ")</span>";
  609. };
  610. });
  611. this.groupIDLookups = [];
  612. if (Array.isArray(groupBy) || groupBy) {
  613. if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "table" && this.table.options.columnCalcs != "both") {
  614. this.table.modules.columnCalcs.removeCalcs();
  615. }
  616. } else {
  617. if (this.table.modExists("columnCalcs") && this.table.options.columnCalcs != "group") {
  618. var cols = this.table.columnManager.getRealColumns();
  619. cols.forEach(function (col) {
  620. if (col.definition.topCalc) {
  621. self.table.modules.columnCalcs.initializeTopRow();
  622. }
  623. if (col.definition.bottomCalc) {
  624. self.table.modules.columnCalcs.initializeBottomRow();
  625. }
  626. });
  627. }
  628. }
  629. if (!Array.isArray(groupBy)) {
  630. groupBy = [groupBy];
  631. }
  632. groupBy.forEach(function (group, i) {
  633. var lookupFunc, column;
  634. if (typeof group == "function") {
  635. lookupFunc = group;
  636. } else {
  637. column = self.table.columnManager.getColumnByField(group);
  638. if (column) {
  639. lookupFunc = function lookupFunc(data) {
  640. return column.getFieldValue(data);
  641. };
  642. } else {
  643. lookupFunc = function lookupFunc(data) {
  644. return data[group];
  645. };
  646. }
  647. }
  648. self.groupIDLookups.push({
  649. field: typeof group === "function" ? false : group,
  650. func: lookupFunc,
  651. values: self.allowedValues ? self.allowedValues[i] : false
  652. });
  653. });
  654. if (startOpen) {
  655. if (!Array.isArray(startOpen)) {
  656. startOpen = [startOpen];
  657. }
  658. startOpen.forEach(function (level) {
  659. level = typeof level == "function" ? level : function () {
  660. return true;
  661. };
  662. });
  663. self.startOpen = startOpen;
  664. }
  665. if (groupHeader) {
  666. self.headerGenerator = Array.isArray(groupHeader) ? groupHeader : [groupHeader];
  667. }
  668. this.initialized = true;
  669. };
  670. GroupRows.prototype.setDisplayIndex = function (index) {
  671. this.displayIndex = index;
  672. };
  673. GroupRows.prototype.getDisplayIndex = function () {
  674. return this.displayIndex;
  675. };
  676. //return appropriate rows with group headers
  677. GroupRows.prototype.getRows = function (rows) {
  678. if (this.groupIDLookups.length) {
  679. this.table.options.dataGrouping.call(this.table);
  680. this.generateGroups(rows);
  681. if (this.table.options.dataGrouped) {
  682. this.table.options.dataGrouped.call(this.table, this.getGroups(true));
  683. }
  684. return this.updateGroupRows();
  685. } else {
  686. return rows.slice(0);
  687. }
  688. };
  689. GroupRows.prototype.getGroups = function (compoment) {
  690. var groupComponents = [];
  691. this.groupList.forEach(function (group) {
  692. groupComponents.push(compoment ? group.getComponent() : group);
  693. });
  694. return groupComponents;
  695. };
  696. GroupRows.prototype.getChildGroups = function (group) {
  697. var _this2 = this;
  698. var groupComponents = [];
  699. if (!group) {
  700. group = this;
  701. }
  702. group.groupList.forEach(function (child) {
  703. if (child.groupList.length) {
  704. groupComponents = groupComponents.concat(_this2.getChildGroups(child));
  705. } else {
  706. groupComponents.push(child);
  707. }
  708. });
  709. return groupComponents;
  710. };
  711. GroupRows.prototype.wipe = function () {
  712. this.groupList.forEach(function (group) {
  713. group.wipe();
  714. });
  715. };
  716. GroupRows.prototype.pullGroupListData = function (groupList) {
  717. var self = this;
  718. var groupListData = [];
  719. groupList.forEach(function (group) {
  720. var groupHeader = {};
  721. groupHeader.level = 0;
  722. groupHeader.rowCount = 0;
  723. groupHeader.headerContent = "";
  724. var childData = [];
  725. if (group.hasSubGroups) {
  726. childData = self.pullGroupListData(group.groupList);
  727. groupHeader.level = group.level;
  728. groupHeader.rowCount = childData.length - group.groupList.length; // data length minus number of sub-headers
  729. groupHeader.headerContent = group.generator(group.key, groupHeader.rowCount, group.rows, group);
  730. groupListData.push(groupHeader);
  731. groupListData = groupListData.concat(childData);
  732. } else {
  733. groupHeader.level = group.level;
  734. groupHeader.headerContent = group.generator(group.key, group.rows.length, group.rows, group);
  735. groupHeader.rowCount = group.getRows().length;
  736. groupListData.push(groupHeader);
  737. group.getRows().forEach(function (row) {
  738. groupListData.push(row.getData("data"));
  739. });
  740. }
  741. });
  742. return groupListData;
  743. };
  744. GroupRows.prototype.getGroupedData = function () {
  745. return this.pullGroupListData(this.groupList);
  746. };
  747. GroupRows.prototype.getRowGroup = function (row) {
  748. var match = false;
  749. this.groupList.forEach(function (group) {
  750. var result = group.getRowGroup(row);
  751. if (result) {
  752. match = result;
  753. }
  754. });
  755. return match;
  756. };
  757. GroupRows.prototype.countGroups = function () {
  758. return this.groupList.length;
  759. };
  760. GroupRows.prototype.generateGroups = function (rows) {
  761. var self = this,
  762. oldGroups = self.groups;
  763. self.groups = {};
  764. self.groupList = [];
  765. if (this.allowedValues && this.allowedValues[0]) {
  766. this.allowedValues[0].forEach(function (value) {
  767. self.createGroup(value, 0, oldGroups);
  768. });
  769. rows.forEach(function (row) {
  770. self.assignRowToExistingGroup(row, oldGroups);
  771. });
  772. } else {
  773. rows.forEach(function (row) {
  774. self.assignRowToGroup(row, oldGroups);
  775. });
  776. }
  777. };
  778. GroupRows.prototype.createGroup = function (groupID, level, oldGroups) {
  779. var groupKey = level + "_" + groupID,
  780. group;
  781. oldGroups = oldGroups || [];
  782. group = new Group(this, false, level, groupID, this.groupIDLookups[0].field, this.headerGenerator[0], oldGroups[groupKey]);
  783. this.groups[groupKey] = group;
  784. this.groupList.push(group);
  785. };
  786. // GroupRows.prototype.assignRowToGroup = function(row, oldGroups){
  787. // var groupID = this.groupIDLookups[0].func(row.getData()),
  788. // groupKey = "0_" + groupID;
  789. // if(!this.groups[groupKey]){
  790. // this.createGroup(groupID, 0, oldGroups);
  791. // }
  792. // this.groups[groupKey].addRow(row);
  793. // };
  794. GroupRows.prototype.assignRowToExistingGroup = function (row, oldGroups) {
  795. var groupID = this.groupIDLookups[0].func(row.getData()),
  796. groupKey = "0_" + groupID;
  797. if (this.groups[groupKey]) {
  798. this.groups[groupKey].addRow(row);
  799. }
  800. };
  801. GroupRows.prototype.assignRowToGroup = function (row, oldGroups) {
  802. var groupID = this.groupIDLookups[0].func(row.getData()),
  803. newGroupNeeded = !this.groups["0_" + groupID];
  804. if (newGroupNeeded) {
  805. this.createGroup(groupID, 0, oldGroups);
  806. }
  807. this.groups["0_" + groupID].addRow(row);
  808. return !newGroupNeeded;
  809. };
  810. GroupRows.prototype.reassignRowToGroup = function (row) {
  811. var oldRowGroup = row.getGroup(),
  812. oldGroupPath = oldRowGroup.getPath(),
  813. newGroupPath = this.getExpectedPath(row),
  814. samePath = true;
  815. // figure out if new group path is the same as old group path
  816. var samePath = oldGroupPath.length == newGroupPath.length && oldGroupPath.every(function (element, index) {
  817. return element === newGroupPath[index];
  818. });
  819. // refresh if they new path and old path aren't the same (aka the row's groupings have changed)
  820. if (!samePath) {
  821. oldRowGroup.removeRow(row);
  822. this.assignRowToGroup(row, self.groups);
  823. this.table.rowManager.refreshActiveData("group", false, true);
  824. }
  825. };
  826. GroupRows.prototype.getExpectedPath = function (row) {
  827. var groupPath = [],
  828. rowData = row.getData();
  829. this.groupIDLookups.forEach(function (groupId) {
  830. groupPath.push(groupId.func(rowData));
  831. });
  832. return groupPath;
  833. };
  834. GroupRows.prototype.updateGroupRows = function (force) {
  835. var self = this,
  836. output = [],
  837. oldRowCount;
  838. self.groupList.forEach(function (group) {
  839. output = output.concat(group.getHeadersAndRows());
  840. });
  841. //force update of table display
  842. if (force) {
  843. var displayIndex = self.table.rowManager.setDisplayRows(output, this.getDisplayIndex());
  844. if (displayIndex !== true) {
  845. this.setDisplayIndex(displayIndex);
  846. }
  847. self.table.rowManager.refreshActiveData("group", true, true);
  848. }
  849. return output;
  850. };
  851. GroupRows.prototype.scrollHeaders = function (left) {
  852. if (this.table.options.virtualDomHoz) {
  853. left -= this.table.vdomHoz.vDomPadLeft;
  854. }
  855. left = left + "px";
  856. this.groupList.forEach(function (group) {
  857. group.scrollHeader(left);
  858. });
  859. };
  860. GroupRows.prototype.removeGroup = function (group) {
  861. var groupKey = group.level + "_" + group.key,
  862. index;
  863. if (this.groups[groupKey]) {
  864. delete this.groups[groupKey];
  865. index = this.groupList.indexOf(group);
  866. if (index > -1) {
  867. this.groupList.splice(index, 1);
  868. }
  869. }
  870. };
  871. Tabulator.prototype.registerModule("groupRows", GroupRows);