ngx-deebodata 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/fesm2022/ngx-deebodata.mjs +6863 -0
  2. package/fesm2022/ngx-deebodata.mjs.map +1 -0
  3. package/package.json +35 -16
  4. package/types/ngx-deebodata.d.ts +439 -0
  5. package/ng-package.json +0 -7
  6. package/src/lib/data-table/charts/bar-graph-component/bar-graph-component.css +0 -156
  7. package/src/lib/data-table/charts/bar-graph-component/bar-graph-component.html +0 -29
  8. package/src/lib/data-table/charts/bar-graph-component/bar-graph-component.spec.ts +0 -23
  9. package/src/lib/data-table/charts/bar-graph-component/bar-graph-component.ts +0 -286
  10. package/src/lib/data-table/charts/charts-and-graphs/charts-and-graphs.css +0 -27
  11. package/src/lib/data-table/charts/charts-and-graphs/charts-and-graphs.html +0 -53
  12. package/src/lib/data-table/charts/charts-and-graphs/charts-and-graphs.spec.ts +0 -23
  13. package/src/lib/data-table/charts/charts-and-graphs/charts-and-graphs.ts +0 -214
  14. package/src/lib/data-table/charts/column-chart/column-chart.css +0 -19
  15. package/src/lib/data-table/charts/column-chart/column-chart.html +0 -47
  16. package/src/lib/data-table/charts/column-chart/column-chart.spec.ts +0 -23
  17. package/src/lib/data-table/charts/column-chart/column-chart.ts +0 -178
  18. package/src/lib/data-table/charts/line-graph-component/line-graph-component.css +0 -33
  19. package/src/lib/data-table/charts/line-graph-component/line-graph-component.html +0 -59
  20. package/src/lib/data-table/charts/line-graph-component/line-graph-component.spec.ts +0 -23
  21. package/src/lib/data-table/charts/line-graph-component/line-graph-component.ts +0 -661
  22. package/src/lib/data-table/charts/num-value-distro-component/num-value-distro-component.css +0 -61
  23. package/src/lib/data-table/charts/num-value-distro-component/num-value-distro-component.html +0 -27
  24. package/src/lib/data-table/charts/num-value-distro-component/num-value-distro-component.spec.ts +0 -23
  25. package/src/lib/data-table/charts/num-value-distro-component/num-value-distro-component.ts +0 -210
  26. package/src/lib/data-table/charts/pie-graph-component/pie-graph-component.css +0 -0
  27. package/src/lib/data-table/charts/pie-graph-component/pie-graph-component.html +0 -15
  28. package/src/lib/data-table/charts/pie-graph-component/pie-graph-component.spec.ts +0 -23
  29. package/src/lib/data-table/charts/pie-graph-component/pie-graph-component.ts +0 -197
  30. package/src/lib/data-table/data-table-module/data-cell/data-cell.css +0 -0
  31. package/src/lib/data-table/data-table-module/data-cell/data-cell.html +0 -6
  32. package/src/lib/data-table/data-table-module/data-cell/data-cell.spec.ts +0 -23
  33. package/src/lib/data-table/data-table-module/data-cell/data-cell.ts +0 -271
  34. package/src/lib/data-table/data-table-module/data-table-header/data-table-header.css +0 -25
  35. package/src/lib/data-table/data-table-module/data-table-header/data-table-header.html +0 -55
  36. package/src/lib/data-table/data-table-module/data-table-header/data-table-header.spec.ts +0 -23
  37. package/src/lib/data-table/data-table-module/data-table-header/data-table-header.ts +0 -261
  38. package/src/lib/data-table/data-table-module/data-table-paginator/data-table-paginator.css +0 -69
  39. package/src/lib/data-table/data-table-module/data-table-paginator/data-table-paginator.html +0 -24
  40. package/src/lib/data-table/data-table-module/data-table-paginator/data-table-paginator.spec.ts +0 -23
  41. package/src/lib/data-table/data-table-module/data-table-paginator/data-table-paginator.ts +0 -125
  42. package/src/lib/data-table/data-table-module/export-component/export-component.css +0 -91
  43. package/src/lib/data-table/data-table-module/export-component/export-component.html +0 -16
  44. package/src/lib/data-table/data-table-module/export-component/export-component.spec.ts +0 -23
  45. package/src/lib/data-table/data-table-module/export-component/export-component.ts +0 -206
  46. package/src/lib/data-table/data-table-module/ngx-deebodata/ngx-deebodata.css +0 -91
  47. package/src/lib/data-table/data-table-module/ngx-deebodata/ngx-deebodata.html +0 -193
  48. package/src/lib/data-table/data-table-module/ngx-deebodata/ngx-deebodata.spec.ts +0 -23
  49. package/src/lib/data-table/data-table-module/ngx-deebodata/ngx-deebodata.ts +0 -2226
  50. package/src/lib/data-table/data-table-module/row-group-menu/row-group-menu.css +0 -14
  51. package/src/lib/data-table/data-table-module/row-group-menu/row-group-menu.html +0 -27
  52. package/src/lib/data-table/data-table-module/row-group-menu/row-group-menu.spec.ts +0 -23
  53. package/src/lib/data-table/data-table-module/row-group-menu/row-group-menu.ts +0 -58
  54. package/src/lib/data-table/data-table-module/row-group-panel/row-group-panel.css +0 -23
  55. package/src/lib/data-table/data-table-module/row-group-panel/row-group-panel.html +0 -48
  56. package/src/lib/data-table/data-table-module/row-group-panel/row-group-panel.spec.ts +0 -23
  57. package/src/lib/data-table/data-table-module/row-group-panel/row-group-panel.ts +0 -599
  58. package/src/lib/data-table/data-table-module/worker.worker.ts +0 -44
  59. package/src/lib/interfaces/cell-edit.ts +0 -5
  60. package/src/lib/interfaces/column-header.ts +0 -10
  61. package/src/lib/interfaces/column-styles.ts +0 -14
  62. package/src/lib/interfaces/column-symbol.ts +0 -4
  63. package/src/lib/interfaces/data-cell.ts +0 -14
  64. package/src/lib/interfaces/data-row.ts +0 -11
  65. package/src/lib/interfaces/row-number.ts +0 -4
  66. package/src/lib/services/common-service.spec.ts +0 -16
  67. package/src/lib/services/common-service.ts +0 -336
  68. package/src/lib/services/data-table-service.spec.ts +0 -16
  69. package/src/lib/services/data-table-service.ts +0 -597
  70. package/src/lib/services/table-drag-service.spec.ts +0 -16
  71. package/src/lib/services/table-drag-service.ts +0 -347
  72. package/src/lib/styles.css +0 -1065
  73. package/src/public-api.ts +0 -8
  74. package/tsconfig.lib.json +0 -17
  75. package/tsconfig.lib.prod.json +0 -11
  76. package/tsconfig.spec.json +0 -15
