mdkcontroller 1.2.1 → 1.2.2
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/Cores/file/DKGrid.js +87 -42
- package/package.json +1 -1
- package/readme.md +1 -1
package/Cores/file/DKGrid.js
CHANGED
|
@@ -22,7 +22,7 @@ class DKGrid {
|
|
|
22
22
|
addEventListener(eventName, callback) {
|
|
23
23
|
this.#event[eventName] = this.#event[eventName] || [];
|
|
24
24
|
this.#event[eventName].push(callback);
|
|
25
|
-
//rowClick, openEditor, commitData,
|
|
25
|
+
//rowClick, openEditor, commitData, onAddNewRow, onOpenEditor, onSelectorSelecting
|
|
26
26
|
}
|
|
27
27
|
fireEvent(eventName, callback, ...args) {
|
|
28
28
|
const callbacks = this.#event[eventName] || [];
|
|
@@ -48,7 +48,6 @@ class DKGrid {
|
|
|
48
48
|
console.error(`Không tìm thấy phần tử có ID: ${this.boxId}`);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
|
|
52
51
|
if (!this.config.primaryKey) {
|
|
53
52
|
this.config.primaryKey = this.config.column[0]?.fieldName || '';
|
|
54
53
|
}
|
|
@@ -69,22 +68,22 @@ class DKGrid {
|
|
|
69
68
|
totalWidth += width;
|
|
70
69
|
return `<col style="width: ${width}px;">`;
|
|
71
70
|
}).join("");
|
|
72
|
-
|
|
71
|
+
this.editorDefault = '<tr>' + this.config.column.map(f => {
|
|
73
72
|
switch (f.dataType) {
|
|
74
73
|
case "string": return `<td><input type='text'name='${f.fieldName}'/></td>`;
|
|
75
74
|
case "bool": return `<td><input type="checkbox" name='${f.fieldName}'></td>`;
|
|
76
75
|
case "date": return `<td><input type="date" name='${f.fieldName}'></td>`;
|
|
77
76
|
case "number": return `<td><input type="number" name='${f.fieldName}'></td>`;
|
|
78
77
|
case "select":
|
|
79
|
-
let
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
78
|
+
let itemSelector = f.items;
|
|
79
|
+
this.fireEvent('onSelectorSelecting', (rs) => {
|
|
80
|
+
itemSelector = rs || itemSelector;
|
|
81
|
+
}, f.fieldName, null);
|
|
82
|
+
let items = itemSelector.map(i => `<option value="${i.value}">${i.text}</option>`).join("");
|
|
84
83
|
return `<td><select name='${f.fieldName}'>${items}</select></td>`;
|
|
85
84
|
default: return `<td><input type='text' name='${f.fieldName}'/></td>`;
|
|
86
85
|
}
|
|
87
|
-
}).join("\r\n");
|
|
86
|
+
}).join("\r\n") + '</tr>';
|
|
88
87
|
return `
|
|
89
88
|
<div style='height: 100%;width: 100%; overflow: hidden;'>
|
|
90
89
|
<table id='${this.id}' class='dk-table' style='height: 100%;'>
|
|
@@ -96,7 +95,7 @@ class DKGrid {
|
|
|
96
95
|
<li data-cmd='del'><i class="fa fa-times" aria-hidden="true"></i></li>
|
|
97
96
|
<li data-cmd='cancel'><i class="fa fa-recycle" aria-hidden="true"></i></li>
|
|
98
97
|
<li data-cmd='save'><i class="fa fa-cloud-upload" aria-hidden="true"></i></li>
|
|
99
|
-
<li data-cmd='refresh'><input id='${this.id}_inputSearch' type='search' style='width:
|
|
98
|
+
<li data-cmd='refresh'><input id='${this.id}_inputSearch' type='search' style='width:250px;'></li>
|
|
100
99
|
</ul>
|
|
101
100
|
</div>
|
|
102
101
|
</td>
|
|
@@ -113,14 +112,14 @@ class DKGrid {
|
|
|
113
112
|
</tr>
|
|
114
113
|
<tr>
|
|
115
114
|
<td class='gridBodyCell'>
|
|
116
|
-
<div id='${this.id}_bodyContent' style='position: relative; height: 100%; overflow: scroll;'>
|
|
115
|
+
<div id='${this.id}_bodyContent' style='min-height: 100px; position: relative; height: 100%; overflow: scroll;'>
|
|
117
116
|
<table id='${this.idRaw}' class='edit' cellpadding="0" cellspacing="0" border="0" style="table-layout: fixed;width: ${totalWidth}px;">
|
|
118
117
|
<colgroup>${colWidths}</colgroup>
|
|
119
118
|
<tbody></tbody>
|
|
120
119
|
</table>
|
|
121
120
|
<table id='${this.idEditor}' class='edit RowNavigator' cellpadding="0" cellspacing="0" border="0" style="table-layout: fixed;width: ${totalWidth}px;position: absolute;left: 0px;top: 40px; display: none;">
|
|
122
121
|
<colgroup>${colWidths}</colgroup>
|
|
123
|
-
<tbody
|
|
122
|
+
<tbody>${this.editorDefault}</tbody>
|
|
124
123
|
</table>
|
|
125
124
|
</div>
|
|
126
125
|
</td>
|
|
@@ -130,12 +129,8 @@ class DKGrid {
|
|
|
130
129
|
<div style='display: flex; align-items: center;'>
|
|
131
130
|
<ul id='${this.id}_gridPagingCell' style='display: flex; list-style-type: none; margin: 5px; padding: 2px 32px;'>
|
|
132
131
|
<li data-cmd='1'>1</li>
|
|
133
|
-
<li data-cmd='2'>2</li>
|
|
134
|
-
<li data-cmd='3'>3</li>
|
|
135
|
-
<li data-cmd='4'>4</li>
|
|
136
|
-
<li data-cmd='5'>5</li>
|
|
137
132
|
</ul>
|
|
138
|
-
<span id='${this.id}_status' style='font-size:18px;'>
|
|
133
|
+
<span id='${this.id}_status' style='font-size:18px;'>0/10</span>
|
|
139
134
|
</div>
|
|
140
135
|
</td>
|
|
141
136
|
</tr>
|
|
@@ -178,7 +173,7 @@ class DKGrid {
|
|
|
178
173
|
const page = parseInt(cmd);
|
|
179
174
|
if (page) {
|
|
180
175
|
this.page.current = Math.min(page, this.page.total);
|
|
181
|
-
this.
|
|
176
|
+
this.buildNav_List();
|
|
182
177
|
}
|
|
183
178
|
});
|
|
184
179
|
document.getElementById(dkgrid.id + "_bodyContent").addEventListener("scroll", function () {
|
|
@@ -188,7 +183,7 @@ class DKGrid {
|
|
|
188
183
|
document.getElementById(dkgrid.id + "_inputSearch").addEventListener("keydown", function (event) {
|
|
189
184
|
if (event.key === "Enter") {
|
|
190
185
|
event.preventDefault();
|
|
191
|
-
dkgrid.
|
|
186
|
+
dkgrid.buildNav_List();
|
|
192
187
|
}
|
|
193
188
|
});
|
|
194
189
|
}
|
|
@@ -196,15 +191,13 @@ class DKGrid {
|
|
|
196
191
|
// ESC
|
|
197
192
|
if (keyCode == 27) {
|
|
198
193
|
if (this.rowOnFocus) {
|
|
199
|
-
|
|
200
|
-
this.#closeEditor(lastRow, true);
|
|
194
|
+
this.#closeEditor(true);
|
|
201
195
|
}
|
|
202
196
|
}
|
|
203
197
|
// ENTER
|
|
204
198
|
if (keyCode == 13) {
|
|
205
199
|
if (this.rowOnFocus) {
|
|
206
|
-
|
|
207
|
-
this.#closeEditor(lastRow, false);
|
|
200
|
+
this.#closeEditor(false);
|
|
208
201
|
}
|
|
209
202
|
}
|
|
210
203
|
}
|
|
@@ -214,7 +207,7 @@ class DKGrid {
|
|
|
214
207
|
if (this.rowOnFocus) {
|
|
215
208
|
const lastRow = this.rowOnFocus;
|
|
216
209
|
if (lastRow.dataset.editting == "1") {
|
|
217
|
-
this.#closeEditor(
|
|
210
|
+
this.#closeEditor(false);
|
|
218
211
|
}
|
|
219
212
|
}
|
|
220
213
|
this.rowOnFocus = trTag;
|
|
@@ -242,7 +235,7 @@ class DKGrid {
|
|
|
242
235
|
let objectCurrent = cache.updated[currentKeyValue] || cache.origin[currentKeyValue];
|
|
243
236
|
{
|
|
244
237
|
let throwX = false;
|
|
245
|
-
this.fireEvent('
|
|
238
|
+
this.fireEvent('onOpenEditor', (rs) => {
|
|
246
239
|
throwX = rs === false;
|
|
247
240
|
return !throwX;
|
|
248
241
|
}, objectCurrent, this);
|
|
@@ -254,10 +247,21 @@ class DKGrid {
|
|
|
254
247
|
const input = child.firstChild;
|
|
255
248
|
try {
|
|
256
249
|
if (input.tagName == "INPUT" || input.tagName == "SELECT") {
|
|
250
|
+
if (input.tagName == "SELECT") {
|
|
251
|
+
let itemSelector = tableConfig.column.find(f => f.fieldName == input.name).items;
|
|
252
|
+
this.fireEvent('onSelectorSelecting', (rs) => {
|
|
253
|
+
itemSelector = rs || itemSelector;
|
|
254
|
+
}, input.name, objectCurrent);
|
|
255
|
+
let items = itemSelector.map(i => `<option value="${i.value}">${i.text}</option>`).join("");
|
|
256
|
+
input.innerHTML = items;
|
|
257
|
+
}
|
|
258
|
+
|
|
257
259
|
input.value = objectCurrent[input.name] || "";
|
|
258
260
|
if (input.type == 'checkbox') {
|
|
259
261
|
input.checked = objectCurrent[input.name] || false;
|
|
260
262
|
}
|
|
263
|
+
|
|
264
|
+
this.fireEvent('onSetInput', null, input, objectCurrent);
|
|
261
265
|
}
|
|
262
266
|
} catch (exx) {
|
|
263
267
|
console.log("Error in openEditor: ", exx);
|
|
@@ -269,16 +273,17 @@ class DKGrid {
|
|
|
269
273
|
trTag.dataset.editting = '1';
|
|
270
274
|
return true;
|
|
271
275
|
}
|
|
272
|
-
#closeEditor(
|
|
273
|
-
const
|
|
276
|
+
#closeEditor(isClear = false, isdelete = false) {
|
|
277
|
+
const trTag = this.rowOnFocus;
|
|
278
|
+
if (trTag == null) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
274
281
|
const tbEditor = this.tableEditor;
|
|
275
282
|
if (!isdelete) {
|
|
276
|
-
const tableConfig = this.config;
|
|
277
|
-
const primaryKey = tableConfig.primaryKey;
|
|
278
283
|
const currentKeyValue = trTag.dataset.primaryValue;
|
|
279
284
|
const cache = this.#cache;
|
|
280
285
|
|
|
281
|
-
let objectCurrent = cache.updated[currentKeyValue] || {...cache.origin[currentKeyValue]};
|
|
286
|
+
let objectCurrent = cache.updated[currentKeyValue] || { ...cache.origin[currentKeyValue] };
|
|
282
287
|
let objectEditing = {};
|
|
283
288
|
let hasChange = false;
|
|
284
289
|
tbEditor.querySelector('tbody').querySelectorAll('td').forEachExt(
|
|
@@ -333,7 +338,11 @@ class DKGrid {
|
|
|
333
338
|
case "date": td.textContent = item[f.fieldName] || ''; break;
|
|
334
339
|
case "number": td.textContent = item[f.fieldName] || ''; break;
|
|
335
340
|
case "select":
|
|
336
|
-
|
|
341
|
+
let itemSelector = f.items;
|
|
342
|
+
this.fireEvent('onSelectorSelecting', (rs) => {
|
|
343
|
+
itemSelector = rs || itemSelector;
|
|
344
|
+
}, f.fieldName, null);
|
|
345
|
+
td.textContent = itemSelector.find(i => i.value == item[f.fieldName])?.text;
|
|
337
346
|
break;
|
|
338
347
|
default: td.textContent = item[f.fieldName]; break;
|
|
339
348
|
}
|
|
@@ -351,9 +360,9 @@ class DKGrid {
|
|
|
351
360
|
cache.deleted = {};
|
|
352
361
|
this.page.total = Math.ceil(data.length / this.page.size);
|
|
353
362
|
}
|
|
354
|
-
this.
|
|
363
|
+
this.buildNav_List();
|
|
355
364
|
}
|
|
356
|
-
|
|
365
|
+
buildNav_List(holdPage = false) {
|
|
357
366
|
const cache = this.#cache;
|
|
358
367
|
|
|
359
368
|
const dataCollection = {};
|
|
@@ -365,8 +374,8 @@ class DKGrid {
|
|
|
365
374
|
});
|
|
366
375
|
Object.keys(cache.deleted).forEach(key => {
|
|
367
376
|
delete dataCollection[key];
|
|
368
|
-
});
|
|
369
|
-
|
|
377
|
+
});
|
|
378
|
+
this.#closeEditor(false, false);
|
|
370
379
|
const dataCollection_array = [];
|
|
371
380
|
const textSearch = document.getElementById(this.id + "_inputSearch").value;
|
|
372
381
|
Object.values(dataCollection).forEach(item => {
|
|
@@ -401,7 +410,9 @@ class DKGrid {
|
|
|
401
410
|
for (let index = min; index <= max; index++) {
|
|
402
411
|
this.pagingCell.appendChild(hideCreatePageLi(index));
|
|
403
412
|
}
|
|
404
|
-
|
|
413
|
+
if (page.total > 1) {
|
|
414
|
+
this.pagingCell.appendChild(hideCreatePageLi(page.total, "font-weight: bold; margin-left: 15px;"));
|
|
415
|
+
}
|
|
405
416
|
function hideCreatePageLi(num, style = '') {
|
|
406
417
|
const li = document.createElement('li');
|
|
407
418
|
li.dataset.cmd = num;
|
|
@@ -415,6 +426,9 @@ class DKGrid {
|
|
|
415
426
|
}
|
|
416
427
|
const dataPrint = dataCollection_array.slice(start, end);
|
|
417
428
|
this.statusBox.textContent = `${dataPrint.length}/${dataCollection_array.length}`;
|
|
429
|
+
if (holdPage) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
418
432
|
this.printPage(dataPrint);
|
|
419
433
|
}
|
|
420
434
|
printPage(dataPrint = []) {
|
|
@@ -437,7 +451,11 @@ class DKGrid {
|
|
|
437
451
|
case "date": td.textContent = item[f.fieldName] || ''; break;
|
|
438
452
|
case "number": td.textContent = item[f.fieldName] || ''; break;
|
|
439
453
|
case "select":
|
|
440
|
-
|
|
454
|
+
let itemSelector = f.items;
|
|
455
|
+
this.fireEvent('onSelectorSelecting', (rs) => {
|
|
456
|
+
itemSelector = rs || itemSelector;
|
|
457
|
+
}, f.fieldName, null);
|
|
458
|
+
td.textContent = itemSelector.find(i => i.value == item[f.fieldName])?.text || '';
|
|
441
459
|
break;
|
|
442
460
|
default: td.textContent = item[f.fieldName]; break;
|
|
443
461
|
}
|
|
@@ -455,9 +473,7 @@ class DKGrid {
|
|
|
455
473
|
const primaryKey = tableConfig.primaryKey;
|
|
456
474
|
let newOb = {};
|
|
457
475
|
{
|
|
458
|
-
this.fireEvent('
|
|
459
|
-
newOb[primaryKey] = rs;
|
|
460
|
-
});
|
|
476
|
+
this.fireEvent('onAddNewRow', null, newOb);
|
|
461
477
|
}
|
|
462
478
|
if (!newOb[primaryKey]) {
|
|
463
479
|
newOb[primaryKey] = DKGrid.generateRandomString(32);
|
|
@@ -465,13 +481,15 @@ class DKGrid {
|
|
|
465
481
|
newTR.dataset.primaryValue = newOb[primaryKey];
|
|
466
482
|
const cache = this.#cache;
|
|
467
483
|
cache.updated[newOb[primaryKey]] = (newOb);
|
|
484
|
+
this.buildNav_List(true);
|
|
468
485
|
this.#createRow(newTR, newOb);
|
|
486
|
+
newTR.querySelector('td').click();
|
|
469
487
|
}
|
|
470
488
|
|
|
471
489
|
deleteRow() {
|
|
472
490
|
if (this.rowOnFocus) {
|
|
473
491
|
if (confirm("Bạn có chắc chắn muốn xóa dữ liệu này?") != true) return;
|
|
474
|
-
this.#closeEditor(
|
|
492
|
+
this.#closeEditor(true, true);
|
|
475
493
|
const cache = this.#cache;
|
|
476
494
|
const tableConfig = this.config;
|
|
477
495
|
const primaryKey = tableConfig.primaryKey;
|
|
@@ -492,9 +510,36 @@ class DKGrid {
|
|
|
492
510
|
delete this.rowOnFocus;
|
|
493
511
|
}
|
|
494
512
|
}
|
|
513
|
+
getData() {
|
|
514
|
+
const datas = [];
|
|
515
|
+
const cache = this.#cache;
|
|
516
|
+
const dataCollection = {};
|
|
517
|
+
Object.keys(cache.origin).forEach(key => {
|
|
518
|
+
dataCollection[key] = cache.origin[key];
|
|
519
|
+
});
|
|
520
|
+
Object.keys(cache.updated).forEach(key => {
|
|
521
|
+
dataCollection[key] = cache.updated[key];
|
|
522
|
+
});
|
|
523
|
+
Object.keys(cache.deleted).forEach(key => {
|
|
524
|
+
delete dataCollection[key];
|
|
525
|
+
});
|
|
495
526
|
|
|
527
|
+
const dataCollection_array = [];
|
|
528
|
+
Object.values(dataCollection).forEach(item => {
|
|
529
|
+
dataCollection_array.push(item);
|
|
530
|
+
});
|
|
531
|
+
return dataCollection_array;
|
|
532
|
+
}
|
|
496
533
|
commitData() {
|
|
497
|
-
|
|
534
|
+
const cache = this.#cache;
|
|
535
|
+
const data = { updated: [], deleted: [] };
|
|
536
|
+
Object.keys(cache.updated).forEach(key => {
|
|
537
|
+
data.updated.push(cache.updated[key]);
|
|
538
|
+
});
|
|
539
|
+
Object.keys(cache.deleted).forEach(key => {
|
|
540
|
+
data.deleted.push(cache.deleted[key]);
|
|
541
|
+
});
|
|
542
|
+
this.fireEvent('commitData', null, data);
|
|
498
543
|
}
|
|
499
544
|
|
|
500
545
|
cancelChanges() {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Project Summary
|