tablevu 0.1.4 → 0.2.1

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.
package/src/table.js CHANGED
@@ -1,382 +1,580 @@
1
- /*
2
- * tablevu
3
- * A small, fast, easy-to-use table component.
4
- * Copyright (c) 2020 Ender Boz <ender.boz@gmail.com>
5
- * https://github.com/endb/tablevu/LICENCE
6
- */
7
-
8
- import { h, reactive, watch } from 'vue';
9
-
10
- const tablevuStatuses = { Error: -1, Ready: 0, Loading: 1 };
11
-
12
- const tablevu = {
13
- props: {
14
- data: { type: [Array, Object] },
15
- search: { type: String },
16
- filter: { type: [Array, Object] },
17
- command: { type: Array, default: [] },
18
- rowid: { type: String },
19
- onRowClick: { type: Function },
20
- onRowDblClick: { type: Function },
21
- class: { type: String, default: 'table' },
22
- buttonclass: { type: String, default: 'btn' }
23
- },
24
-
25
- setup(props) {
26
- let rows = [];
27
-
28
- const spec = reactive({
29
- pageSize: props.data.pageSize || 20,
30
- pageCount: 0,
31
- currPage: 0,
32
- sort: props.data.sort || [],
33
- status: tablevuStatuses.Ready,
34
- timer: null,
35
- time: null,
36
- cols: [],
37
- filter: null,
38
- search: null
39
- });
40
-
41
- // Setup Search Input //
42
- watch(() => props.search, (n,o) => {
43
- if (spec.timer)
44
- clearTimeout(spec.timer);
45
-
46
- if ((o && o.length > (props.data.searchMinChar || 3) && (n == undefined || n == null || n.length <= (props.data.searchMinChar || 3))) || (n && n.length > (props.data.searchMinChar || 3))) {
47
- spec.timer = setTimeout(() => { if (props.search && props.search.length > (props.data.searchMinChar || 3)) spec.search = props.search; else spec.search = null; refresh(); }, 444);
48
- }
49
- });
50
-
51
- // Setup dynamic filter //
52
- watch(() => props.filter, () => {
53
- if (props.filter)
54
- spec.filter = props.filter;
55
- else
56
- spec.filter = null;
57
-
58
- refresh();
59
- }, { deep: true });
60
-
61
- // Setup commands //
62
- watch(() => props.command, (n,o) => {
63
- if (n && n.length > 0) {
64
- const c = props.command[n.length-1];
65
-
66
- if (c && c.name) {
67
- if (c.name.toLowerCase() == 'refresh') refresh()
68
- else if (c.name.toLowerCase() == 'first') first()
69
- else if (c.name.toLowerCase() == 'prior') prior()
70
- else if (c.name.toLowerCase() == 'next') next()
71
- else if (c.name.toLowerCase() == 'last') last()
72
- else console.log('Unknown command');
73
- }
74
-
75
- props.command.length = 0;
76
- }
77
- }, { deep: true });
78
- /*****************************************************************
79
-
80
- *****************************************************************/
81
- function first() { // Go First Page //
82
- page(1);
83
- }
84
-
85
- function prior() { // Go Previus Page //
86
- if (spec.currPage > 1) {
87
- page(spec.currPage - 1);
88
- } else {
89
- page(spec.currPage);
90
- }
91
- }
92
-
93
- function next() { // Go Next Page //
94
- page(spec.currPage + 1);
95
- }
96
-
97
- function last() { // Go Last Page //
98
- page(spec.pageCount);
99
- }
100
-
101
- function refresh() { // Refresh active page //
102
- page(spec.currPage);
103
- }
104
-
105
- function orderby(ind) { // Sort data //
106
- if (spec.sort && spec.sort.length > 0) {
107
- let l = spec.sort.findIndex(f => f.index == ind);
108
-
109
- if (l == 0) {
110
- spec.sort[l].dir = spec.sort[0].dir ? null : 'desc';
111
- } else if (l > 0) {
112
- spec.sort.splice(l, 1);
113
- }
114
-
115
- if (l != 0) {
116
- spec.sort.unshift({ index: ind, dir: null });
117
- }
118
-
119
- if (spec.sort.length > 2) {
120
- spec.sort.pop();
121
- }
122
- } else {
123
- spec.sort.push({ index: ind, dir: null });
124
- }
125
-
126
- page(spec.currPage);
127
- }
128
-
129
- // Go Custom Page number //
130
- function page(currentPage) {
131
- if (!props.data) {
132
- return;
133
- }
134
-
135
- //const tm = Date.now();
136
-
137
- spec.status = tablevuStatuses.Loading;
138
- //spec.currPage = currentPage;
139
-
140
- if (Array.isArray(props.data)) {
141
- rows = props.data;
142
-
143
- spec.pageCount = (rows.length > 0 && spec.pageSize > 0) ? (rows.length / spec.pageSize) : 0;
144
- spec.status = tablevuStatuses.Ready;
145
- spec.currPage = currentPage;
146
- spec.time = Date.now();
147
- }
148
-
149
- if (props.data.adapter) {
150
- const r = props.data.adapter({ pageSize: spec.pageSize, pageCount: spec.pageCount, currPage: currentPage, sort: spec.sort, cols: spec.cols, filter: spec.filter, search: spec.search });
151
-
152
- fetch(r).then(res => res.json()).then(res => {
153
- let cnt = 0;
154
- if (res && Object.hasOwnProperty.call(res, '@count')) {
155
- cnt = BigInt.parse(res['@count']);
156
- }
157
-
158
- if (res && res.value) {
159
- rows = res.value;
160
-
161
- spec.pageCount = (cnt > 0 && spec.pageSize > 0) ? (cnt / spec.pageSize) : 0;
162
- spec.status = tablevuStatuses.Ready;
163
- spec.currPage = currentPage;
164
- spec.time = Date.now();
165
- }
166
- }).catch(err => {
167
- console.error(err);
168
- // debugger;
169
- spec.status = tablevuStatuses.Error;
170
- alert(err.message);
171
- });
172
- }
173
- }
174
- /*****************************************************************
175
- Render Functions
176
- *****************************************************************/
177
- function renderCell(col, val) {
178
- let v;
179
- const o = { style: {} };
180
-
181
- if (col.align) {
182
- o.style['text-align'] = col.align;
183
- }
184
-
185
- if (col.width) {
186
- o.style['max-width'] = col.width;
187
- }
188
-
189
- if (val) {
190
- if (col.type == 'datetime' || col.type == 'date' || col.type == 'time') {
191
- let t = new Date(val);
192
-
193
- if (col.type == 'date')
194
- v = t.toLocaleDateString();
195
- else
196
- if (col.type == 'time')
197
- v = t.toLocaleTimeString();
198
- else
199
- v = t.toLocaleString();
200
- } else {
201
- if (col.type == 'numeric') {
202
- v = Number.parse(val);
203
- } else {
204
- v = val;
205
- }
206
- }
207
- } else {
208
- v = '';
209
- }
210
-
211
- return h('td', o, v);
212
- }
213
-
214
- function renderCustomCell(col, row) {
215
- const o = { style: {} };
216
-
217
- if (col.align) {
218
- o.style['text-align'] = col.align;
219
- }
220
-
221
- if (col.width) {
222
- o.style['max-width'] = col.width;
223
- }
224
-
225
- let f = col.render(row);
226
-
227
- return h('td', o, f);
228
- }
229
-
230
- function renderRow(index, row) {
231
- const o = {};
232
- const r = [];
233
-
234
- o.key = index;
235
-
236
- if (props.rowid) {
237
- o.rowid = row[props.rowid];
238
- }
239
-
240
- for (let i = 0; i < spec.cols.length; i += 1) {
241
- let v;
242
- const c = spec.cols[i];
243
-
244
- if (c.render) {
245
- v = renderCustomCell(c, row);
246
- r.push(v);
247
- } else {
248
- if (c.depth) {
249
- v = row;
250
- for (let j = 0; j < c.depth.length; j += 1) {
251
- if (v)
252
- v = v[c.depth[j]];
253
- }
254
- } else {
255
- v = row[c.name];
256
- }
257
-
258
- r.push(renderCell(c, v));
259
- }
260
- }
261
-
262
- if (props.data.onRowDblClick) {
263
- o.ondblclick = (event) => {
264
- const r = rows[event.currentTarget.rowIndex-1];
265
- props.data.onRowDblClick(event, r);
266
- };
267
- } else if (props.onRowDblClick) {
268
- o.ondblclick = (event) => {
269
- const r = rows[event.currentTarget.rowIndex-1];
270
- props.onRowDblClick(event, r);
271
- };
272
- }
273
-
274
- if (props.onRowClick) {
275
- o.onClick = (event) => {
276
- const r = rows[event.currentTarget.rowIndex-1];
277
- props.onRowClick(event, r);
278
- };
279
- }
280
-
281
- return h('tr', o, r);
282
- }
283
-
284
- function renderHeader() {
285
- const th = [];
286
-
287
- for (let i = 0; i < spec.cols.length; i += 1) {
288
- const s = [];
289
-
290
- if (spec.cols[i].label) {
291
- s.push(h('span', spec.cols[i].label));
292
- } else {
293
- s.push(h('span', spec.cols[i].name));
294
- }
295
-
296
- if (spec.sort && spec.sort.length > 0 && spec.sort[0].index == i) {
297
- if (spec.sort[0].dir == 'desc')
298
- s.push(h('span', { style: { float: 'right' } }, '⯆'))
299
- else
300
- s.push(h('span', { style: { float: 'right' } }, '⯅'))
301
- }
302
-
303
- const a = h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: { display: 'block', 'font-weight': 500, 'text-decoration': 'none', color: 'black' } }, s);
304
-
305
- th.push(h('th', { style: { width: spec.cols[i].width ? spec.cols[i].width : 'auto', 'max-width': spec.cols[i].width ? spec.cols[i].width : 'auto' } }, [a]));
306
- }
307
-
308
- const tr = h('tr', {}, th);
309
-
310
- return [tr];
311
- }
312
-
313
- function renderBody() {
314
- const dr = [];
315
-
316
- if (rows && rows.length > 0) {
317
- for (let i = 0; i < rows.length; i += 1) {
318
- dr.push(renderRow(i, rows[i]));
319
- }
320
- }
321
-
322
- return dr;
323
- }
324
-
325
- function renderFooter() {
326
- const fr = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: first, disabled: spec.currPage == 1 }, '\u2bc5');
327
- const ls = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: last, disabled: spec.pageCount > 0 }, '\u2bc6');
328
- const pg = h('button', { class: props.buttonclass, style: 'margin-right: .5rem' }, spec.currPage);
329
- const pr = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: prior, disabled: spec.currPage == 1 }, '\u2bc7');
330
- const nx = h('button', { class: props.buttonclass, style: 'margin-right: .5rem', onClick: next }, '\u2bc8');
331
- const td = h('td', { colspan: spec.cols.length, align: 'center' }, [fr, pr, pg, nx, ls]);
332
- const tr = h('tr', {}, [td]);
333
-
334
- return [tr];
335
- }
336
- /*****************************************************************
337
- Columns
338
- *****************************************************************/
339
- let cls = [];
340
-
341
- if (props.data.columns) {
342
- cls = props.data.columns;
343
- } else {
344
- alert('not ready !')
345
- //cls = slots.default().map(m => m.props);
346
- }
347
-
348
- for (let i = 0; i < cls.length; i += 1) {
349
- let s = cls[i];
350
-
351
- if (s.name.indexOf('.') > -1) {
352
- s.depth = s.name.split('.');
353
- }
354
-
355
- spec.cols.push(s);
356
- }
357
-
358
- page(1);
359
-
360
- return {
361
- spec, rows,
362
- first, prior, next, last, refresh, orderby,
363
- renderHeader, renderCell, renderCustomCell, renderRow, renderBody, renderFooter
364
- };
365
- },
366
-
367
- render(props) {
368
- const header = h('thead', {}, this.renderHeader());
369
- const body = h('tbody', { 'data-time': this.spec.time}, this.renderBody());
370
- const footer = h('tfoot', {}, this.renderFooter());
371
-
372
- return h('table', {
373
- class: props.class,
374
- }, [
375
- header,
376
- body,
377
- footer
378
- ]);
379
- }
380
- };
381
-
382
- export default tablevu;
1
+ /*
2
+ * tablevu
3
+ * A small, fast, easy-to-use table component.
4
+ * Copyright (c) 2020 Ender Boz <ender.boz@gmail.com>
5
+ * https://github.com/endb/tablevu/LICENCE
6
+ */
7
+
8
+ import { h, onMounted, reactive, ref, watch } from 'vue';
9
+ import adaptarr from './array.js';
10
+
11
+ const tablevuStatuses = { Error: -1, Ready: 0, Loading: 1 };
12
+
13
+ const tablevu = {
14
+ props: {
15
+ settings: { type: Object, default: null },
16
+ data: { type: [Array, Function] },
17
+ //group: { type: Object, default: { value: null, expandAll: true, class: 'table-light' } },
18
+ search: { type: String },
19
+ filter: { type: [Array, Object] },
20
+ command: { type: Array, default: [] },
21
+ rowid: { type: String },
22
+ onRowClick: { type: Function },
23
+ onRowDblClick: { type: Function },
24
+ class: { type: String, default: 'table' },
25
+ style: { type: String, default: null },
26
+ buttonClass: { type: String, default: 'btn' }
27
+ },
28
+
29
+ emits: ['onRowClick', 'onRowDblClick'],
30
+
31
+ setup(props, { attrs, slots, emit, expose }) {
32
+ let grps = [];
33
+ let rows = [];
34
+ let count = 0;
35
+
36
+ const spec = reactive({
37
+ adapter: null,
38
+ group: {
39
+ value: (props.settings && props.settings.group) ? props.settings.group.value : props.group ? props.group: null, // string ise alan adı, int ise index, fonksiyon ise calistirip alacak.
40
+ content: (props.settings && props.settings.group) ? props.settings.group.content : null, // grid de ne gosterilecek
41
+ expandAll: true,
42
+ class: 'table-light'
43
+ },
44
+ page: {
45
+ count: 0,
46
+ size: (props.settings && props.settings.page) ? props.settings.page.size : 0,
47
+ current: 0,
48
+ type: null // incrementral, dynamic
49
+ },
50
+ footer: {
51
+ button: {
52
+ first: { visible: true, content: null },
53
+ prior: { visible: true, content: null },
54
+ next: { visible: true, content: null },
55
+ last: { visible: true, content: null },
56
+ page: { visible: true, content: null },
57
+ size: { visible: true, content: null },
58
+ class: 'btn'
59
+ }
60
+ },
61
+ sort: (props.settings && props.settings.sort) ? props.settings.sort : [],
62
+ columns: (props.settings && props.settings.columns) ? props.settings.columns : [],
63
+ onRowClick: props.settings.onRowClick || props.onRowClick,
64
+ onRowDblClick: props.settings.onRowDblClick || props.onRowDblClick,
65
+ });
66
+
67
+ if (props.data) {
68
+ if (Array.isArray(props.data)) {
69
+ spec.adapter = adaptarr;
70
+ }
71
+ else {
72
+ spec.adapter = props.data;
73
+ }
74
+ };
75
+
76
+ // Setup dynamic filter //
77
+ if (props.filter)
78
+ spec.filter = props.filter;
79
+
80
+ watch(() => props.filter, (n, o) => {
81
+ if (n)
82
+ spec.filter = n;
83
+ else
84
+ spec.filter = null;
85
+
86
+ refresh();
87
+ }, { deep: true });
88
+
89
+ // Setup Search Input //
90
+ watch(() => props.search, (n,o) => {
91
+ if (spec.timer)
92
+ clearTimeout(spec.timer);
93
+
94
+ if ((o && o.length > (props.data.searchMinChar || 3) && (n == undefined || n == null || n.length <= (props.data.searchMinChar || 3))) || (n && n.length > (props.data.searchMinChar || 3))) {
95
+ spec.timer = setTimeout(() => { if (props.search && props.search.length > (props.data.searchMinChar || 3)) spec.search = props.search; else spec.search = null; refresh(); }, 444);
96
+ }
97
+ });
98
+
99
+ // Setup commands //
100
+ watch(() => props.command, (n,o) => {
101
+ if (n && n.length > 0) {
102
+ const c = props.command[n.length-1];
103
+
104
+ if (c && c.name) {
105
+ if (c.name.toLowerCase() == 'refresh') refresh()
106
+ else if (c.name.toLowerCase() == 'first') first()
107
+ else if (c.name.toLowerCase() == 'prior') prior()
108
+ else if (c.name.toLowerCase() == 'next') next()
109
+ else if (c.name.toLowerCase() == 'last') last()
110
+ else console.log('Unknown command');
111
+ }
112
+
113
+ props.command.length = 0;
114
+ }
115
+ }, { deep: true });
116
+
117
+ function prepareGroup(g, r) {
118
+ let s = [];
119
+
120
+ for (let i = 0; i < r.length; i++) {
121
+ let v = null;
122
+ let c = null;
123
+
124
+ const o = r[i];
125
+
126
+ if (g.value) {
127
+ if (typeof g.value == 'function')
128
+ v = g.value(o);
129
+ else
130
+ v = o[g.value];
131
+ } else
132
+ if (typeof g == 'function')
133
+ v = g(o);
134
+ else {
135
+ if (typeof g == 'bigint' || typeof g == 'number') {
136
+ const l = parseInt(g);
137
+
138
+ if (l)
139
+ v = o[l];
140
+ } else
141
+ if (typeof g == 'string')
142
+ v = o[g];
143
+ }
144
+
145
+ if (g.content) {
146
+ if (typeof g.content == 'function')
147
+ c = g.content(o);
148
+ else
149
+ c = o[g.content];
150
+ };
151
+
152
+ const n = s.findIndex(f => f.group == v);
153
+
154
+ if (n > -1)
155
+ s[n].rows.push(o);
156
+ else
157
+ s.push({ group: v, content: c, expand: spec.group.expandAll, rows: [o] });
158
+ };
159
+
160
+ return s;
161
+ }
162
+ /*****************************************************************
163
+
164
+ *****************************************************************/
165
+ function first() { // Go First Page //
166
+ page(1);
167
+ }
168
+
169
+ function prior() { // Go Previus Page //
170
+ if (spec.page.current > 1) {
171
+ page(spec.page.current - 1);
172
+ } else {
173
+ page(spec.page.current);
174
+ }
175
+ }
176
+
177
+ function next() { // Go Next Page //
178
+ page(spec.page.current + 1);
179
+ }
180
+
181
+ function last() { // Go Last Page //
182
+ page(spec.page.count);
183
+ }
184
+
185
+ function refresh() { // Refresh active page //
186
+ page(spec.page.current);
187
+ }
188
+
189
+ function orderby(ind, dir) { // Sort data //
190
+ if (spec.sort && spec.sort.length > 0) {
191
+ let l = spec.sort.findIndex(f => f.index == ind);
192
+
193
+ if (l == 0) {
194
+ spec.sort[l].dir = dir ? dir: (spec.sort[0].dir ? null : 'desc');
195
+ } else if (l > 0) {
196
+ spec.sort.splice(l, 1);
197
+ }
198
+
199
+ if (l != 0) {
200
+ spec.sort.unshift({ index: ind, dir: dir ? dir: null });
201
+ }
202
+
203
+ if (spec.sort.length > 2) {
204
+ spec.sort.pop();
205
+ }
206
+ } else {
207
+ spec.sort.push({ index: ind, dir: dir ? dir: null });
208
+ }
209
+
210
+ page(spec.page.current);
211
+ }
212
+
213
+ function page(currentPage) { // Go Custom Page number //
214
+ let dat = null;
215
+
216
+ if (props.data) {
217
+ if (Array.isArray(props.data))
218
+ dat = props.data;
219
+ } else
220
+ return;
221
+
222
+ spec.status = tablevuStatuses.Loading;
223
+
224
+ if (spec.adapter) {
225
+ spec.adapter({ pageSize: spec.page.size, currPage: currentPage, sort: spec.sort, cols: spec.columns, filter: spec.filter, search: spec.search }, dat).then(ada => {
226
+
227
+ if (spec.onData)
228
+ rows = spec.onData(ada.rows);
229
+ else
230
+ rows = ada.rows;
231
+
232
+ count = ada.count;
233
+
234
+ if (spec.group)
235
+ grps = prepareGroup(spec.group, rows);
236
+
237
+ spec.page.count = (ada.count > 0 && spec.page.size > 0) ? (ada.count / spec.page.size) : 0
238
+ spec.page.current = currentPage;
239
+
240
+ spec.status = tablevuStatuses.Ready;
241
+ spec.time = Date.now();
242
+ });
243
+ }
244
+ }
245
+ /*****************************************************************
246
+ Render Functions
247
+ *****************************************************************/
248
+ function renderValue(col, val) {
249
+ if (val) {
250
+ let v;
251
+
252
+ if (col.type == 'datetime' || col.type == 'date' || col.type == 'time') {
253
+ let t = new Date(val);
254
+
255
+ if (col.type == 'date')
256
+ v = t.toLocaleDateString();
257
+ else
258
+ if (col.type == 'time')
259
+ v = t.toLocaleTimeString();
260
+ else
261
+ v = t.toLocaleString();
262
+ } else {
263
+ if (col.type == 'numeric') {
264
+ v = parseFloat(val);
265
+ } else {
266
+ if (col.type == 'integer') {
267
+ v = parseInt(val);
268
+ } else
269
+ v = val;
270
+ }
271
+ };
272
+
273
+ return v;
274
+ } else
275
+ return '';
276
+ }
277
+
278
+ function renderCell(col, val) {
279
+ const o = { style: {} };
280
+
281
+ if (col.colspan && col.colspan > 1) {
282
+ o.colspan = col.colspan;
283
+ }
284
+
285
+ if (col.align) {
286
+ o.style['text-align'] = col.align;
287
+ }
288
+
289
+ if (col.width) {
290
+ o.style['max-width'] = col.width;
291
+ }
292
+
293
+ if (col.color) {
294
+ o.style['color'] = col.color;
295
+ }
296
+
297
+ if (col.backgroundColor) {
298
+ o.style['background-color'] = col.backgroundColor;
299
+ }
300
+
301
+ const v = renderValue(col, val);
302
+
303
+ return h('td', o, v);
304
+ }
305
+
306
+ function renderCustomCell(col, row) {
307
+ const o = { style: {} };
308
+
309
+ if (col.colspan && col.colspan > 1) {
310
+ o.colspan = col.colspan;
311
+ }
312
+
313
+ if (col.align) {
314
+ o.style['text-align'] = col.align;
315
+ }
316
+
317
+ if (col.width) {
318
+ o.style['max-width'] = col.width;
319
+ }
320
+
321
+ let f = col.render(row);
322
+
323
+ return h('td', o, f);
324
+ }
325
+
326
+ function renderGroup(grp) {
327
+ const b = h('button', { title: grp.expand, onClick: event => { console.log(grp.expand); grp.expand = (grp.expand ? false: true); event.currentTarget.value = grp.expand ? '▼': '►'; spec.time = Date.now(); event.preventDefault() }, style: { padding: 0, margin: '0 6px 0 0', width: '12px', height: '100%', border: 'none', outline: 0, backgroundColor: 'transparent' } }, grp.expand ? '▼': '►');
328
+ const v = grp.content || grp.group;
329
+
330
+
331
+ return h('tr', {}, h('td', { colspan: spec.columns.length, class: spec.group.class }, [b, v]));
332
+ }
333
+
334
+ function renderRow(index, row) {
335
+ const o = {};
336
+ const r = [];
337
+
338
+ o.key = index;
339
+ o.index = index;
340
+
341
+ if (props.rowid) {
342
+ o.rowid = row[props.rowid];
343
+ }
344
+
345
+ for (let i = 0; i < spec.columns.length; i += 1) {
346
+ let v;
347
+ const c = spec.columns[i];
348
+
349
+ if (c.render) {
350
+ v = renderCustomCell(c, row);
351
+ r.push(v);
352
+ } else {
353
+ if (c.depth) {
354
+ v = row;
355
+ for (let j = 0; j < c.depth.length; j += 1) {
356
+ if (v)
357
+ v = v[c.depth[j]];
358
+ }
359
+ } else {
360
+ v = row[c.name];
361
+ }
362
+
363
+ r.push(renderCell(c, v));
364
+ }
365
+ }
366
+
367
+ //if (spec.onRowDblClick)
368
+ o.ondblclick = (event) => {
369
+ const r = rows[event.currentTarget.attributes.index.value];
370
+ emit('onRowDblClick', event, r);
371
+ //props.onRowDblClick(event, r);
372
+ };
373
+
374
+ if (props.onRowClick) {
375
+ o.onClick = (event) => {
376
+ const r = rows[event.currentTarget.attributes.index.value];
377
+ props.onRowClick(event, r);
378
+ };
379
+ }
380
+
381
+ return h('tr', o, r);
382
+ }
383
+
384
+ function renderHeader() {
385
+ let ar = [];
386
+ let sp = 1;
387
+
388
+ for (let i = 0; i < spec.columns.length; i += 1) {
389
+ if (sp > 1) {
390
+ sp--;
391
+ continue;
392
+ };
393
+
394
+ const cl = [];
395
+
396
+ if (spec.columns[i].label) {
397
+ cl.push(h('span', spec.columns[i].label));
398
+ } else {
399
+ cl.push(h('span', spec.columns[i].name));
400
+ }
401
+
402
+ if (spec.sort && spec.sort.length > 0 && spec.sort[0].index == i) {
403
+ if (spec.sort[0].dir == 'desc')
404
+ cl.push(h('span', { style: { float: 'right' } }, '▼'))
405
+ else
406
+ cl.push(h('span', { style: { float: 'right' } }, '▲'))
407
+ }
408
+
409
+ let ch = { position: 'relative' };
410
+
411
+ if (spec.columns[i].width) {
412
+ ch.width = spec.columns[i].width;
413
+ ch.minWidth = spec.columns[i].width;
414
+ ch.maxWidth = spec.columns[i].width;
415
+ }
416
+
417
+ let cy = { display: 'block', 'font-weight': 500, textDecoration: 'none', color: 'black', textAlign: 'center' };
418
+
419
+ if (spec.columns[i].header) {
420
+ if (spec.columns[i].header.colspan)
421
+ sp = parseInt(spec.columns[i].header.colspan) || 1;
422
+
423
+ if (spec.columns[i].header.align)
424
+ cy.textAlign = spec.columns[i].header.align;
425
+
426
+ if (spec.columns[i].header.backgroundColor)
427
+ ch.backgroundColor = spec.columns[i].header.backgroundColor;
428
+
429
+ if (spec.columns[i].header.color)
430
+ cy.color = spec.columns[i].header.color;
431
+ }
432
+
433
+ let a;
434
+ let f;
435
+
436
+ if (spec.columns[i].popup) {
437
+ const r = ref(null);
438
+ let c = [
439
+ h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: { display: 'block', textDecoration: 'none', color: 'black', fontWeight: 'initial', padding: '.25rem' } }, 'Order by Ascending'),
440
+ h('a', { href: '#', onClick(event) { orderby(i, 'desc'); event.preventDefault(); }, style: { display: 'block', textDecoration: 'none', color: 'black', fontWeight: 'initial', padding: '.25rem' } }, 'Order by Descending'),
441
+ ];
442
+
443
+ a = h('a', { href: '#', onClick(event) { if (r.value && r.value.style && r.value.style.display && r.value.style.display == 'block') r.value.style.display = 'none'; else r.value.style.display = 'block'; event.preventDefault(); }, style: cy }, cl);
444
+ f = h('div', { ref: r, style: { position: 'absolute', display: 'none', width: spec.columns[i].width || '12rem', height: 'fit-content', border: '1px solid lightgray', backgroundColor: 'whitesmoke', zIndex: 1, left: 0, top: '2rem', bottom: 0, right: 0, padding: '.25rem' }}, c);
445
+
446
+ } else
447
+ a = h('a', { href: '#', onClick(event) { orderby(i); event.preventDefault(); }, style: cy }, cl);
448
+
449
+ if (spec.columns[i].filter) {
450
+ }
451
+
452
+ ar.push(h('th', { colspan: sp > 1 ? sp: null, style: ch }, [a, f]));
453
+ }
454
+
455
+ const tr = h('tr', {}, ar);
456
+
457
+ return [tr];
458
+ }
459
+
460
+ function renderBody() {
461
+ const dr = [];
462
+
463
+ if (grps && grps.length > 0) {
464
+ let x = 0;
465
+
466
+ for (let g = 0; g < grps.length; g += 1) {
467
+ const r = grps[g];
468
+
469
+ dr.push(renderGroup(r));
470
+
471
+ if (r.expand && r.rows && r.rows.length > 0) {
472
+ for (let i = 0; i < r.rows.length; i += 1) {
473
+ dr.push(renderRow(x, r.rows[i]));
474
+ x++;
475
+ }
476
+ }
477
+ }
478
+ } else
479
+ if (rows && rows.length > 0) {
480
+ for (let i = 0; i < rows.length; i += 1) {
481
+ dr.push(renderRow(i, rows[i]));
482
+ }
483
+ }
484
+
485
+ return dr;
486
+ }
487
+
488
+ function renderFooter() {
489
+ const fr = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: first, disabled: spec.page.current == 1 }, '◀◀');
490
+ const ls = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: last, disabled: spec.page.count > 0 }, '▶▶');
491
+ const pg = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem' }, spec.page.current);
492
+ const pr = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: prior, disabled: spec.page.current == 1 }, '◀');
493
+ const nx = h('button', { class: spec.footer.button.class, style: 'margin-right: .5rem', onClick: next, disabled: spec.page.count > 0 && spec.page.current == spec.page.count }, '▶');
494
+ const td = h('td', { colspan: spec.columns.length, align: 'center' }, [fr, pr, pg, nx, ls]);
495
+ const tr = h('tr', {}, [td]);
496
+
497
+ return [tr];
498
+ }
499
+
500
+ function renderCaption() {
501
+ return null; // NOT REMEMBER !!!
502
+ // caption-side
503
+ // text-align
504
+ }
505
+ /*****************************************************************
506
+ Columns
507
+ *****************************************************************/
508
+ if (spec.columns.length == 0) {
509
+ alert('Columns not defined !')
510
+ //cls = slots.default().map(m => m.props);
511
+ }
512
+
513
+ for (let i = 0; i < spec.columns.length; i++)
514
+ if (spec.columns[i].name && spec.columns[i].name.indexOf('.') > -1) {
515
+ spec.columns[i].depth = spec.columns[i].name.split('.');
516
+ }
517
+
518
+ page(1);
519
+
520
+ onMounted(() => {
521
+ console.log('tablevu.mounted');
522
+ });
523
+
524
+ return {
525
+ spec, renderHeader, renderBody, renderFooter, renderCaption
526
+ };
527
+
528
+
529
+ },
530
+
531
+ render(props) {
532
+ console.log('tablevu.render', this.spec.status);
533
+ let prps = { class: 'tablevu' };
534
+ /*
535
+ if (props.id)
536
+ prps.id = props.id;
537
+ */
538
+ if (props.class)
539
+ prps.class = 'tablevu ' + props.class;
540
+
541
+ if (props.style)
542
+ prps.style = props.style;
543
+
544
+ /* if (props.dir)
545
+ prps.dir = props.dir;
546
+
547
+ if (props.hidden)
548
+ prps.hidden = props.hidden;
549
+
550
+
551
+ if (props.title)
552
+ prps.title = props.title;
553
+ */
554
+ // Content //
555
+ let cntn = [];
556
+
557
+ cntn.push(
558
+ h('thead', {}, this.renderHeader())
559
+ );
560
+
561
+ if (this.spec.status == tablevuStatuses.Ready)
562
+ cntn.push(
563
+ h('tbody', { 'data-time': this.spec.time}, this.renderBody())
564
+ );
565
+
566
+ if (this.spec.caption)
567
+ cntn.push(
568
+ h('caption', {}, this.renderCaption())
569
+ );
570
+
571
+ if (this.spec.page.size > 0)
572
+ cntn.push(
573
+ h('tfoot', {}, this.renderFooter())
574
+ );
575
+
576
+ return h('table', prps, cntn);
577
+ }
578
+ };
579
+
580
+ export default tablevu;