ui.scheduler.table_creator.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**
  2. * DevExtreme (ui/scheduler/ui.scheduler.table_creator.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var $ = require("../../core/renderer");
  11. var domAdapter = require("../../core/dom_adapter");
  12. var dataUtils = require("../../core/element_data");
  13. var typeUtils = require("../../core/utils/type");
  14. var getPublicElement = require("../../core/utils/dom").getPublicElement;
  15. var ROW_SELECTOR = "tr";
  16. var SchedulerTableCreator = {
  17. VERTICAL: "vertical",
  18. HORIZONTAL: "horizontal",
  19. insertAllDayRow: function(allDayElements, tableBody, index) {
  20. if (allDayElements[index]) {
  21. var row = allDayElements[index].find(ROW_SELECTOR);
  22. if (!row.length) {
  23. row = $(domAdapter.createElement(ROW_SELECTOR));
  24. row.append(allDayElements[index].get(0))
  25. }
  26. tableBody.appendChild(row.get ? row.get(0) : row)
  27. }
  28. },
  29. makeTable: function(options) {
  30. var tableBody = domAdapter.createElement("tbody");
  31. var templateCallbacks = [];
  32. var row;
  33. var rowCountInGroup = options.groupCount ? options.rowCount / options.groupCount : options.rowCount;
  34. var allDayElementIndex = 0;
  35. var allDayElements = options.allDayElements;
  36. var groupIndex = options.groupIndex;
  37. var rowCount = options.rowCount;
  38. $(options.container).append(tableBody);
  39. if (allDayElements) {
  40. this.insertAllDayRow(allDayElements, tableBody, 0);
  41. allDayElementIndex++
  42. }
  43. for (var i = 0; i < rowCount; i++) {
  44. row = domAdapter.createElement(ROW_SELECTOR);
  45. tableBody.appendChild(row);
  46. var isLastRowInGroup = (i + 1) % rowCountInGroup === 0;
  47. if (options.rowClass) {
  48. row.className = options.rowClass
  49. }
  50. for (var j = 0; j < options.cellCount; j++) {
  51. var td = domAdapter.createElement("td");
  52. row.appendChild(td);
  53. if (options.cellClass) {
  54. if (typeUtils.isFunction(options.cellClass)) {
  55. td.className = options.cellClass(i, j)
  56. } else {
  57. td.className = options.cellClass
  58. }
  59. }
  60. var cellDataObject;
  61. var dataKey;
  62. var dataValue;
  63. if (options.getCellData) {
  64. cellDataObject = options.getCellData(td, i, j, groupIndex);
  65. dataKey = cellDataObject.key;
  66. dataValue = cellDataObject.value;
  67. dataKey && dataUtils.data(td, dataKey, dataValue)
  68. }
  69. if (options.cellTemplate && options.cellTemplate.render) {
  70. var templateOptions = {
  71. model: {
  72. text: options.getCellText ? options.getCellText(i, j) : "",
  73. date: options.getCellDate ? options.getCellDate(i) : void 0
  74. },
  75. container: getPublicElement($(td)),
  76. index: i * options.cellCount + j
  77. };
  78. if (dataValue) {
  79. if (dataValue.startDate) {
  80. templateOptions.model.startDate = dataValue.startDate
  81. }
  82. if (dataValue.endDate) {
  83. templateOptions.model.endDate = dataValue.endDate
  84. }
  85. if (dataValue.groups) {
  86. templateOptions.model.groups = dataValue.groups
  87. }
  88. if (dataValue.allDay) {
  89. templateOptions.model.allDay = dataValue.allDay
  90. }
  91. }
  92. templateCallbacks.push(options.cellTemplate.render.bind(options.cellTemplate, templateOptions))
  93. } else {
  94. if (options.getCellText) {
  95. td.innerHTML = "<div>" + options.getCellText(i, j) + "</div>"
  96. }
  97. }
  98. }
  99. if (allDayElements && isLastRowInGroup) {
  100. this.insertAllDayRow(allDayElements, tableBody, allDayElementIndex);
  101. allDayElementIndex++
  102. }
  103. }
  104. return templateCallbacks
  105. },
  106. makeGroupedTable: function(type, groups, cssClasses, cellCount, cellTemplate, rowCount, groupByDate) {
  107. var rows = [];
  108. if (type === this.VERTICAL) {
  109. rows = this._makeVerticalGroupedRows(groups, cssClasses, cellTemplate, rowCount)
  110. } else {
  111. rows = this._makeHorizontalGroupedRows(groups, cssClasses, cellCount, cellTemplate, groupByDate)
  112. }
  113. return rows
  114. },
  115. makeGroupedTableFromJSON: function(type, data, config) {
  116. var table;
  117. var cellStorage = [];
  118. var rowIndex = 0;
  119. config = config || {};
  120. var cellTag = config.cellTag || "td";
  121. var childrenField = config.childrenField || "children";
  122. var titleField = config.titleField || "title";
  123. var groupTableClass = config.groupTableClass;
  124. var groupRowClass = config.groupRowClass;
  125. var groupCellClass = config.groupCellClass;
  126. var groupCellCustomContent = config.groupCellCustomContent;
  127. function createTable() {
  128. table = domAdapter.createElement("table");
  129. if (groupTableClass) {
  130. table.className = groupTableClass
  131. }
  132. }
  133. function getChildCount(item) {
  134. if (item[childrenField]) {
  135. return item[childrenField].length
  136. }
  137. return 0
  138. }
  139. function createCell(text, childCount, index, data) {
  140. var cell = {
  141. element: domAdapter.createElement(cellTag),
  142. childCount: childCount
  143. };
  144. if (groupCellClass) {
  145. cell.element.className = groupCellClass
  146. }
  147. var cellText = domAdapter.createTextNode(text);
  148. if ("function" === typeof groupCellCustomContent) {
  149. groupCellCustomContent(cell.element, cellText, index, data)
  150. } else {
  151. cell.element.appendChild(cellText)
  152. }
  153. return cell
  154. }
  155. function generateCells(data) {
  156. for (var i = 0; i < data.length; i++) {
  157. var childCount = getChildCount(data[i]);
  158. var cell = createCell(data[i][titleField], childCount, i, data[i]);
  159. if (!cellStorage[rowIndex]) {
  160. cellStorage[rowIndex] = []
  161. }
  162. cellStorage[rowIndex].push(cell);
  163. if (childCount) {
  164. generateCells(data[i][childrenField])
  165. } else {
  166. rowIndex++
  167. }
  168. }
  169. }
  170. function putCellsToRows() {
  171. cellStorage.forEach(function(cells) {
  172. var row = domAdapter.createElement(ROW_SELECTOR);
  173. if (groupRowClass) {
  174. row.className = groupRowClass
  175. }
  176. var rowspans = [];
  177. for (var i = cells.length - 1; i >= 0; i--) {
  178. var prev = cells[i + 1];
  179. var rowspan = cells[i].childCount;
  180. if (prev && prev.childCount) {
  181. rowspan *= prev.childCount
  182. }
  183. rowspans.push(rowspan)
  184. }
  185. rowspans.reverse();
  186. cells.forEach(function(cell, index) {
  187. if (rowspans[index]) {
  188. cell.element.setAttribute("rowSpan", rowspans[index])
  189. }
  190. row.appendChild(cell.element)
  191. });
  192. table.appendChild(row)
  193. })
  194. }
  195. createTable();
  196. generateCells(data);
  197. putCellsToRows();
  198. return table
  199. },
  200. _makeVerticalGroupedRows: function(groups, cssClasses, cellTemplate, rowCount) {
  201. var cellTemplates = [];
  202. var repeatCount = 1;
  203. var arr = [];
  204. var i;
  205. var cellIterator = function(cell) {
  206. if (cell.template) {
  207. cellTemplates.push(cell.template)
  208. }
  209. };
  210. for (i = 0; i < groups.length; i++) {
  211. if (i > 0) {
  212. repeatCount = groups[i - 1].items.length * repeatCount
  213. }
  214. var cells = this._makeGroupedRowCells(groups[i], repeatCount, cssClasses, cellTemplate);
  215. cells.forEach(cellIterator);
  216. arr.push(cells)
  217. }
  218. var rows = [];
  219. var groupCount = arr.length;
  220. var maxCellCount = arr[groupCount - 1].length;
  221. for (i = 0; i < maxCellCount; i++) {
  222. rows.push($("<tr>").addClass(cssClasses.groupHeaderRowClass))
  223. }
  224. for (i = groupCount - 1; i >= 0; i--) {
  225. var currentColumnLength = arr[i].length;
  226. var rowspan = maxCellCount / currentColumnLength;
  227. for (var j = 0; j < currentColumnLength; j++) {
  228. var currentRowIndex = j * rowspan;
  229. var row = rows[currentRowIndex];
  230. row.prepend(arr[i][j].element.attr("rowSpan", rowspan))
  231. }
  232. }
  233. return {
  234. elements: rows,
  235. cellTemplates: cellTemplates
  236. }
  237. },
  238. _makeHorizontalGroupedRows: function(groups, cssClasses, cellCount, cellTemplate, groupByDate) {
  239. var repeatCount = 1;
  240. var groupCount = groups.length;
  241. var rows = [];
  242. var cellTemplates = [];
  243. var repeatByDate = groupByDate ? cellCount : 1;
  244. var cellIterator = function(cell) {
  245. if (cell.template) {
  246. cellTemplates.push(cell.template)
  247. }
  248. return cell.element
  249. };
  250. for (var i = 0; i < groupCount; i++) {
  251. if (i > 0) {
  252. repeatCount = groups[i - 1].items.length * repeatCount
  253. }
  254. var cells = this._makeGroupedRowCells(groups[i], repeatCount, cssClasses, cellTemplate, repeatByDate);
  255. rows.push($("<tr>").addClass(cssClasses.groupRowClass).append(cells.map(cellIterator)))
  256. }
  257. var maxCellCount = rows[groupCount - 1].find("th").length;
  258. for (var j = 0; j < groupCount; j++) {
  259. var $cell = rows[j].find("th");
  260. var colspan = maxCellCount / $cell.length;
  261. if (!groupByDate) {
  262. colspan *= cellCount
  263. }
  264. if (colspan > 1 && 1 === repeatByDate || groupByDate && groupCount > 1) {
  265. $cell.attr("colSpan", colspan)
  266. }
  267. }
  268. return {
  269. elements: rows,
  270. cellTemplates: cellTemplates
  271. }
  272. },
  273. _makeGroupedRowCells: function(group, repeatCount, cssClasses, cellTemplate, repeatByDate) {
  274. repeatByDate = repeatByDate || 1;
  275. repeatCount *= repeatByDate;
  276. var cells = [];
  277. var items = group.items;
  278. var itemCount = items.length;
  279. for (var i = 0; i < repeatCount; i++) {
  280. for (var j = 0; j < itemCount; j++) {
  281. var $container = $("<div>");
  282. var cell = {};
  283. if (cellTemplate && cellTemplate.render) {
  284. var templateOptions = {
  285. model: items[j],
  286. container: getPublicElement($container),
  287. index: i * itemCount + j
  288. };
  289. if (group.data) {
  290. templateOptions.model.data = group.data[j]
  291. }
  292. cell.template = cellTemplate.render.bind(cellTemplate, templateOptions)
  293. } else {
  294. $container.text(items[j].text);
  295. $container = $("<div>").append($container)
  296. }
  297. $container.addClass(cssClasses.groupHeaderContentClass);
  298. var cssClass;
  299. if (typeUtils.isFunction(cssClasses.groupHeaderClass)) {
  300. cssClass = cssClasses.groupHeaderClass(j)
  301. } else {
  302. cssClass = cssClasses.groupHeaderClass
  303. }
  304. cell.element = $("<th>").addClass(cssClass).append($container);
  305. cells.push(cell)
  306. }
  307. }
  308. return cells
  309. }
  310. };
  311. module.exports = SchedulerTableCreator;