@@ -1,2226 +0,0 @@
1
- import { Component, ElementRef, EventEmitter, HostListener, input, Input, NgZone, Output, signal, SimpleChanges, ViewChild } from '@angular/core';
2
- import { ColumnHeader } from '../../../interfaces/column-header';
3
- import { CommonService } from '../../../services/common-service';
4
- import { TableDragService } from '../../../services/table-drag-service';
5
- import { DataTableService } from '../../../services/data-table-service';
6
- import { DataRow } from '../../../interfaces/data-row';
7
- import { DataTableHeader } from '../data-table-header/data-table-header';
8
- import { DataTablePaginator } from '../data-table-paginator/data-table-paginator';
9
- import { DataCellComponent } from '../data-cell/data-cell';
10
- import { CommonModule, DecimalPipe } from '@angular/common';
11
- import { ExportComponent } from '../export-component/export-component';
12
- import { FormsModule } from '@angular/forms';
13
- import { CellEdit } from '../../../interfaces/cell-edit';
14
- import { DataCell } from '../../../interfaces/data-cell';
15
- import { RowGroupMenu } from '../row-group-menu/row-group-menu';
16
- import { RowGroupPanel } from '../row-group-panel/row-group-panel';
17
- import { ChartsAndGraphs } from '../../charts/charts-and-graphs/charts-and-graphs';
18
- import { RowNumber } from '../../../interfaces/row-number';
19
- import { ColumnStyles, ValueCss } from '../../../interfaces/column-styles';
20
- import { finalize, Subscription } from 'rxjs';
21
- import { ColumnSymbol } from '../../../interfaces/column-symbol';
22
-
23
- @Component({
24
- selector: 'ngx-deebodata',
25
- imports: [
26
- DataTableHeader,
27
- DataCellComponent,
28
- DataTablePaginator,
29
- ChartsAndGraphs,
30
- RowGroupMenu,
31
- RowGroupPanel,
32
- ExportComponent,
33
- FormsModule,
34
- DecimalPipe,
35
- CommonModule,
36
- ],
37
- templateUrl: './ngx-deebodata.html',
38
- styleUrls: ['./ngx-deebodata.css', '../../../styles.css'],
39
- })
40
- export class NgxDeebodata {
41
-
42
- @HostListener('window:click', ['$event'])
43
- onWindowClick(e: MouseEvent) {
44
- if(this.listenToWindowCurrFil && this.currFilOpts.length){
45
- if(e && e.target && (e.target instanceof Element) && (/selfil-/g.test(e.target.className) || /selfil-/g.test(e.target.id))){
46
- } else {
47
- this.killSelFilOpts(true)
48
- }
49
- }
50
-
51
- if(this.dataTableService.listenToCloseExportOpts){
52
- if(e && e.target && (e.target instanceof Element) && /deebo-dd-export/g.test(e.target.className)){
53
- } else {
54
- this.dataTableService.closeExportOpts.next(false)
55
- this.dataTableService.listenToCloseExportOpts = false
56
- }
57
- }
58
-
59
- if(this.dataTableService.listenToCloseGroupByOpts){
60
- if(e && e.target && (e.target instanceof Element) && /deebo-dd-groupby/g.test(e.target.className)){
61
- } else {
62
- this.dataTableService.closeGroupByOpts.next(false)
63
- this.dataTableService.listenToCloseGroupByOpts = false
64
- }
65
- }
66
-
67
- if(this.validatedEditType && (!document.activeElement || (document.activeElement && !document.activeElement.className)))
68
- this.clearValidatedEdit(e)
69
- }
70
-
71
- @HostListener('window:mouseup', ['$event'])
72
- onWindowMouseUp(e: MouseEvent) {
73
- if(this.tblDragService.listenForMouseUp){
74
- this.tblDragService.handleColResMouseUp(e)
75
- this.dataTableBody?.nativeElement.scrollBy(1, 0)
76
- }
77
- if(this.tblDragService.listenForColMvMouseUp)
78
- this.tblDragService.handleColMoveMouseUp(e)
79
- if(this.listenToCellDraggerMouseMove){
80
- this.listenToCellDraggerMouseMove = false
81
- this.clearDragEditFlag()
82
- try{this.fCellDragger.nativeElement.blur()}catch(e){}
83
- }
84
- if(this.listenToCellDraggerMouseUp)
85
- this.handleDraggerMU(e)
86
- if(this.currGroupValues().length)
87
- return this.dataTableService.mouseupWhileGrouped.next(e)
88
- }
89
-
90
- @HostListener('window:mousemove', ['$event'])
91
- onWindowMouseMove(e: MouseEvent) {
92
- if(this.listenToCellDraggerMouseMove)
93
- this.handleCellDraggerEdit(e)
94
- }
95
-
96
- @HostListener('window:selectstart', ['$event'])
97
- onWindowSelectStart(e: Event) {
98
- if(this.listenToCellDraggerMouseMove)
99
- e.preventDefault()
100
- if(this.tblDragService.listenForSelectStart)
101
- this.tblDragService.stopWindowSelection(e)
102
- }
103
-
104
- @HostListener('window:resize', ['$event'])
105
- onWindowResize(e: Event) {
106
- this.dataTableService.setTblBounds()
107
- this.testHideMinBtn()
108
- this.clearValidatedEdit()
109
- }
110
-
111
- @HostListener('window:scroll', ['$event'])
112
- onWindowScroll(e: Event) {
113
- this.dataTableService.setTblBounds()
114
- this.clearValidatedEdit()
115
- }
116
-
117
- constructor(public dataTableService: DataTableService,
118
- private tblDragService: TableDragService,
119
- public common: CommonService,) {
120
-
121
- }
122
-
123
- rows: DataRow[] = [];
124
- aboveHgt = signal<number>(0);
125
- belowHgt = signal<number>(0);
126
- dtChecks: number[] = [];
127
- rowNos: RowNumber[] = [];
128
- verticalRest = 0
129
- horizRest = signal<number>(0)
130
- isScrolling = false;
131
- useRowWid: string = ""
132
- currGroupValues = signal<any[]>([])
133
- chartHgt: string = ""
134
- chartState: string = "all"
135
- columnsForCharts: string[] = []
136
- paginatorReady = false;
137
- handlingSelRows = false
138
- columnOfInterest = signal<string>("")
139
- hiddenCols: string[] = [];
140
- desRowHeight: string = "50"
141
- currFilOpts: any[] = []
142
- currSelEditOpts: any[] = []
143
- listenToWindowCurrFil = false
144
- listenToCellDraggerMouseMove = false
145
- listenToCellDraggerMouseUp = false
146
- currDDFilter: string = "";
147
- topLevelFilter: string = ""
148
- allFilSortInfo = signal<string>("")
149
- lockVScroll: boolean = false;
150
- isMultiFiltering = signal<boolean>(false);
151
- ddFilStyle: any = {}
152
- filterBuildUp: any[] = []
153
- togSelRows: string = "Selected Rows"
154
- maxCols: number = 0;
155
- lastElRowIndex: number = 0;
156
- columnHeaders: ColumnHeader[] = []
157
- columnNames: string[] = []
158
- linkCell: any;
159
- linkCells: any[] = []
160
- canGroupBy = signal<string[]>([]);
161
- validatedEditType: string = ""
162
- validationSettled = signal<boolean>(false)
163
- dataHasBeenSet = signal<boolean>(false)
164
- validationSub: Subscription = new Subscription;
165
- data = input<any[]>([])
166
- @Input() licenseKey: string = "";
167
- @Input() color1: string = ""
168
- @Input() color2: string = ""
169
- @Input() primaryKey: string = ""
170
- @Input() defRowHgt: string = "50px"
171
- @Input() defGridHgt: number = 500
172
- @Input() altRowColor: string = "";
173
- @Input() myColumnSymbols: ColumnSymbol[] = []
174
- @Input() myColumnStyles: ColumnStyles[] = []
175
- @Input() pieGraphColors: string[] = []
176
- @Input() removePieCovers: boolean|string[] = false
177
- @Input() editable: boolean = true;
178
- @Input() rowNumbers: boolean = true
179
- @Output("cellEdit") cellEdit: EventEmitter<CellEdit> = new EventEmitter()
180
- @ViewChild("dataTable", { static: true }) dataTable!: ElementRef<HTMLElement>;
181
- @ViewChild("dataTableBody", { static: true }) dataTableBody!: ElementRef<HTMLElement>;
182
- @ViewChild("aboveArea", { static: true }) aboveArea!: ElementRef<HTMLElement>;
183
- @ViewChild("belowArea", { static: true }) belowArea!: ElementRef<HTMLElement>;
184
- @ViewChild("validatedEdit", { static: true }) validatedEdit!: ElementRef<HTMLElement>;
185
- @ViewChild("rowNumHeader", { static: true }) rowNumHeader!: ElementRef<HTMLElement>;
186
- @ViewChild("rowNumBody", { static: true }) rowNumBody!: ElementRef<HTMLElement>;
187
- @ViewChild("fCellDragger", { static: true }) fCellDragger!: ElementRef<HTMLElement>;
188
- @ViewChild("selFilContainer", { static: true }) selFilContainer!: ElementRef<HTMLElement>;
189
- @ViewChild("btnTogSelRows", { static: true }) btnTogSelRows!: ElementRef<HTMLButtonElement>;
190
- @ViewChild("dataTableHeaders", { static: true }) dataTableHeaders!: ElementRef<HTMLElement>;
191
- @ViewChild("topLevelDataFilter", { static: true }) topLevelDataFilter!: ElementRef<HTMLInputElement>;
192
-
193
- ngOnChanges(changes: SimpleChanges) {
194
- if(typeof changes !== "undefined" && changes["data"] && this.validationSettled() && !this.dataHasBeenSet() && this.data().length)
195
- this.handleDataInput()
196
- }
197
-
198
- ngOnInit() {
199
- this.execSetters()
200
- this.handleValidation()
201
- }
202
-
203
- execSetters() {
204
- if(this.defRowHgt && /\d+px/g.test(this.defRowHgt))
205
- this.dataTableService.defltRHgt = this.defRowHgt
206
- if(this.defGridHgt)
207
- this.dataTableService.dTblHeight = this.defGridHgt
208
- if(this.myColumnSymbols)
209
- this.dataTableService.columnSymbols = [...this.myColumnSymbols]
210
- if(this.myColumnStyles)
211
- this.dataTableService.columnStyles = [...this.myColumnStyles]
212
- if(this.pieGraphColors)
213
- this.dataTableService.pieGraphColors = [...this.pieGraphColors];
214
- this.dataTableService.removePieCovers = this.removePieCovers
215
- }
216
-
217
- handleDataInput() {
218
- let tdata = this.convertNeededCols([...this.data()])
219
- this.dataTableService.mainData = tdata.filter( (d: any) => true )
220
- this.dataTableService.currFilData = tdata.filter( (d: any) => true )
221
- this.dataTableService.mainDataLen = this.dataTableService.mainData.length
222
- this.buildInitUiDataTable(tdata, this.color1, this.color2)//hex or rgb values work best
223
- if(!this.dataTableService.errorLoading)
224
- this.dataTableService.noDataMsg = "No data to display for this configuration.";
225
- this.tblDragService.dTblHeightOutput.subscribe( h => this.setTableHeight(h) )
226
- this.tblDragService.columnMove.subscribe( c => this.processColMove(c) )
227
- this.dataTableService.currGrouping.subscribe( g => this.processGrouping(g) )
228
- setTimeout( () => this.setTableHeight(510), 1000)//for demo
229
- this.dataHasBeenSet.set(true)
230
- }
231
-
232
- getAllColsAtRuntime(excludeHidden: any) {
233
- let cols = (typeof this.dataTableService.mainData[0] === "object" ? Object.keys(this.dataTableService.mainData[0]) :
234
- (Object.keys(this.dataTableService.dataFilSrtTracker)));
235
- if(!excludeHidden)
236
- return cols;
237
- return cols.filter( (c: any) => {
238
- return !this.dataTableService.dataFilSrtTracker[c].minimize
239
- });
240
- }
241
-
242
- setMaxCols() {
243
- const el = this.dataTable.nativeElement
244
- if(el){
245
- const elWid = el.getBoundingClientRect().width;
246
- return elWid >= 1024 ? 5 : (elWid > 760 ? 3 : 2)
247
- }
248
- const wid = window.innerWidth
249
- return wid >= 1024 ? 5 : (wid > 760 ? 3 : 2)
250
- }
251
-
252
- getAllColWidth(colLen: any) {
253
- try{
254
- if(!colLen || colLen === 0)
255
- return 0
256
- const colWid = parseInt(this.dataTableService.useColWid.replace(/[ ]?px/g, ""))
257
- let i = 0
258
- let wid = 0
259
- for(const prop in this.dataTableService.dataFilSrtTracker){
260
- if(this.dataTableService.dataFilSrtTracker[prop].minimize)
261
- continue
262
- i += 1
263
- const ownColWid = this.dataTableService.dataFilSrtTracker[prop].colWidth
264
- wid += (ownColWid ? parseInt(ownColWid.replace(/[ ]?px/g, "")) : colWid)
265
- }
266
- if(i === colLen)
267
- return Math.floor(wid)
268
- return Math.floor(colWid*colLen)
269
- }catch(e){
270
- try{
271
- return Math.floor(parseInt(this.dataTableService.useColWid.replace(/[ ]?px/g, ""))*colLen)
272
- }catch(e){
273
- return window.innerWidth
274
- }
275
- }
276
- }
277
-
278
- removeAllFreezeCols() {
279
- const len = this.columnHeaders.length
280
- const rlen = this.rows.length
281
- for(var i = (len-1); i >= 0; i--)
282
- try{this.columnHeaders[i].freeze = false}catch(e){}
283
- for(var o = (rlen-1); o >= 0; o--){
284
- try{
285
- const row =this.rows[o]
286
- const clen = row.cells?.length
287
- if(clen && clen > 0){
288
- for(var n = (clen-1); n >= 0; n--){
289
- const cell = row.cells?.[n]
290
- if(cell)
291
- cell.freeze = false
292
- }
293
- }
294
- }catch(e){}
295
- }
296
- }
297
-
298
- setTableHeight(h: number) {
299
- this.dataTableService.dTblHeight = h
300
- setTimeout( () => {
301
- this.dataTableService.setTblBounds()
302
- this.chartHgt = this.dataTable.nativeElement.getBoundingClientRect().height + "px";
303
- if(!this.dataTableService.showCharts() && !this.currGroupValues().length){
304
- const el = this.dataTableBody?.nativeElement
305
- if(el){
306
- el.scrollBy(0, 1)
307
- el.scrollBy(0, -1)
308
- }
309
- setTimeout(() => { this.setRowSelChecksPlacement() })
310
- }
311
- if(this.currGroupValues().length)
312
- setTimeout( () => { this.dataTableService.gridScrollEndWhileGrouped.next(true) })
313
- })
314
- }
315
-
316
- openCharts() {
317
- this.dataTableService.showCharts.set(true)
318
- this.chartHgt = this.dataTable.nativeElement.getBoundingClientRect().height + "px";
319
- this.columnsForCharts = this.columnHeaders.filter( c => !c.minimized && !this.common.idCol(c.column)).map( c => c.column)
320
- this.chartState = this.dataTableService.displayOnlySelRows ? 'selected' :
321
- (this.dataTableService.currFilData.length !== this.dataTableService.mainDataLen ? 'filtered' : 'all');
322
- this.clearValidatedEdit(null, true)
323
- }
324
-
325
- closeCharts(event: boolean) {
326
- this.dataTableService.showCharts.set(event)
327
- const bod = this.dataTableBody?.nativeElement
328
- if(bod){
329
- bod.scrollBy(1, 0)
330
- bod.scrollBy(-1, 0)
331
- }
332
- }
333
-
334
- processColMove(event: any) {
335
- let lfts = event.ls
336
- let nwColLft = event.nl
337
- let wantlfts = event.wl
338
- let xDrop = event.x
339
- const wLf = wantlfts.indexOf(xDrop)
340
- if(wLf != lfts.indexOf(nwColLft)){
341
- const inAft = wLf - 1
342
- this.columnHeaders = this.columnHeaders.filter( c => this.common.elifyCol(c.column) !== this.dataTableService.currColumnEdit)
343
- const rwCol = this.common.replaceUniSep(this.dataTableService.currColumnEdit)
344
- const trkr = this.dataTableService.dataFilSrtTracker[rwCol]
345
- const addCol: ColumnHeader = { column: rwCol, width: (trkr["colWidth"] || this.dataTableService.useColWid),
346
- hideMinCol: false, freeze: false, minimized: trkr["minimize"], dataType: this.dataTableService.figureFilterType(rwCol) }
347
- if(inAft === -1){//they want it first
348
- this.columnHeaders.unshift(addCol)
349
- } else {
350
- if(inAft >= (wantlfts.length - 2)){//last
351
- this.columnHeaders.push(addCol)
352
- } else {
353
- if(this.columnHeaders[inAft])
354
- this.columnHeaders.splice((inAft+1), 0, addCol)
355
- }
356
- }
357
- setTimeout( () => {
358
- let i = 0
359
- const els = document.getElementsByClassName("col-header")
360
- const len = els.length
361
- this.columnHeaders = []
362
- for(i; i < len; i++){
363
- const col = this.common.replaceUniSep(els[i].id.replace(/^columnHeader/, ""))
364
- if(this.columnHeaders.map( c => c.column).indexOf(col) < 0){
365
- const trkr = this.dataTableService.dataFilSrtTracker[col]
366
- const addCol: ColumnHeader = { column: col, width: (trkr["colWidth"] || this.dataTableService.useColWid),
367
- hideMinCol: false, freeze: false, minimized: trkr["minimize"], dataType: this.dataTableService.figureFilterType(col) }
368
- this.columnHeaders.push(addCol)
369
- }
370
- }
371
- this.columnNames = this.columnHeaders.map( c => c.column)
372
- const dtB = this.dataTableBody.nativeElement
373
- if(dtB){
374
- const willSclTo = dtB.scrollLeft
375
- this.renderCurrData(false)
376
- setTimeout( () => { dtB.scrollLeft = willSclTo })
377
- }
378
- }, 100)
379
- }
380
- this.clearValidatedEdit(null, true)
381
- }
382
-
383
- processGrouping(group: any): any {
384
- if(!group)
385
- return this.resetCurrentData()
386
- this.verticalRest = 0
387
- this.rows = []
388
- this.aboveHgt.set(0)
389
- this.belowHgt.set(0)
390
- this.dtChecks = []
391
- this.rowNos = []
392
- this.clearValidatedEdit(null, true)
393
- this.dataTableService.currMapping = {}
394
- this.dataTableService.currSelRows = []
395
- this.dataTableService.displayOnlySelRows = false
396
- this.dataTableService.currGroup = group
397
- this.dataTableBody.nativeElement.scrollTop = 0;
398
- this.currGroupValues.set(this.dataTableService.dataFilSrtTracker[group]?.["selDDVals"]?.filter( (g: any) => g.value !== "(Select All)"))
399
- setTimeout( () => { this.rows = [] })
400
- }
401
-
402
- setColHeaderHgt() {//set hgt = to tallest
403
- let z = 0; let i = 0; let x = 0
404
- let hgts = []
405
- const cols = document.getElementsByClassName("col-header")
406
- const cLen = this.columnHeaders?.length
407
- for(x; x < cLen; x++){
408
- const col = this.columnHeaders[x]
409
- col.height = undefined
410
- col.lineHeight = undefined
411
- }
412
- for(z; z < cLen; z++){
413
- if(cols[z])
414
- hgts.push(cols[z].getBoundingClientRect().height)
415
- }
416
- const maxHgt = hgts.sort( (a: number,b: number) => a > b ? -1 : 1 )[0]
417
- const useHgt = Math.ceil(maxHgt)
418
- for(i; i < cLen; i++){
419
- const col = this.columnHeaders[i]
420
- if(col && !col.minimized){
421
- col.height = useHgt + "px"
422
- const elCol = cols[i]
423
- if(elCol && elCol.firstElementChild && elCol.firstElementChild.getBoundingClientRect().height < 40)
424
- col.lineHeight = Math.floor(((useHgt/2)-21)) + "px"
425
- }
426
- }
427
- if(this.dataTableHeaders)
428
- this.dataTableHeaders.nativeElement.style.height = useHgt + "px"
429
- if(this.rowNumHeader)
430
- this.rowNumHeader.nativeElement.style.height = useHgt + "px"
431
- setTimeout( () => { this.setRowSelChecksPlacement() })
432
- }
433
-
434
- renameColSpecChars(data: any[]) {
435
- if(data && data.some( d => d && typeof d === "object" )){
436
- let specCharCols = []
437
- if(data[0] && typeof data[0] === "object"){
438
- for(const prop in data[0]){
439
- if(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/g.test(prop))
440
- specCharCols.push(prop)
441
- }
442
- let c = 0
443
- let i = 0
444
- const dlen = data.length
445
- const len = specCharCols.length
446
- for(c; c < len; c++){
447
- const prop = specCharCols[c]
448
- const okNwNam = this.common.stripSpecChars(prop)
449
- for(i; i < dlen; i++){
450
- if(data[i] && typeof data[i] === "object"){
451
- const desc = Object.getOwnPropertyDescriptor(data[i], prop)
452
- if(desc){
453
- try{
454
- Object.defineProperty(data[i], okNwNam, desc);
455
- delete data[i][prop]
456
- }catch(e){}
457
- }
458
- }
459
- }
460
- i = 0;
461
- }
462
- return data?.filter( d => true );
463
- }
464
- return data?.filter( d => true );
465
- }
466
- return data?.filter( d => true );
467
- }
468
-
469
- scoopOutObjsInObjs(data: any[]) {//scoop out one layer of nested objs
470
- let i = 0;
471
- let ndata = []
472
- const len = data?.length
473
- if(data && data.some( (d: any) => { return d && typeof d === "object" })){
474
- for(i; i < len; i++){
475
- try{
476
- const dta = data[i]
477
- if(dta && typeof dta === "object"){
478
- let nobj: any = {}
479
- for(const prop in dta){
480
- const val = dta[prop]
481
- if(val && typeof val === "object" && typeof val.getTime === "undefined" && typeof val.filter === "undefined" && Object.keys(val).length){
482
- for(const iprp in val)
483
- nobj[iprp] = val[iprp]
484
- } else {
485
- nobj[prop] = val
486
- }
487
- }
488
- ndata.push(nobj)
489
- }
490
- } catch(e){}
491
- }
492
- } else {
493
- ndata = data?.filter( (d: any) => { return true })
494
- }
495
- return ndata;
496
- }
497
-
498
- convertNeededCols(data: any) {
499
- data = this.scoopOutObjsInObjs(data)
500
- data = this.renameColSpecChars(data)
501
- let nData = data?.filter( (d: any) => true )
502
- const symReg = new RegExp(/[$€£₹¥¢%\,\"\']/, "g")
503
- const isDtReg = new RegExp(/\d+(\/|-)\d+(\/|-)\d+/)
504
- let i = 0;
505
- const len = data?.length
506
- let allCols: any[] = []
507
- if(data && data.some( (d: any) => d && typeof d === "object" )){
508
- allCols = this.getDataColumns(data)//gets all possible props in array
509
- this.dataTableService.dataFilSrtTracker = this.dataTableService.buildDataFilSrtTracker(allCols)
510
- for(i; i < len; i++){
511
- try{
512
- if(data[i] && typeof data[i] === "object"){
513
- for(const prop in data[i]){
514
- if(allCols.indexOf(prop) < 0){
515
- delete data[i][prop]
516
- continue
517
- }
518
- const val = data[i][prop]
519
- if(val && typeof val === "string"){
520
- const tval = val.trim()
521
- const low = tval.toLocaleLowerCase()
522
- if(this.common.testLongDate(low))
523
- nData[i][prop] = this.common.coerceDate(low)
524
- if(!this.common.testLongDate(low) && (this.common.testShortDate(tval) || this.common.testISODate(tval)))
525
- nData[i][prop] = this.common.coerceDate(tval)
526
- if(this.common.testISODate(tval.replace(/ /g, "")))
527
- nData[i][prop] = this.common.coerceDate(tval.replace(/ /g, ""))
528
- if(low === "null" || low === "undefined")
529
- nData[i][prop] = null
530
- if(!this.common.idCol(prop) && !isDtReg.test(tval) && !/[A-Za-z]/g.test(val) && /^[0-9,]+[\.]{0,1}?[0-9,]*$/g.test(tval.replace(symReg, "")) && !isNaN(parseInt(tval.replace(symReg, ""))))//not viewed as num, but can be
531
- nData[i][prop] = /\./g.test(val) ? parseFloat(tval.replace(symReg, "")) : parseInt(tval.replace(symReg, ""))
532
- }
533
- if(val && typeof val === "object" && typeof val.getTime === "undefined")/**not dates */
534
- try{ nData[i][prop] = JSON.stringify(val).replace(/[\[\]{}\"]/g, "").replace(/:/g, ": ").replace(/,/g, ", ").replace(/ /g, " ")}catch(e){}
535
- }
536
- const keys = Object.keys(data[i])
537
- const diff = allCols.filter( (c) => keys.indexOf(c) < 0 )
538
- const dLen = diff.length
539
- if(dLen){//obj doesn't have all props
540
- let n = 0
541
- for(n; n < dLen; n++)
542
- nData[i][diff[n]] = "";
543
- }
544
- }
545
- }catch(e) { }
546
- }
547
- }
548
- //read data that's already not a string
549
- if(allCols && allCols.length){//array of objs
550
- let a = 0
551
- const alen = allCols.length
552
- for(a; a < alen; a++){
553
- const col = allCols[a]
554
- const colData = nData?.map( (d: any) => d[col] )
555
- if(colData && colData.every( (d: any) => !d ))
556
- continue
557
- if(!this.common.idCol(col) && colData && colData.every( (d: any) => !d || typeof d === "number" )){
558
- try{ this.dataTableService.dataFilSrtTracker[col]["type"] = "number" } catch(e){}
559
- }
560
- if(colData && colData.every( (d: any) => { return !d || this.common.isADateObject(d) })){
561
- try{ this.dataTableService.dataFilSrtTracker[col]["type"] = "date" } catch(e){}
562
- }
563
- if(colData && colData.every( (d: any) => !d || typeof d === "boolean" )){
564
- nData = nData.map( (d: any) => {
565
- d[col] = d[col]?.toString() || "false";
566
- return d
567
- })
568
- }
569
- }
570
- }
571
- return nData
572
- }
573
-
574
- setRowSelChecksPlacement() {
575
- let i = 0
576
- const radd = 12
577
- const els = document.getElementsByClassName("select-row-check")
578
- const len = els.length
579
- const dtBody = this.dataTableBody.nativeElement
580
- const tbds = dtBody.getBoundingClientRect()
581
- const initT = this.initCheckTop()
582
- const col1Frozen = document.getElementsByClassName("col-item-freeze").length
583
- for(i; i < len; i++){
584
- const chk = <HTMLInputElement>els[i]
585
- const row = document.getElementById(chk.value)
586
- if(row){
587
- const tTop = tbds.top
588
- const rbds = row.getBoundingClientRect()
589
- const hh = (rbds.height/2)
590
- const top = Math.floor(initT + ((rbds.bottom - (hh+radd)) - tTop))
591
- chk.style.top = Math.floor(top) + "px"
592
- if((rbds.top+(hh-radd)) < tTop || ((rbds.bottom - (hh-radd)) >= (tTop + tbds.height)) || (dtBody.scrollLeft > 35 && !col1Frozen)){
593
- chk.classList.add("hide")
594
- continue
595
- }
596
- chk.className = "select-row-check"
597
- } else {
598
- chk.classList.add("hide")
599
- }
600
- }
601
- this.setRowNumbers()
602
- }
603
-
604
- setRowNumbers() {
605
- const rlen = this.rows.length
606
- if(this.rowNumbers && rlen){
607
- const hasHgt: RowNumber[] = this.rowNos.filter( r => r.height)
608
- this.rowNos = []
609
- let n = (this.lastElRowIndex + 1) - rlen
610
- for(n; n <= this.lastElRowIndex; n++){
611
- let rn: any = {number: n + 1}
612
- if(hasHgt.length){
613
- const hh = hasHgt.find( h => h.number === n+1)
614
- if(hh)
615
- rn.height = hh.height
616
- }
617
- this.rowNos.push(rn)
618
- }
619
- const r1 = document.getElementById("dataTableRow" + this.rows[0]?.index)
620
- if(r1){
621
- const useCalc = -(this.dataTableService.tblTop - r1.getBoundingClientRect().top)
622
- this.rowNumBody.nativeElement.style.marginTop = Math.min(useCalc, 0) + "px"
623
- }
624
- }
625
- }
626
-
627
- initCheckTop() {
628
- const headHt = this.dataTableHeaders.nativeElement.getBoundingClientRect().height
629
- return headHt + 17;//dt table marg top is 17
630
- }
631
-
632
- toggleSelectedRows(forceUnsel?: any) {
633
- this.handlingSelRows = true
634
- setTimeout( () => {//let the button disable
635
- this.dataTableService.displayOnlySelRows = !this.dataTableService.displayOnlySelRows
636
- if(forceUnsel)
637
- this.dataTableService.displayOnlySelRows = false
638
- const icn = this.btnTogSelRows.nativeElement.firstElementChild;
639
- if(this.dataTableService.displayOnlySelRows){
640
- this.dataTableService.currFilData = this.dataTableService.mainData.
641
- filter( (d: any, ind: number) => this.dataTableService.currSelRows.indexOf(ind) > -1 )
642
- if(icn){
643
- icn.textContent = "check_box"
644
- icn.classList.add("sel-rows-checked")
645
- }
646
- } else {
647
- this.dataTableService.currFilData = this.dataTableService.mainData.filter( (d: any) => true )
648
- if(icn){
649
- icn.classList.remove("sel-rows-checked")
650
- icn.textContent = "check_box_outline_blank"
651
- }
652
- }
653
- if(this.dataTableService.arefilSrtTrkPropsDefault(true)){
654
- this.renderCurrData(false)
655
- } else {
656
- const col = this.columnHeaders[0].column//just fil by 1st col
657
- const fil = this.dataTableService.dataFilSrtTracker[col].filter
658
- if(col)
659
- this.execFilter(col, (fil || ""))
660
- }
661
- setTimeout( () => this.handlingSelRows = false)
662
- })
663
- }
664
-
665
- toggleSingleRowSelected(useInd: number) {
666
- if(this.tblDragService.didResizeOnEvent)
667
- return false
668
- try{
669
- if(this.dataTableService.currSelRows.indexOf(useInd) > -1){//it's already selected
670
- this.dataTableService.currSelRows = this.dataTableService.currSelRows.filter( (r) => r !== useInd )
671
- if(this.dataTableService.displayOnlySelRows){
672
- const btnTog = this.btnTogSelRows.nativeElement
673
- btnTog.click()
674
- btnTog.click()
675
- if(!this.dataTableService.currSelRows.length)
676
- btnTog.click()
677
- }
678
- } else {
679
- if(this.dataTableService.currSelRows.indexOf(useInd) < 0)
680
- this.dataTableService.currSelRows.push(useInd)
681
- }
682
- }catch(e){}
683
- return this.setBtnTogRows(this.dataTableService.currSelRows.length)
684
- }
685
-
686
- setBtnTogRows(amt?: number) {
687
- if(amt){
688
- this.togSelRows = amt.toLocaleString(undefined, {maximumFractionDigits:0}) + " Selected Row" + (amt == 1 ? "" : "s")
689
- } else {
690
- this.togSelRows = "Selected Rows"
691
- }
692
- }
693
-
694
- clearSelectedRows() {
695
- this.handlingSelRows = true
696
- this.dataTableService.currSelRows = []
697
- const fullClear = this.dataTableService.displayOnlySelRows ? true : false;
698
- this.dataTableService.displayOnlySelRows = false;
699
- this.setBtnTogRows()
700
- if(fullClear)
701
- return this.toggleSelectedRows(true)
702
- setTimeout( () => this.handlingSelRows = false)
703
- }
704
-
705
- getDataColumns(data: any[]) {
706
- let i = 0
707
- let cols = Object.keys(data[0])
708
- const len = data.length
709
- for(i; i < len; i++){
710
- const obj = data[i]
711
- const keys = Object.keys(obj)
712
- const notInCols = keys.filter( (k: any) => cols.indexOf(k) < 0)
713
- if(typeof obj === "object" && notInCols.length){
714
- let n = 0
715
- const dLen = notInCols.length
716
- for(n; n < dLen; n++)
717
- cols.push(notInCols[n])
718
- }
719
- }
720
- let f =0
721
- let fincols: any = []
722
- const strpdcols = cols.map( (c: any) => this.common.stripSpecChars(c) )
723
- const slen = strpdcols.length
724
- for(f; f < slen; f++){
725
- const scol = strpdcols[f]
726
- if(!fincols.includes(scol))
727
- fincols.push(scol)
728
- }
729
- return fincols
730
- }
731
-
732
- setLastRowIndex() {
733
- const realMax = this.dataTableService.currFilData.length - 1
734
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
735
- const wannabeMax = (this.rows.length - 1) + Math.floor(this.aboveHgt()/defNum)
736
- this.lastElRowIndex = Math.min(wannabeMax, realMax)
737
- return this.lastElRowIndex;
738
- }
739
-
740
- buildInitUiDataTable(data: any[], color1?: any, color2?: any) {
741
- try{
742
- const cols = Object.keys(data[0])
743
- let i = 0; let n = 0;
744
- const len = data.length;
745
- const colLen = cols.length
746
- this.maxCols = this.setMaxCols()
747
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
748
- const init = Math.max(this.dataTableService.dTblHeight/defNum);
749
- this.dataTableService.useColWid = Math.ceil((this.dataTableBody.nativeElement.getBoundingClientRect().width-16)/Math.min(colLen, this.maxCols)) + "px"
750
- for(i; i < colLen; i++){
751
- this.columnHeaders.push({ column: cols[i], width: this.dataTableService.useColWid, hideMinCol: false, freeze: false, minimized: false, dataType: this.dataTableService.figureFilterType(cols[i]) })
752
- if(i < this.maxCols)
753
- this.dataTableService.visibleCols.push(cols[i])
754
- }
755
- this.columnNames = this.columnHeaders.map( c => c.column)
756
- const initVisCols = cols.filter( (c, ind) => ind <= (this.maxCols+1) )
757
- const addCell = (text: any, prop: string | null, row: DataRow | null, indx: number) => {
758
- if(prop && row){
759
- const notNum = (this.dataTableService.figureFilterType(prop) != "number" || /(year|yr|fy)/g.test(prop.toLocaleLowerCase())) ? true : false
760
- const useTxt = this.dataTableService.figureCellText(text, notNum, this.dataTableService.dataFilSrtTracker[prop]["colCellSymbol"])
761
- const colStyle = this.dataTableService.getColumnStyle(prop)
762
- row.cells?.push({
763
- column: prop,
764
- freeze: false,
765
- minimized: false,
766
- rawText: text,
767
- visible: initVisCols.indexOf(prop) > -1,
768
- width: this.dataTableService.useColWid,
769
- editable: useTxt.prop === "textContent" ? this.editable : false,
770
- dataType: this.dataTableService.figureFilterType(prop),
771
- text: (useTxt.prop === "textContent" ? useTxt.value : ""),
772
- html: (useTxt.prop !== "textContent" ? useTxt.value : ""),
773
- specialColClass: (colStyle ? (colStyle + this.common.elifyCol(useTxt.value)) : ""),
774
- })
775
- this.dataTableService.dataFilSrtTracker[prop].colWidth = this.dataTableService.useColWid
776
- }
777
-
778
- if(row && prop && row.cells && row.cells.length === 1)
779
- this.dtChecks.push(indx)
780
- }
781
- this.useRowWid = this.getAllColWidth(colLen) + "px"
782
- const limit = Math.min(init, len)
783
- for(n; n < limit; n++){
784
- this.rows.push({ id: "dataTableRow" + n, index: n, width: this.useRowWid, cells: [], height: this.dataTableService.defltRHgt })
785
- let k = 0
786
- for(k; k < colLen; k++)
787
- addCell(data[n][cols[k]], cols[k], this.rows[n], n)
788
- this.dataTableService.currMapping[n] = n
789
- }
790
- this.setLastRowIndex()
791
- this.paginatorReady = true;
792
- this.handleTheme(color1, color2)
793
- this.handleColAnyDDFilters(data, cols)
794
- setTimeout( () => {
795
- this.testHideMinBtn()
796
- this.setColHeaderHgt()
797
- this.setHoldingCheckCls()
798
- this.setRowSelChecksPlacement()
799
- this.dataTableService.setTblBounds()
800
- })
801
- setTimeout( () => {
802
- this.dataTableService.setIdealColumnWidth.next(true)
803
- if(len > init){
804
- let total = 0
805
- let z = this.lastElRowIndex + 1
806
- for(z; z < len; z++){
807
- total += 1
808
- this.dataTableService.currMapping[z] = z
809
- }
810
- this.belowHgt.set(total*defNum)
811
- setTimeout( () => { if(this.dataTableBody) {this.dataTableBody.nativeElement.scrollBy(0, 1); this.dataTableBody.nativeElement.scrollBy(0, -1)} })
812
- }
813
-
814
- this.setColsOnVisScreen()
815
- }, 250)
816
- this.getPrimaryKey(cols)
817
- } catch(e) {}
818
- }
819
-
820
- getPrimaryKey(cols: string[]): string {
821
- let i = 0
822
- const len = cols.length
823
- if(this.primaryKey){//means they set 1 manually
824
- const colData = this.dataTableService.mainData.map( (d) => d[this.primaryKey] )
825
- if(colData.length && !colData.some( (c) => !c )){
826
- const map = new Set(colData)
827
- if(map.size === this.dataTableService.mainDataLen){
828
- this.dataTableService.primaryKey = this.primaryKey;
829
- return this.dataTableService.primaryKey;//they set a good one
830
- }
831
- }
832
- }
833
- for(i; i < len; i++){
834
- const col = cols[i]
835
- if(this.common.idCol(col)){
836
- const colData = this.dataTableService.mainData.map( d => d[col])
837
- if(colData && !colData.some( c => !c)){//no null vals
838
- const map = new Set(colData)
839
- if(map.size === this.dataTableService.mainDataLen){//all unique vals
840
- this.dataTableService.primaryKey = col
841
- return this.dataTableService.primaryKey
842
- }
843
- }
844
- }
845
- }
846
- return ""
847
- }
848
-
849
- handleColAnyDDFilters(data: any[], cols: string[]) {
850
- let i = 0;
851
- let cgb: string[] = []
852
- const len = cols.length
853
- const dLen = data.length
854
- for(i; i < len; i++){
855
- const col = cols[i]
856
- const colData = data.map( (d) => (d && typeof d === "object") ? d[col] : d )
857
- const yearCol = /(year|yr|fy)/g.test(col?.toLocaleLowerCase())
858
- const allNumData = colData.every( (d) => !d || (d && typeof d === "number") )
859
- const boolData = colData.every( (d) => !d || (d && typeof d === "boolean") )
860
- if(colData.every( (d) => !d ))
861
- continue;
862
- let bitData;
863
- if(allNumData)
864
- bitData = colData.every( (d) => !d || d === 1 || d === 0 )
865
- if(allNumData && !yearCol && !bitData)//num data
866
- continue
867
- const dSet =new Set(colData)
868
- if(dSet.size >= colData.filter( (d) => !!d ).length)
869
- continue//means values are all unique so likely not dropdown material
870
- let arrFrmSet: any[] = []
871
- dSet.forEach( (v: any) => { arrFrmSet.push(v) })
872
- const doSels = dLen < 100 ? 2 : ((dLen >= 100 && dLen < 500) ? 10 : 15)
873
- const cantDoDD = arrFrmSet.some( (a) => (a && a.length > 40) )
874
- if(!cantDoDD && ((boolData || bitData) || (arrFrmSet.filter( (a) => !!a ).length > 0 && colData.every( (d) => !d || typeof d === "string" )))){
875
- if(arrFrmSet.length > 1 && arrFrmSet.length <= doSels){
876
- this.swapColFilterToSelect(col, arrFrmSet.filter( (v: any) => (!!v && this.dataTableService.badStrings.indexOf(v) < 0) ))
877
- cgb.push(col)
878
- }
879
- }
880
- }
881
- this.canGroupBy.set([...cgb])
882
- }
883
-
884
- swapColFilterToSelect(col: string, vals: any[]) {
885
- let o = 0;
886
- vals = vals?.sort()
887
- const oLen = vals?.length
888
- this.dataTableService.dataFilSrtTracker[col]["selDDVals"] = []
889
- this.dataTableService.dataFilSrtTracker[col]["selDDVals"].push({ value: "(Select All)", checked: true })
890
- for(o; o < oLen; o++)
891
- this.dataTableService.dataFilSrtTracker[col]["selDDVals"].push({ value: vals[o], checked: true })
892
- this.dataTableService.dataFilSrtTracker[col].comparator = "Equals"
893
- }
894
-
895
- handleFilFocus(event: any) {
896
- if(!event.select)
897
- return this.killSelFilOpts(true)
898
- this.buildSelFilOptions(event)
899
- }
900
-
901
- buildSelFilOptions(event: any) {
902
- const target = event.target
903
- const col: string = event.col;
904
- const esfd = document.getElementsByClassName("selfil-opt-" + this.currDDFilter)[0]
905
- if(this.currDDFilter){
906
- target.blur()
907
- this.currFilOpts = []
908
- this.currDDFilter = ""
909
- this.listenToWindowCurrFil = false
910
- return this.listenToWindowCurrFil
911
- }
912
- if(esfd){
913
- this.currFilOpts = []
914
- this.listenToWindowCurrFil = false
915
- }
916
- let i = 0
917
- const rel = this.selFilContainer.nativeElement
918
- this.currDDFilter = this.common.elifyCol(col)
919
- if(this.common.goodLs()){
920
- const len = this.dataTableService.dataFilSrtTracker[col]["selDDVals"].length
921
- for(i; i < len; i++)
922
- this.currFilOpts.push(this.dataTableService.dataFilSrtTracker[col]["selDDVals"][i])
923
- }
924
- const rbds = rel.getBoundingClientRect()
925
- const ibds = target.getBoundingClientRect()
926
- this.ddFilStyle = {'top': Math.ceil((ibds.bottom - rbds.top)+5) + "px", 'left': Math.ceil(ibds.left - rbds.left) + "px"}
927
- return target.blur()
928
- }
929
-
930
- handleWinClickOnSelFil() {
931
- this.listenToWindowCurrFil = false;
932
- setTimeout( () => { this.listenToWindowCurrFil = true })
933
- }
934
-
935
- killSelFilOpts(skipBlur?: boolean) {
936
- this.currFilOpts = []
937
- this.ddFilStyle = {}
938
- this.currDDFilter = ""
939
- if(!skipBlur){
940
- try{
941
- const actEl = document.activeElement
942
- if(actEl && actEl instanceof HTMLInputElement)
943
- actEl.blur()
944
- }catch(e){}
945
- }
946
- this.listenToWindowCurrFil = false
947
- }
948
-
949
- handleMultiSelFilter(elCol: string, value: any, checked: boolean) {
950
- let checkAll: any;
951
- const sAll = "(Select All)";
952
- const col= this.common.replaceUniSep(elCol)
953
- if(col && this.dataTableService.dataFilSrtTracker[col] && !this.isMultiFiltering() &&
954
- this.dataTableService.dataFilSrtTracker[col]["selDDVals"]){
955
- this.dataTableService.dataFilSrtTracker[col]["selDDVals"] = this.dataTableService.dataFilSrtTracker[col]["selDDVals"].map( (v: any) => {
956
- if(value === sAll){
957
- v.checked = checked
958
- checkAll = checked ? "true" : "false";
959
- } else {
960
- const tarChkd = checked;
961
- if((v.value === value) || (!v.value && !value))
962
- v.checked = tarChkd
963
- if(!tarChkd && v.value === sAll)
964
- v.checked = false
965
- }
966
- return v
967
- })
968
- if(checkAll && typeof checkAll === "string"){
969
- this.currFilOpts = this.currFilOpts.map( o => {
970
- o.checked = checkAll === "true" ? true : false;
971
- return o;
972
- })
973
-
974
- }
975
- this.isMultiFiltering.set(true);
976
- this.execFilter(col, "")
977
- setTimeout( () => { this.isMultiFiltering.set(false) })
978
- this.topLevelFilter = ""
979
- }
980
- }
981
-
982
- execFilter(field: any, val: any) {
983
- this.dataTableService.isFiltering.set(true)
984
- this.dataTableService.dataFilSrtTracker[field].filter = val || ""
985
- this.dataTableService.columnFilter(this.dataTableService.mainData, field, this.dataTableService.dataFilSrtTracker, this.dataTableService.sortOrder, true)
986
- this.renderCurrData(false, field)
987
- setTimeout( () => { this.dataTableService.isFiltering.set(false) }, 500)
988
- }
989
-
990
- tFilTO: any = null;
991
-
992
- topFilterOnKeyUp(event: any) {
993
- if(event && !this.common.keyCanSearch(event))
994
- return;
995
- if(!this.dataTableService.isFiltering()){
996
- this.dataTableService.isFiltering.set(true)
997
- this.dataTableService.easyFilter((this.topLevelFilter || ""), this.dataTableService.mainData, this.dataTableService.sortOrder)
998
- if(!this.topLevelFilter && !this.dataTableService.arefilSrtTrkPropsDefault()){
999
- let altField = Object.keys(this.dataTableService.mainData[0])[0]
1000
- this.dataTableService.columnFilter(this.dataTableService.mainData, altField, this.dataTableService.dataFilSrtTracker, this.dataTableService.sortOrder, false)
1001
- }
1002
- this.renderCurrData(false, "topLevelDataFilter")
1003
- if(this.tFilTO){
1004
- clearTimeout(this.tFilTO)
1005
- this.tFilTO = null
1006
- }
1007
- this.tFilTO = setTimeout( () => {
1008
- this.dataTableService.isFiltering.set(false)
1009
- const buildUpLen = this.filterBuildUp.length
1010
- if(buildUpLen){
1011
- this.topFilterOnKeyUp(null)
1012
- this.filterBuildUp = []
1013
- }
1014
- }, 500)
1015
- } else {
1016
- if(this.filterBuildUp.indexOf(this.topLevelFilter) < 0)
1017
- this.filterBuildUp.push(this.topLevelFilter)
1018
- }
1019
- }
1020
-
1021
- setHorizPos(event: any) {
1022
- const head = this.dataTableHeaders.nativeElement
1023
- if(event > 0)
1024
- head.style.marginLeft = -event + "px"
1025
- else
1026
- head.style.removeProperty("margin-left")
1027
- this.horizRest.set(event)
1028
- }
1029
-
1030
- blurContEd() {
1031
- const actEl = <HTMLElement>document.activeElement
1032
- if(actEl && actEl.getAttribute("contenteditable"))
1033
- actEl.blur()
1034
- }
1035
-
1036
- setColsOnVisScreen() {
1037
- const lftPlus = this.rowNumbers ? 75 : 0//ctrl+f "--row-num-width" in css
1038
- let i = 0
1039
- let vCols = []
1040
- const useCols = this.columnHeaders.filter( c => !c.minimized).map( c => c.column)
1041
- const len = useCols.length
1042
- for(i; i < len; i++){
1043
- const col = useCols[i]
1044
- const el = document.getElementById("columnHeader" + this.common.elifyCol(col))
1045
- if(el){
1046
- const elbds = el.getBoundingClientRect()
1047
- if(elbds.left >= (this.dataTableService.tblLeft-lftPlus) && elbds.right < this.dataTableService.tblRight)
1048
- vCols.push(col)
1049
- }
1050
- }
1051
- this.dataTableService.visibleCols = [...vCols]
1052
- }
1053
-
1054
- handleScroll(event: any) {
1055
- if(this.currGroupValues().length || this.dataTableService.showCharts())
1056
- return;
1057
- const top = event.target.scrollTop
1058
- const left = event.target.scrollLeft
1059
- /*horiz scroll*/
1060
- if(left !== this.horizRest())
1061
- requestAnimationFrame( () => { this.execHorizScroll(left) })
1062
- /*horiz scroll*/
1063
- /*vert scroll*/
1064
- if(top === this.verticalRest || this.lockVScroll){
1065
- this.isScrolling = false
1066
- if(!this.dataTableService.autoScrollOnEdit)
1067
- this.clearValidatedEdit();
1068
- return this.setRowSelChecksPlacement()
1069
- }
1070
- this.isScrolling = true
1071
- requestAnimationFrame( () => { this.execVertScroll(top) })
1072
- /*vert scroll*/
1073
- if(top%2===0)
1074
- this.clearValidatedEdit()
1075
- }
1076
-
1077
- execHorizScroll(left: number) {
1078
- const head = this.dataTableHeaders.nativeElement
1079
- if(left > 0)
1080
- head.style.marginLeft = -left + "px"
1081
- else
1082
- head.style.removeProperty("margin-left")
1083
- this.setColsOnVisScreen()
1084
- this.execHorizBodyScroll()
1085
- this.horizRest.set(left)
1086
- this.setColsOnVisScreen()
1087
- }
1088
-
1089
- execVertScroll(top: number) {
1090
- if(top >= this.verticalRest){
1091
- this.execVertScrollDown(this.columnNames, this.columnNames.length)
1092
- this.clearAboveFoldRows()
1093
- this.scrollDir = "down"
1094
- } else {//scrolling back up
1095
- this.execVertScrollUp(this.columnNames, this.columnNames.length)
1096
- this.clearBelowFoldRows()
1097
- this.scrollDir = "up"
1098
- }
1099
- this.verticalRest = top;
1100
- if(this.rowNumbers && top%2 === 0)
1101
- this.setRowNumbers()
1102
- }
1103
-
1104
- scrollDir: string = "down"
1105
-
1106
- handleScrollEnd(): any {
1107
- this.isScrolling = false
1108
- this.lockVScroll = false
1109
- if(this.currGroupValues().length)
1110
- return setTimeout( () => { this.dataTableService.gridScrollEndWhileGrouped.next(true) })
1111
- if(this.dataTableService.showCharts())
1112
- return;
1113
- setTimeout( () => {
1114
- this.dataTableService.autoScrollOnEdit = false
1115
- this.setColsOnVisScreen()
1116
- this.setRowSelChecksPlacement()
1117
- if(this.listenToCellDraggerMouseMove)
1118
- this.settleCellDragger()
1119
- setTimeout( () => { this.cleanUpPossibles() })
1120
- })
1121
- }
1122
-
1123
- addCell(text: any, prop: string, visible: boolean): DataCell {
1124
- const useProp = this.dataTableService.dataFilSrtTracker[prop]
1125
- const notNum = (this.dataTableService.figureFilterType(prop) != "number" || /(year|yr|fy)/g.test(prop.toLocaleLowerCase())) ? true : false
1126
- const useTxt = this.dataTableService.figureCellText(text, notNum, useProp["colCellSymbol"])
1127
- const colStyle = this.dataTableService.getColumnStyle(prop)
1128
- return {
1129
- column: prop,
1130
- rawText: text,
1131
- editable: useTxt.prop !== "textContent" ? false : this.editable,
1132
- dataType: this.dataTableService.figureFilterType(prop),
1133
- freeze: useProp.freeze,
1134
- visible: visible,
1135
- minimized: useProp.minimize,
1136
- width: useProp.colWidth || this.dataTableService.useColWid,
1137
- text: useTxt.prop === "textContent" ? useTxt.value : "",
1138
- html: useTxt.prop !== "textContent" ? useTxt.value : "",
1139
- specialColClass: (colStyle ? (colStyle + this.common.elifyCol(useTxt.value)) : ""),
1140
- }
1141
- }
1142
-
1143
- execHorizBodyScroll() {
1144
- const allcols = this.getAllColsAtRuntime(null);
1145
- let i = 0;
1146
- const clen = allcols.length
1147
- const rlen = this.rows.length
1148
- const lftPlus = this.rowNumbers ? 75 : 0//ctrl+f "--row-num-width" in css
1149
- let positions: any = []
1150
- const row0 = this.rows[0]
1151
- for(let p = (clen-1); p >= 0; p--){
1152
- const col = allcols[p]
1153
- const elcol = this.common.elifyCol(col)
1154
- const head = document.getElementById("columnHeader" + elcol)
1155
- if(head){
1156
- const bds = head.getBoundingClientRect()
1157
- if(bds.left > this.dataTableService.tblRight)
1158
- continue
1159
- const cell = row0?.cells?.find( c => c.column === col)
1160
- if(cell){
1161
- if(!cell.visible && (this.dataTableService.visibleCols.indexOf(col) > -1 || (bds.left >= (this.dataTableService.tblLeft-lftPlus) && bds.right < (this.dataTableService.tblRight+lftPlus))))//visible
1162
- positions.push({ col: col, vis: true })
1163
- if(cell.visible && this.dataTableService.visibleCols.indexOf(col) < 0 && !positions.find( (p: any) => p.col === col))
1164
- positions.push({ col: col, vis: false })
1165
- }
1166
- }
1167
- }
1168
- const plen = positions.length
1169
- for(i; i < rlen; i++){
1170
- let c = 0
1171
- const row = this.rows[i]
1172
- if(row){
1173
- for(c; c < plen; c++){
1174
- const pos = positions[c]
1175
- if(pos){
1176
- if(pos.vis){
1177
- row.cells = row.cells?.map( c => {
1178
- if(c.column === pos.col)
1179
- return this.addCell(c.rawText, pos.col, true)
1180
- return c
1181
- })
1182
- } else {
1183
- const rCell: DataCell | undefined = row.cells?.find( c => c.column === pos.col)
1184
- if(rCell){
1185
- rCell.visible = false
1186
- }
1187
- }
1188
- }
1189
- }
1190
- }
1191
- }
1192
- setTimeout( () => {
1193
- this.dataTableService.setIdealColumnWidth.next(true);
1194
- this.setColsOnVisScreen()
1195
- setTimeout( () => { this.cleanUpPossibles() })
1196
- }, 50)
1197
- }
1198
-
1199
- cleanUpPossibles() {
1200
- let i = 0
1201
- const len = this.rows.length
1202
- const lftPlus = this.rowNumbers ? 75 : 0//ctrl+f "--row-num-width" in css
1203
- for(i; i < len; i++){
1204
- const row = this.rows[i]
1205
- if(row){
1206
- let p = 0
1207
- if(row.cells?.length){
1208
- const rclen = row.cells.length
1209
- for(p; p < rclen; p++){
1210
- const cell = row.cells[p]
1211
- if(cell){
1212
- const ccol = cell.column
1213
- const el = document.querySelector("#" + row.id + " .data-cell-" + this.common.elifyCol(ccol))
1214
- if((el && el.getBoundingClientRect().right < (this.dataTableService.tblLeft-lftPlus)) && (!el?.innerHTML || !el.getAttribute("style"))){
1215
- row.cells[p].visible = true
1216
- row.cells[p] = {...this.addCell(cell.rawText, ccol, true)}
1217
- }
1218
- }
1219
- }
1220
- }
1221
- }
1222
- }
1223
- }
1224
-
1225
- execVertScrollDown(cols: string[], colLen: number) {
1226
- let canAdd = 0
1227
- const actvCols = this.columnHeaders.map(c => c.column)
1228
- const vlen = this.dataTableService.visibleCols.length
1229
- const lastVisInd = actvCols.indexOf(this.dataTableService.visibleCols[(vlen-1)]) + 1
1230
- const bel = this.belowArea.nativeElement
1231
- const bbds = bel.getBoundingClientRect()
1232
- const rTop = (bbds.top - this.verticalRest)
1233
- const gap = this.dataTableService.tblBot - rTop
1234
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1235
- if(gap > 0){
1236
- let h = 0
1237
- let z = this.lastElRowIndex + 1
1238
- const last = document.getElementById("dataTableRow" + this.lastElRowIndex)
1239
- if(last && this.dataTableService.elIsBelowFold(last, this.dataTableService.tblBot))
1240
- return;
1241
- let bhToSub = 0
1242
- let ahToAdd = 0
1243
- const rowsInGap = Math.ceil(gap/defNum)
1244
- canAdd = z+(rowsInGap)
1245
- let chksToAdd = []
1246
- let rowsToAdd: DataRow[] = []
1247
- const goTo = Math.min(this.dataTableService.currFilData.length, canAdd)
1248
- for(z; z < goTo; z++){
1249
- const wldBeElTop = bbds.top + (defNum*h);
1250
- const wldBeElBot = wldBeElTop+defNum
1251
- if(wldBeElBot < this.dataTableService.tblTop){
1252
- ahToAdd += defNum
1253
- bhToSub += defNum
1254
- } else {
1255
- if(wldBeElTop <= this.dataTableService.tblBot){
1256
- const item = this.dataTableService.currFilData[z]
1257
- const index = this.dataTableService.currMapping[z] || this.dataTableService.findObjIndxInData(item)
1258
- if(index > -1 && !this.rows.find( r => r.index === index)){
1259
- const nRow: DataRow = { id: "dataTableRow" + index, index: index, width: this.useRowWid, cells: [], height: this.dataTableService.defltRHgt }
1260
- let cells: DataCell[] = []
1261
- for(let k = (colLen-1); k >= 0; k--){
1262
- const col = cols[k]
1263
- const cell = this.addCell(item[col], col, (k <= lastVisInd))
1264
- if(typeof cell !== "string")
1265
- cells.unshift(cell)
1266
- }
1267
- nRow.cells = [...cells]
1268
- chksToAdd.push(index)
1269
- rowsToAdd.push(nRow)
1270
- bhToSub += defNum
1271
- }
1272
- }
1273
- }
1274
- h += 1
1275
- }
1276
- this.rows = [...this.rows, ...rowsToAdd]
1277
- if(bhToSub)
1278
- this.belowHgt.set(Math.max(0, this.belowHgt() - bhToSub))
1279
- if(chksToAdd.length)
1280
- this.dtChecks= [...this.dtChecks, ...chksToAdd]
1281
- if(ahToAdd)
1282
- this.aboveHgt.set(this.aboveHgt() + ahToAdd)
1283
- this.setLastRowIndex()
1284
- }
1285
- }
1286
-
1287
- execVertScrollUp(cols: string[], colLen: number) {
1288
- const actvCols = this.columnHeaders.map(c => c.column)
1289
- const vlen = this.dataTableService.visibleCols.length
1290
- const lastVisInd = actvCols.indexOf(this.dataTableService.visibleCols[(vlen-1)]) + 1;
1291
- const ael = this.aboveArea.nativeElement
1292
- const abds = ael.getBoundingClientRect()
1293
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1294
- const rbot = abds.bottom
1295
- const gap = rbot - (this.dataTableService.tblTop)
1296
- if(gap > 0){
1297
- let h = 0
1298
- const rlen = this.rows.length
1299
- let z = (this.lastElRowIndex - rlen)
1300
- if(z < 0)
1301
- return
1302
- let bhToAdd = 0
1303
- let ahToSub = 0
1304
- const rowsInGap = Math.ceil(gap/defNum)
1305
- const min = Math.max(0, (z-rowsInGap))
1306
- for(z; z >= min; z--){
1307
- const wldBeElBot = rbot - (defNum*h);
1308
- const wldBeElTop = wldBeElBot-defNum
1309
- if(wldBeElTop > this.dataTableService.tblBot){
1310
- bhToAdd += defNum
1311
- ahToSub += defNum
1312
- } else {
1313
- if(wldBeElBot > this.dataTableService.tblTop){
1314
- const item = this.dataTableService.currFilData[z]
1315
- const index = this.dataTableService.currMapping[z] || this.dataTableService.findObjIndxInData(item)
1316
- if(index > -1){
1317
- let k = 0
1318
- const nRow: DataRow = { id: "dataTableRow" + index, index: index, width: this.useRowWid, cells: [], height: this.dataTableService.defltRHgt }
1319
- let cells: DataCell[] = []
1320
- for(k; k < colLen; k++){
1321
- const col = cols[k]
1322
- const cell = this.addCell(item[col], col, (k <= lastVisInd))
1323
- if(typeof cell !== "string")
1324
- cells.push(cell)
1325
- }
1326
- nRow.cells = [...cells]
1327
- this.rows = [nRow, ...this.rows]
1328
- this.dtChecks = [index, ...this.dtChecks]
1329
- ahToSub += defNum
1330
- }
1331
- }
1332
- }
1333
- h += 1
1334
- }
1335
- if(ahToSub)
1336
- this.aboveHgt.set(Math.max(0, (this.aboveHgt() - ahToSub)))
1337
- if(bhToAdd)
1338
- this.belowHgt.set(this.belowHgt() + bhToAdd)
1339
- }
1340
- }
1341
-
1342
- clearAboveFoldRows() {
1343
- const els = this.rows.filter( r => this.dataTableService.elIsAboveFold(document.getElementById(r.id), (this.dataTableService.tblTop)))
1344
- const justids = els.map( e => e.id)
1345
- const justindx = els.map( e => e.index)
1346
- const changes = justids.length
1347
- if(changes > 0){
1348
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1349
- this.rows = this.rows.filter( r => justids.indexOf(r.id) < 0)
1350
- this.dtChecks = this.dtChecks.filter( c => justindx.indexOf(c) < 0)
1351
- const item = this.dataTableService.mainData[(this.rows[0]?.index || -1)]
1352
- if(item)
1353
- this.aboveHgt.set(Math.max(0, this.dataTableService.findObjIndxInData(item, this.dataTableService.currFilData)*defNum))
1354
- }
1355
- }
1356
-
1357
- clearBelowFoldRows() {
1358
- const els = this.rows.filter( r => this.dataTableService.elIsBelowFold(document.getElementById(r.id), this.dataTableService.tblBot))
1359
- const justids = els.map( e => e.id)
1360
- const justindx = els.map( e => e.index)
1361
- let changes = justids.length
1362
- if(changes > 0){
1363
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1364
- this.rows = this.rows.filter( r => justids.indexOf(r.id) < 0)
1365
- this.dtChecks = this.dtChecks.filter( c => justindx.indexOf(c) < 0)
1366
- const rlen = this.rows.length
1367
- const item = this.dataTableService.mainData[(this.rows[(rlen-1)]?.index || -1)]
1368
- if(item)
1369
- this.belowHgt.set(Math.max(0, ((this.dataTableService.currFilData.length-1)-this.dataTableService.findObjIndxInData(item, this.dataTableService.currFilData))*defNum))
1370
- this.setLastRowIndex()
1371
- }
1372
- }
1373
-
1374
- jumpToRow(row: number) {
1375
- if(this.dataTableBody){
1376
- const ind = row - 1
1377
- const tbl = this.dataTableBody.nativeElement
1378
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1379
- tbl.scrollTop = ind*defNum;
1380
- setTimeout( () => { this.setRowSelChecksPlacement() })
1381
- }
1382
- }
1383
-
1384
- scrollToRowGroup(rClass: string) {
1385
- const el = document.getElementsByClassName(rClass)[0]
1386
- if(el){
1387
- const dtb = this.dataTableBody.nativeElement
1388
- const dttop = dtb.getBoundingClientRect().top - dtb.scrollTop
1389
- const etop = el.getBoundingClientRect().top
1390
- this.dataTableBody.nativeElement.scrollTop = etop - dttop
1391
- }
1392
- }
1393
-
1394
- valEditFocusTo: number|null = null;
1395
-
1396
- handleValidatedCellEditFocus(cellData: any) {//{type: this.cell.dataType, value: this.cell.rawText}
1397
- this.validatedEditType = cellData.type
1398
- if(this.valEditFocusTo){
1399
- clearTimeout(this.valEditFocusTo)
1400
- this.valEditFocusTo = null
1401
- }
1402
- this.valEditFocusTo = setTimeout( () => {
1403
- const rel = this.validatedEdit.nativeElement
1404
- let el;
1405
- const elD = <HTMLDivElement>document.querySelector(".relly.edit-input")
1406
- if(!elD)//look for the one that's relly (relative) positioned first
1407
- el = <HTMLInputElement>document.getElementsByClassName("edit-input")[0]
1408
- const cell = document.querySelector("#dataTableRow" + this.dataTableService.currEditIndex + " .data-cell-" + this.common.elifyCol(this.dataTableService.currEditCol))
1409
- if((el || elD) && cell){
1410
- const rbds = rel.getBoundingClientRect()
1411
- const cbds = cell.getBoundingClientRect();
1412
- (el || elD).style.top = (cellData.type === "text" ? (Math.ceil(cbds.bottom-rbds.top) + 1) : (Math.ceil(cbds.top-rbds.top) + 1)) + "px";
1413
- (el || elD).style.left = (Math.ceil(cbds.left-rbds.left) + 1) + "px";
1414
- (el || elD).style.width = (cbds.width-2) + "px";
1415
- (el || elD).style.height = (cbds.height-2) + "px";
1416
- if(el){
1417
- el.value = cellData.type === "date" ? new Date(cellData.value)?.toISOString().split("T")[0] : cellData.value;
1418
- setTimeout( () => { el.focus() })
1419
- }
1420
- if(elD){//text w/ limited values
1421
- this.currSelEditOpts = this.dataTableService.dataFilSrtTracker[this.dataTableService.currEditCol]["selDDVals"]?.
1422
- filter( (g: any) => g.value !== "(Select All)").map( (s: any) => ({ ...s, selected: s.value === cellData.value }))
1423
- }
1424
- rel.classList.remove("invisible")
1425
- this.fCellDragger.nativeElement.style.left = (Math.ceil(cbds.left-rbds.left) + cbds.width - 4) + "px";
1426
- this.fCellDragger.nativeElement.style.top = (Math.ceil(cbds.bottom-rbds.top) - 4) + "px"
1427
- }
1428
- }, 10)
1429
- }
1430
-
1431
- clearFCellDragger() {
1432
- if(!this.dataTableService.autoScrollOnEdit){
1433
- this.fCellDragger.nativeElement.style.removeProperty("top")
1434
- this.fCellDragger.nativeElement.style.removeProperty("left")
1435
- }
1436
- }
1437
-
1438
- clearValidatedEdit(e?: any, clearDrag?: boolean) {
1439
- if(this.listenToCellDraggerMouseMove)
1440
- return;
1441
- if((e && e.type === "blur") || (e && e.type === "focus" && e.relatedTarget?.id === "fCellDragger")){
1442
- setTimeout( () => { this.handleCellDraggerInit() })
1443
- } else {
1444
- this.execValClear(clearDrag)
1445
- }
1446
- }
1447
-
1448
- execValClear(clearDrag?: boolean) {
1449
- this.blurContEd()
1450
- this.dataTableService.currEditIndex = -1
1451
- this.dataTableService.currEditCol = ""
1452
- this.validatedEditType = ""
1453
- this.currSelEditOpts = []
1454
- this.validatedEdit.nativeElement.classList.add("invisible")
1455
- if(clearDrag)
1456
- this.clearCellDEdits()
1457
- setTimeout( () => { this.dataTableService.clearAllFocused() })
1458
- }
1459
-
1460
- handleDraggerMU(e: any) {
1461
- if(e && e.target && e.target.id && e.target.id.startsWith("selEdit"))
1462
- return;
1463
- this.listenToCellDraggerMouseUp = false
1464
- if(this.listenToCellDraggerMouseMove){
1465
- this.listenToCellDraggerMouseMove = false
1466
- this.clearCellDEdits()
1467
- }
1468
- }
1469
-
1470
- handleDraggerKD(e: any) {
1471
- const row = document.getElementById("dataTableRow" + this.dataTableService.currEditIndex)
1472
- if(row && this.dataTableService.currEditCol){
1473
- let targRow;
1474
- let bds;
1475
- if(e && this.common.isDownKey(e))
1476
- targRow = row.nextElementSibling
1477
-
1478
- if(e && this.common.isUpKey(e))
1479
- targRow = row.previousElementSibling
1480
- if(targRow){
1481
- bds = targRow.getBoundingClientRect()
1482
- this.listenToCellDraggerMouseMove = true
1483
- const execDragEOnDK = (e: any) => {
1484
- this.handleCellDraggerEdit(e)
1485
- }
1486
- targRow.addEventListener("mousemove", execDragEOnDK)
1487
- const mouseEvent = new MouseEvent('mousemove', {
1488
- view: window,
1489
- bubbles: false,
1490
- cancelable: false,
1491
- clientX: bds.right, // X-coordinate relative to the viewport
1492
- clientY: bds.bottom, // Y-coordinate relative to the viewport
1493
- });
1494
- targRow.dispatchEvent(mouseEvent)
1495
- targRow.removeEventListener("mousemove", execDragEOnDK)
1496
- setTimeout( () => {this.listenToCellDraggerMouseMove = false})
1497
- if(e.target.getBoundingClientRect().bottom > (this.dataTableService.tblBot-100))
1498
- this.dataTableBody.nativeElement.scrollBy(0, this.dataTableService.dTblHeight/2)
1499
- }
1500
- }
1501
- }
1502
-
1503
- clearCellDEdits() {
1504
- this.clearFCellDragger()
1505
- this.dataTableService.clearDCellFcsd()
1506
- this.clearDragEditFlag()
1507
- }
1508
-
1509
- clearDragEditFlag() {
1510
- this.rows = this.rows.map( r => {
1511
- if(r.editedInDrag)
1512
- r.editedInDrag = false
1513
- return r
1514
- })
1515
- }
1516
-
1517
- handleCellDraggerInit() {
1518
- const actEl = document.activeElement
1519
- if(actEl && actEl.id === "fCellDragger"){
1520
- this.focusCellDragger()
1521
- } else {
1522
- if(!actEl || (actEl && !/data-cell/g.test(actEl?.className)))
1523
- this.execValClear()
1524
- }
1525
- }
1526
-
1527
- focusCellDragger() {
1528
- this.currSelEditOpts = []
1529
- this.validatedEditType = ""
1530
- this.validatedEdit.nativeElement.classList.add("invisible")
1531
- const cell= document.querySelector("#dataTableRow" + this.dataTableService.currEditIndex + " .data-cell-" + this.common.elifyCol(this.dataTableService.currEditCol))
1532
- if(cell)
1533
- cell.classList.add("dragger-cell-focused")
1534
- this.listenToCellDraggerMouseUp = true
1535
- }
1536
-
1537
- focusCellDraggerFromMouseDown() {
1538
- this.listenToCellDraggerMouseMove = true
1539
- }
1540
-
1541
- handleFDragTab(e: any) {
1542
- if(e && this.common.isTabKey(e)){
1543
- const cell = document.getElementsByClassName("dragger-cell-focused")[0]
1544
- const nxtCell: HTMLElement = <HTMLElement>cell.parentElement?.nextElementSibling?.firstElementChild
1545
- if(cell && nxtCell){
1546
- this.dataTableService.autoScrollOnEdit = true;
1547
- setTimeout( () => { nxtCell.focus() })
1548
- }
1549
- }
1550
- }
1551
-
1552
- settleCellDragger() {
1553
- const els = document.getElementsByClassName("dragger-cell-focused")
1554
- const len = els.length
1555
- const cell = this.scrollDir === "down" ? els[(len-1)] : els[0];
1556
- if(cell){
1557
- const fCellDragger = <HTMLElement>document.getElementsByClassName("focused-cell-dragger")[0]
1558
- const par = fCellDragger?.parentElement
1559
- if(fCellDragger && par){
1560
- const cbds = cell.getBoundingClientRect()
1561
- const rbds = par.getBoundingClientRect()
1562
- fCellDragger.style.left = (Math.ceil(cbds.left-rbds.left) + cbds.width - 4) + "px";
1563
- fCellDragger.style.top = (Math.ceil(cbds.bottom-rbds.top) - 4) + "px";
1564
- }
1565
- }
1566
- }
1567
-
1568
- handleCellDraggerEdit(e: any) {
1569
- if(e && e.target){
1570
- let dragId: number = -1;
1571
- const targ = e.target
1572
- try{
1573
- if(/dataTableRow/g.test(targ.id)){
1574
- dragId = parseInt(targ.id.replace("dataTableRow", ""))
1575
- } else {
1576
- if(/data-cell/g.test(targ.className))
1577
- dragId = parseInt(targ.getAttribute("data-index").replace("dataTableRow", ""))
1578
- }
1579
- let cell;
1580
- const row = this.rows.find( r => r.index === dragId)
1581
- const els = document.getElementsByClassName("dragger-cell-focused")
1582
- if(dragId > -1 && (row && !row.editedInDrag)){
1583
- const item = this.dataTableService.mainData[this.dataTableService.currEditIndex]
1584
- const val = item[this.dataTableService.currEditCol]
1585
- const currEInd = this.dataTableService.findObjIndxInData(item, this.dataTableService.currFilData)
1586
- const currDrgInd = this.dataTableService.findObjIndxInData(this.dataTableService.mainData[dragId], this.dataTableService.currFilData)
1587
- this.scrollDir = currDrgInd > currEInd ? "down" : "up";
1588
- this.dataTableService.currEditIndex = dragId
1589
- this.execCellEdit({ column: this.dataTableService.currEditCol, value: val }, true)
1590
- row.editedInDrag = true
1591
- cell = document.querySelector("#dataTableRow" + dragId + " .data-cell-" + this.common.elifyCol(this.dataTableService.currEditCol))
1592
- }
1593
- if(els.length > 1){
1594
- const dir = this.scrollDir === "down" ? 1 : -1;
1595
- const toScl = dir*(Math.ceil((e.offsetY || 20))/2)
1596
- this.dataTableBody.nativeElement.scrollBy(0, toScl)
1597
- }
1598
- const fCellDragger = <HTMLElement>document.getElementsByClassName("focused-cell-dragger")[0]
1599
- const par = fCellDragger?.parentElement
1600
- if(cell && fCellDragger && par){
1601
- const cbds = cell.getBoundingClientRect()
1602
- const rbds = par.getBoundingClientRect()
1603
- fCellDragger.style.left = (Math.ceil(cbds.left-rbds.left) + cbds.width - 4) + "px";
1604
- fCellDragger.style.top = (Math.ceil(cbds.bottom-rbds.top) - 4) + "px";
1605
- }
1606
- if(!cell){
1607
- const len = els.length
1608
- if(len){
1609
- if(e.clientY > this.dataTableService.tblBot){
1610
- cell = els[(len-1)]
1611
- }
1612
- if(e.clientY < this.dataTableService.tblTop){
1613
- cell = els[0]
1614
- }
1615
- if(cell && fCellDragger && par){
1616
- const cbds = cell.getBoundingClientRect()
1617
- const rbds = par.getBoundingClientRect()
1618
- fCellDragger.style.left = (Math.ceil(cbds.left-rbds.left) + cbds.width - 4) + "px";
1619
- fCellDragger.style.top = (Math.ceil(cbds.bottom-rbds.top) - 4) + "px";
1620
- }
1621
- }
1622
- }
1623
- }catch(e){}
1624
- }
1625
- }
1626
-
1627
- validateRawText(text: string, col: string, dataType: string): string {
1628
- const obj = this.dataTableService.dataFilSrtTracker[col]
1629
- if(obj && obj.selDDVals){
1630
- if(obj.selDDVals.map( (d: any) => d.value).includes(text))
1631
- return text
1632
- return "";
1633
- }
1634
- if(dataType === "number" && (!text || /[a-zA-Z \/]/g.test(text)))
1635
- return ""
1636
- return text
1637
- }
1638
-
1639
- execCellEdit(e: any, noBlur?: boolean, forceVal?: any/*from dropdown select, normally a string*/) {//{ column: this.cell.column, value: val }
1640
- if(this.dataTableService.currEditIndex > -1){
1641
- let cfDIdx;
1642
- const valEl = <HTMLInputElement>document.getElementsByClassName("edit-input")[0]
1643
- let val = forceVal ? forceVal : (valEl ? valEl.value : e.value);
1644
- if(val && !this.validateRawText(val, e.column, this.validatedEditType)){
1645
- if(!noBlur)
1646
- this.clearValidatedEdit(e)
1647
- return;
1648
- }
1649
- if(val && typeof val === "string" && this.validatedEditType === "date")
1650
- val = this.common.coerceDate(val)
1651
- if(val && typeof val === "string" && this.validatedEditType === "number")
1652
- val = /\./g.test(val) ? parseFloat(val) : parseInt(val);
1653
- const realProp: string = this.dataTableService.currEditCol || e.column;
1654
- this.dataTableService.mainData[this.dataTableService.currEditIndex][realProp] = val;
1655
- const item = this.dataTableService.mainData[this.dataTableService.currEditIndex]
1656
- if(item){
1657
- cfDIdx = this.dataTableService.findObjIndxInData(item, this.dataTableService.currFilData)
1658
- if(cfDIdx > -1)
1659
- this.dataTableService.currFilData[cfDIdx][realProp] = val
1660
- }
1661
- let cell;
1662
- const row = this.rows.find( r => r.index === this.dataTableService.currEditIndex)
1663
- if(row){
1664
- cell = row.cells?.find( c => c.column === this.dataTableService.currEditCol || c.column === e.column)
1665
- if(cell)
1666
- cell.rawText = val
1667
- }
1668
- const dtType = this.dataTableService.figureFilterType(realProp)
1669
- const notNum = (dtType != "number" || /(year|yr|fy)/g.test(realProp.toLocaleLowerCase())) ? true : false
1670
- const useTxt = this.dataTableService.figureCellText(val, notNum);
1671
- const cellEl = document.querySelector("#dataTableRow" + this.dataTableService.currEditIndex + " .data-cell-" + this.common.elifyCol(realProp))
1672
- if(cellEl){
1673
- if(useTxt.prop === "textContent")
1674
- cellEl.textContent = useTxt.value;
1675
- else
1676
- cellEl.innerHTML = useTxt.value;
1677
- if(cell){
1678
- cell.text = useTxt.prop === "textContent" ? useTxt.value : ""
1679
- if(this.listenToCellDraggerMouseMove)
1680
- cellEl.classList.add("dragger-cell-focused")
1681
- const colStyle = this.dataTableService.getColumnStyle(realProp)
1682
- if(colStyle)
1683
- cell.specialColClass = colStyle + this.common.elifyCol(useTxt.value)
1684
- }
1685
- }
1686
- const rowKey = (this.dataTableService.primaryKey ? this.dataTableService.mainData[this.dataTableService.currEditIndex][this.dataTableService.primaryKey] :
1687
- this.dataTableService.currEditIndex)
1688
- const edit: CellEdit = {
1689
- value: val,
1690
- column: realProp,
1691
- row: rowKey,
1692
- }
1693
- this.cellEdit.emit(edit)
1694
- if(!noBlur)
1695
- this.clearValidatedEdit(e)
1696
- }
1697
- }
1698
-
1699
- checkCellEditOnClick() {//for select dd edits only
1700
- if(this.dataTableService.currEditIndex > -1 && this.currSelEditOpts.length){
1701
- this.clearValidatedEdit()
1702
- setTimeout( () => {
1703
- const actEl = <HTMLElement>document.activeElement
1704
- if(!this.validatedEditType && this.dataTableService.currEditIndex === -1)
1705
- actEl.blur()
1706
- })
1707
- }
1708
- }
1709
-
1710
- handleSingleColResize(val: any, column?: string) {
1711
- if(val && (this.dataTableService.currColumnEdit || column)){
1712
- const cols = this.getAllColsAtRuntime(null);
1713
- const colLen = cols.length - this.getMiniColCount()
1714
- const rawCol = column || this.common.replaceUniSep(this.dataTableService.currColumnEdit)
1715
- const thecol = this.columnHeaders.find( c => (c && c.column === rawCol))
1716
- if(thecol){
1717
- thecol.width = (val + "px")
1718
- this.dataTableService.dataFilSrtTracker[thecol.column]["colWidth"] = (val + "px")
1719
- }
1720
- let i = 0
1721
- const toResize = this.rows.filter( r => r.cells?.length)
1722
- const len = toResize.length
1723
- for(i; i < len; i++){
1724
- const ind = toResize[i].index
1725
- const row = this.rows.find( r => r.index === ind)
1726
- if(row){
1727
- row.cells = row.cells?.map( c => {
1728
- if(c && c.column === rawCol)
1729
- c.width = (val + "px")
1730
- return c
1731
- })
1732
- }
1733
- }
1734
- setTimeout( () => {
1735
- const allColW = this.getAllColWidth(colLen)
1736
- this.setDataRowWidthsOnMinimize(allColW)
1737
- this.setRowSelChecksPlacement()
1738
- this.testHideMinBtn()
1739
- })
1740
- this.clearValidatedEdit()
1741
- }
1742
- }
1743
-
1744
- testHideMinBtn() {
1745
- let i = 0
1746
- const els = document.getElementsByClassName("btn-min-col")
1747
- const len = els.length
1748
- for(i; i < len; i++){
1749
- const el = els[i]
1750
- const col = el.id.replace(/btnMin/g, "")
1751
- const ellf = el.getBoundingClientRect().left
1752
- const srt = document.getElementById("btnSort" + col)
1753
- const colHd = this.columnHeaders.find( c => c.column === this.common.replaceUniSep(col))
1754
- if(colHd && srt){
1755
- const srtrt = srt.getBoundingClientRect().right + 5;
1756
- if(ellf < srtrt)
1757
- colHd.hideMinCol = true
1758
- else
1759
- colHd.hideMinCol = false
1760
- }
1761
- }
1762
- }
1763
-
1764
- setHeaderHeight(val: any, force?: boolean) {
1765
- if(val && typeof val === "string")
1766
- val = Math.ceil(parseInt(val))
1767
- const rHgt = force ? val : Math.max(val, parseInt(this.desRowHeight))
1768
- const useHgt = Math.floor(rHgt) + "px";
1769
- const row = this.dataTableHeaders.nativeElement
1770
- row["style"]["height"] = useHgt
1771
- this.columnHeaders.forEach( c => {c.height = useHgt})
1772
- if(this.rowNumbers && this.rowNumHeader)
1773
- this.rowNumHeader.nativeElement.style.height = useHgt;
1774
- setTimeout( () => { this.setRowSelChecksPlacement() })
1775
- }
1776
-
1777
- setSingleRowHgt(val: any, row?: any, force?: boolean) {
1778
- if(val && typeof val === "string")
1779
- val = Math.ceil(parseInt(val))
1780
- const rHgt = force ? val : Math.max(val, (parseInt(this.desRowHeight) || Math.ceil(row.getBoundingClientRect().height)))
1781
- const useHgt = Math.floor(rHgt) + "px";
1782
- if(typeof row === "string" && this.tblDragService.colDragStartFrmCellTracker.row && this.tblDragService.colDragStartFrmCellTracker.ystart){
1783
- const drow = this.rows.find( r => r.id === row)
1784
- if(drow){
1785
- drow.height = useHgt
1786
- if(this.rowNumbers){
1787
- const item = this.dataTableService.mainData[drow?.index]
1788
- if(item){
1789
- const indx = this.dataTableService.findObjIndxInData(item, this.dataTableService.currFilData) + 1
1790
- const rNum = this.rowNos.find( r => r.number === indx)
1791
- if(rNum)
1792
- rNum.height = useHgt
1793
- }
1794
- }
1795
- }
1796
- }
1797
- setTimeout( () => { this.setRowSelChecksPlacement() })
1798
- this.clearValidatedEdit()
1799
- }
1800
-
1801
- checkTabHorizScroll(id: string) {
1802
- const colH = document.getElementById("columnHeader" + id)
1803
- const dtb = this.dataTableBody.nativeElement
1804
- if(colH && dtb){
1805
- let left = (colH.getBoundingClientRect().left-50)
1806
- if(colH){
1807
- if(this.currGroupValues().length){
1808
- let i = 0
1809
- const els = document.getElementsByClassName("group-panel-grid")
1810
- const len = els.length
1811
- for(i; i < len; i++)
1812
- els[i].scrollBy(left, 0)
1813
- } else {
1814
- left -= (this.rowNumbers ? 75 : 0)
1815
- dtb.scrollBy(left, 0)
1816
- }
1817
- }
1818
- }
1819
- }
1820
-
1821
- handleTheme(co1: string | null, co2: string | null) {
1822
- try{
1823
- let rule1; let rule1a; let rule2; let rule3; let rule4; let rule5; let rule6; let rule7;
1824
- if(co1){
1825
- this.dataTableService.themeColor1 = co1
1826
- rule1 = ".col-header span, .col-header sup, .col-header button .material-icons, " +
1827
- ".row-group-panel button span, .row-group-panel button i, .data-table-footer div, .btn-fil-comp i{color: "+co1+" !important}";
1828
- rule1a = ".col-header select, .col-header input:not(input[type=file]), #skipTo{box-shadow:0 0 1px 1px "+co1+";" +
1829
- "-webkit-box-shadow:0 0 1px 1px "+co1+"}";
1830
- }
1831
- if(co2){
1832
- this.dataTableService.themeColor2 = co2
1833
- rule2 = ".col-header, .data-table-footer, .btn-fil-comp{background-color: "+co2+" !important}"
1834
- const tblbxSh = "0 -1px 3px 1px ";
1835
- const tblFbxSh = "0 1px 3px -3px ";
1836
- if(this.dataTableService.mainDataLen){
1837
- rule2 = ".col-header, .btn-fil-comp{background-color: "+co2+" !important}"
1838
- rule3 = ".data-table{ box-shadow: "+tblbxSh + co2+"; -webkit-box-shadow: "+tblbxSh + co2+"; -moz-box-shadow: "+tblbxSh + co2+"}"
1839
- rule6 = ".data-table-footer{background-color: "+co2+"; box-shadow: "+tblFbxSh + co2+"; -webkit-box-shadow: "+tblFbxSh + co2+"; -moz-box-shadow: "+tblFbxSh + co2+"}";
1840
- }
1841
- rule4 = ".row-group-panel{background: "+co2+"}";
1842
- if(co1)
1843
- rule4 = ".row-group-panel{background: "+co2+"; border-bottom: 1px dotted "+co1+"}";
1844
- rule5 = ".data-cell{ border-bottom: 1px solid "+co2+" !important; border-right: 1px solid "+co2+" !important}"
1845
- }
1846
- if(this.altRowColor)
1847
- rule7 = ".data-table-row:not(.data-row-selected):nth-of-type(even){background:"+this.altRowColor+"}"
1848
- let el;
1849
- if(rule1 || rule1a || rule2 || rule3 || rule4 || rule5 || rule6 || rule7){
1850
- el = document.createElement("style")
1851
- document.head.appendChild(el)
1852
- if(rule1)
1853
- el.sheet?.insertRule(rule1)
1854
- if(rule1a)
1855
- el.sheet?.insertRule(rule1a)
1856
- if(rule2)
1857
- el.sheet?.insertRule(rule2)
1858
- if(rule3)
1859
- el.sheet?.insertRule(rule3)
1860
- if(rule4)
1861
- el.sheet?.insertRule(rule4)
1862
- if(rule5)
1863
- el.sheet?.insertRule(rule5)
1864
- if(rule6)
1865
- el.sheet?.insertRule(rule6)
1866
- if(rule7)
1867
- el.sheet?.insertRule(rule7)
1868
- }
1869
- this.handleColumnCss(el)
1870
- }catch(e){}
1871
- }
1872
-
1873
- handleColumnCss(cssSheet: HTMLStyleElement|undefined) {
1874
- const clen = this.dataTableService.columnStyles.length
1875
- let i = 0;
1876
- if(clen){
1877
- if(!cssSheet){
1878
- cssSheet = document.createElement("style");
1879
- document.head.appendChild(cssSheet)
1880
- }
1881
- if(cssSheet){
1882
- for(i; i < clen; i++){
1883
- let o = 0
1884
- const cStyle = this.dataTableService.columnStyles[i]
1885
- const col = cStyle.column
1886
- const csss = cStyle.css
1887
- const csslen = csss.length
1888
- const elCol = this.common.elifyCol(col)
1889
- for(o; o < csslen; o++){
1890
- const css = csss[o]
1891
- const val = css.value
1892
- let rule = (".data-cell-" + elCol + "-" + this.common.elifyCol(val) + " {");
1893
- for(const prop in css){
1894
- const cval: string = css[prop as keyof ValueCss] || "";
1895
- if(cval && prop !== "value")
1896
- rule += (prop.replace(/_/g, "-") + ": " + cval + "; ");
1897
- }
1898
- rule += "} ";
1899
- if(cssSheet.sheet)
1900
- cssSheet.sheet.insertRule(rule)
1901
- }
1902
- }
1903
- }
1904
- }
1905
- }
1906
-
1907
- renderCurrData(reset: boolean, field?: any): any {//filter val
1908
- const thead = this.dataTableHeaders.nativeElement
1909
- const tbody = this.dataTableBody.nativeElement
1910
- const tbodyX = tbody.scrollLeft
1911
- this.rows = []
1912
- this.aboveHgt.set(0)
1913
- this.belowHgt.set(0)
1914
- this.rowNos = []
1915
- this.dtChecks = []
1916
- this.clearValidatedEdit(null, true)
1917
- this.dataTableService.currMapping = {}
1918
- if(!this.currGroupValues().length)//only if not grouped
1919
- this.horizRest.set(0)
1920
- tbody.scrollTop = 0
1921
- this.verticalRest = 0
1922
- let didXScrl = false;
1923
- if(reset && !field && thead && tbody && !this.currGroupValues().length){
1924
- thead.style.marginLeft = "0px"
1925
- tbody.scrollLeft = 0
1926
- this.horizRest.set(0)
1927
- }
1928
- this.lastElRowIndex = 0
1929
- let n = 0
1930
- const defNum = parseInt(this.dataTableService.defltRHgt.replace(/[ ]?px/g, ""))
1931
- const init = Math.max(this.dataTableService.dTblHeight/defNum);
1932
- const len = this.dataTableService.currFilData.length;
1933
- if(!len){//always just add 1
1934
- this.allFilSortInfo.set(this.dataTableService.getAllFilSrtInfo())
1935
- return setTimeout( () => { this.styleEmptyFilDataRow(tbody, tbodyX) })
1936
- }
1937
- if(this.currGroupValues().length){//don't add to rows here
1938
- if(field)
1939
- this.columnOfInterest.set(field)
1940
- this.allFilSortInfo.set(this.dataTableService.getAllFilSrtInfo())
1941
- return this.dataTableService.gridEventWhileGrouped.next(true);
1942
- }
1943
- const uCols = [...this.columnHeaders]
1944
- const colLen = uCols.length
1945
- const addCell = (text: any, prop: string | null, row: DataRow, indx: number, visible: boolean) => {
1946
- if(prop && row){
1947
- const notNum = (this.dataTableService.figureFilterType(prop) != "number" || /(year|yr|fy)/g.test(prop.toLocaleLowerCase())) ? true : false
1948
- const useTxt = this.dataTableService.figureCellText(text, notNum, this.dataTableService.dataFilSrtTracker[prop]["colCellSymbol"])
1949
- const colStyle = this.dataTableService.getColumnStyle(prop)
1950
- row.cells?.push({
1951
- column: prop,
1952
- rawText: text,
1953
- visible: visible,
1954
- editable: useTxt.prop === "textContent" ? this.editable : false,
1955
- dataType: this.dataTableService.figureFilterType(prop),
1956
- freeze: this.dataTableService.dataFilSrtTracker[prop].freeze,
1957
- minimized: this.dataTableService.dataFilSrtTracker[prop].minimize,
1958
- width: this.dataTableService.dataFilSrtTracker[prop].colWidth || this.dataTableService.useColWid,
1959
- text: useTxt.prop === "textContent" ? useTxt.value : "",
1960
- html: useTxt.prop !== "textContent" ? useTxt.value : "",
1961
- specialColClass: (colStyle ? (colStyle + this.common.elifyCol(useTxt.value)) : ""),
1962
- })
1963
- }
1964
-
1965
- if(row && prop && row.cells && row.cells.length === 1)
1966
- this.dtChecks.push(indx)
1967
- if(field && field === prop && !didXScrl){
1968
- setTimeout( () => {
1969
- tbody.scrollLeft = tbodyX
1970
- if(thead)
1971
- thead.style.marginLeft = (-tbodyX + "px")
1972
- this.horizRest.set(tbodyX)
1973
- }, 100)
1974
- didXScrl = true
1975
- }
1976
- }
1977
- this.useRowWid = this.getAllColWidth(colLen - this.getMiniColCount()) + "px";
1978
- const limit = Math.min(init, len)
1979
- this.maxCols = this.setMaxCols()
1980
- let horizLim = Math.min(this.maxCols, colLen)
1981
- if(field && field !== "topLevelDataFilter"){
1982
- let room = 0
1983
- let offst = 3
1984
- const fhead = document.getElementById("columnHeader" + this.common.elifyCol(field))
1985
- if(fhead){
1986
- const bds = fhead.getBoundingClientRect()
1987
- room = this.dataTableService.tblRight - bds.right
1988
- if(room > 0)
1989
- offst = Math.ceil(room/bds.width)
1990
- }
1991
- horizLim = Math.max(horizLim, (uCols.map( c => c.column).indexOf(field) + offst))
1992
- }
1993
- for(n; n < limit; n++){
1994
- const item = this.dataTableService.currFilData[n]
1995
- const index = !reset ? this.dataTableService.findObjIndxInData(item) : n
1996
- if(index > -1){
1997
- const row: DataRow = { id: "dataTableRow" + index, index: index, width: this.useRowWid, cells: [], height: this.dataTableService.defltRHgt }
1998
- this.rows.push(row)
1999
- let k = 0
2000
- for(k; k < colLen; k++){
2001
- const col = uCols[k]?.column
2002
- if(col)
2003
- addCell(item[col], col, row, index, (k <= horizLim))
2004
- }
2005
- this.dataTableService.currMapping[n] = index
2006
- }
2007
- }
2008
- this.setLastRowIndex()
2009
- this.allFilSortInfo.set(this.dataTableService.getAllFilSrtInfo())
2010
- this.dataTableService.mapperWorkerId += 1//a reset but needs to incr so prev don't affect mapping
2011
- if(len){
2012
- if(len > init){
2013
- let total = 0
2014
- let z = this.lastElRowIndex + 1
2015
- for(z; z < len; z++){
2016
- total += 1
2017
- if(reset)
2018
- this.dataTableService.currMapping[z] = z
2019
- }
2020
- this.belowHgt.set(total*defNum)
2021
- if(!reset){
2022
- if (typeof Worker !== 'undefined') {
2023
- // Create a new
2024
- let worker
2025
- worker = new Worker(new URL('../worker.worker.ts', import.meta.url));
2026
- worker.onmessage = ({ data }) => {//{ id: data.id, map: {} }
2027
- if(this.dataTableService.mapperWorkerId === data.id)
2028
- this.dataTableService.currMapping = {...data.map}
2029
- };
2030
- if(worker)
2031
- worker.postMessage({id: this.dataTableService.mapperWorkerId, pk: this.dataTableService.primaryKey, main: this.dataTableService.mainData, curr: this.dataTableService.currFilData});
2032
- }
2033
- }
2034
- }
2035
- this.dataTableService.setIdealColumnWidth.next(true)
2036
- setTimeout( () => { this.setRowSelChecksPlacement(); this.setHoldingCheckCls() })
2037
- }
2038
- }
2039
-
2040
- styleEmptyFilDataRow(tbody: HTMLElement, tbodyX: number) {
2041
- const row = <HTMLElement>document.getElementsByClassName("data-table-row-no-data")[0]
2042
- if(row){
2043
- row.style.width = this.dataTableHeaders.nativeElement.scrollWidth + "px"
2044
- setTimeout( () => tbody.scrollLeft = tbodyX, 100)
2045
- }
2046
- }
2047
-
2048
- freezeColCells(col: string) {
2049
- this.rows = this.rows.map( r => {
2050
- r.cells = r.cells?.map( c => {
2051
- if(c && c.column === col)
2052
- c.freeze = !c.freeze
2053
- return c
2054
- })
2055
- return r
2056
- })
2057
- this.dataTableService.gridEventWhileGrouped.next(true)
2058
- }
2059
-
2060
- maximizeColCells(col: string, fullClear?: boolean) {
2061
- this.dataTableService.dataFilSrtTracker[col].minimize = false
2062
- this.minimizeColEls(col, fullClear)
2063
- }
2064
-
2065
- minimizeColEls(col: string, fullClear?: boolean) {
2066
- this.lockVScroll = true
2067
- if(!fullClear)
2068
- setTimeout( () => { this.lockVScroll = false }, 1000)
2069
- const thecol = this.columnHeaders.find( c => c.column === col)
2070
- if(thecol){
2071
- thecol.width = this.dataTableService.dataFilSrtTracker[col].colWidth || this.dataTableService.useColWid;
2072
- thecol.minimized = !thecol.minimized
2073
- }
2074
- this.rows = this.rows.map( r => {
2075
- r.cells = r.cells?.map( c => {
2076
- if(c && c.column === col)
2077
- c.minimized = !c.minimized
2078
- return c
2079
- })
2080
- return r
2081
- })
2082
- if(this.hiddenCols.indexOf(col) < 0)
2083
- this.hiddenCols.push(col)
2084
- else
2085
- this.hiddenCols = this.hiddenCols.filter( c => c !== col)
2086
- setTimeout( () => { this.dataTableService.setTblBounds(); this.testHideMinBtn() })
2087
- setTimeout( () => {
2088
- if(!fullClear || (fullClear && this.hiddenCols.length === 1)){
2089
- this.setTableWidthOnChange()
2090
- setTimeout( () => {
2091
- this.dataTableBody.nativeElement.scrollBy(1, 0)
2092
- this.scrollAllGBPanels()
2093
- this.setRowSelChecksPlacement()
2094
- })
2095
- }
2096
- }, 750)
2097
- }
2098
-
2099
- scrollAllGBPanels() {
2100
- let i = 0
2101
- const els = document.getElementsByClassName("group-panel-grid")
2102
- const len = els.length
2103
- for(i; i < len; i++)
2104
- els[i].scrollBy(1, 0)
2105
- }
2106
-
2107
- setTableWidthOnChange() {
2108
- const cols = this.getAllColsAtRuntime(null)
2109
- this.maxCols = this.setMaxCols()
2110
- const colLen = cols.length - this.getMiniColCount()
2111
- setTimeout( () => {
2112
- this.setDataRowWidthsOnMinimize(this.getAllColWidth(colLen))
2113
- }, 375)
2114
- this.setHoldingCheckCls()
2115
- this.setColsOnVisScreen()
2116
- setTimeout( () => { this.setColHeaderHgt() })
2117
- }
2118
-
2119
- setHoldingCheckCls() {
2120
- this.dataTableService.firstCol = this.columnHeaders.filter( c => !c.minimized)[0].column
2121
- }
2122
-
2123
- setDataRowWidthsOnMinimize(width: number) {
2124
- let i = 0;
2125
- const wid = width + "px"
2126
- const rLen = this.rows.length
2127
- for(i; i < rLen; i++)
2128
- this.rows[i].width = wid
2129
- this.useRowWid = wid;
2130
- this.dataTableService.gridEventWhileGrouped.next(true)
2131
- }
2132
-
2133
- clearHiddenCols() {
2134
- const len = this.hiddenCols.length
2135
- for(var i = (len-1); i >= 0; i--)
2136
- this.maximizeColCells(this.hiddenCols[i], true)
2137
- setTimeout( () => { this.lockVScroll = false }, 900)
2138
- }
2139
-
2140
- clearFilInputs() {
2141
- let i = 0
2142
- const els = document.querySelectorAll(".col-header input")
2143
- const len = els.length
2144
- for(i; i < len; i++){
2145
- const el = <HTMLInputElement>els[i]
2146
- if(el)
2147
- el.value = ""
2148
- }
2149
- }
2150
-
2151
- clearGroupBySels() {
2152
- let i = 0
2153
- const len = this.canGroupBy().length
2154
- for(i; i < len; i++){
2155
- const el = <HTMLInputElement>document.getElementById("groupby" + this.canGroupBy()[i])
2156
- if(el)
2157
- el.checked = false
2158
- }
2159
- }
2160
-
2161
- resetCurrentData(col?: string) {
2162
- this.topLevelFilter = ""
2163
- this.dataTableService.sortOrder = []
2164
- this.clearHiddenCols()
2165
- this.clearSelectedRows()
2166
- this.removeAllFreezeCols()
2167
- this.clearFilInputs()
2168
- this.resetVisCols()
2169
- this.clearGroupBySels()
2170
- this.allFilSortInfo.set("")
2171
- this.columnOfInterest.set("")
2172
- this.currGroupValues.set([])
2173
- this.dataTableService.currGroup = ""
2174
- this.dataTableService.setTblBounds()
2175
- this.dataTableService.resetFilSrtTracker()
2176
- this.dataTableService.currFilData = this.dataTableService.mainData.filter( d => { return true })
2177
- this.renderCurrData(true, col)
2178
- }
2179
-
2180
- resetVisCols() {
2181
- let i = 0
2182
- this.dataTableService.visibleCols = []
2183
- const len = this.columnHeaders.length
2184
- for(i; i < len; i++){
2185
- if(i < this.maxCols)
2186
- this.dataTableService.visibleCols.push(this.columnHeaders[i].column)
2187
- }
2188
- }
2189
-
2190
- getMiniColCount() {
2191
- let o = 0
2192
- for(const prop in this.dataTableService.dataFilSrtTracker){
2193
- if(this.dataTableService.dataFilSrtTracker[prop].minimize)
2194
- o += 1
2195
- }
2196
- return o
2197
- }
2198
-
2199
- handleValidation() {
2200
- if(this.dataTableService.isLocalHost(true)){
2201
- this.validationSettled.set(true)
2202
- if(this.data().length)
2203
- this.handleDataInput()
2204
- } else {
2205
- this.validationSub = this.dataTableService.validateLicense(this.licenseKey).pipe(
2206
- finalize( () => {
2207
- this.validationSettled.set(true);
2208
- if(this.data().length)
2209
- this.handleDataInput()
2210
- } )).
2211
- subscribe({
2212
- next: () => { this.common.setLs() },
2213
- error: e => {
2214
- this.dataTableService.errorLoading = true
2215
- this.dataTableService.noDataMsg = "License validation failed. The data grid will have limited functionality.";
2216
- console.log("INVALID LICENSE KEY")
2217
- }
2218
- })
2219
- }
2220
- }
2221
-
2222
- ngOnDestroy() {
2223
- if(this.validationSub)
2224
- this.validationSub.unsubscribe()
2225
- }
2226
- }