zet-lib 1.5.18 → 1.5.20
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/lib/Form.js +161 -168
- package/lib/Util.js +106 -110
- package/package.json +1 -1
package/lib/Form.js
CHANGED
|
@@ -6,12 +6,19 @@
|
|
|
6
6
|
const Util = require("./Util");
|
|
7
7
|
|
|
8
8
|
const Form = {};
|
|
9
|
+
// Menghitung jumlah tanda "[" dalam str
|
|
10
|
+
const countOpenBrackets = (str) => {
|
|
11
|
+
return (str.match(/\[/g) || []).length;
|
|
12
|
+
};
|
|
13
|
+
const regex = /^(\w+)\[(\w+)\]/;
|
|
14
|
+
|
|
15
|
+
|
|
9
16
|
const addProperties = (obj, defaultObj = {}) => {
|
|
10
17
|
let html = "";
|
|
11
18
|
for (var key in obj) {
|
|
12
19
|
var value = defaultObj.hasOwnProperty(key)
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
? defaultObj[key] + obj[key]
|
|
21
|
+
: obj[key];
|
|
15
22
|
html += ` ${key}="${obj[key]}" `;
|
|
16
23
|
}
|
|
17
24
|
return html;
|
|
@@ -64,33 +71,33 @@ Form.field = (obj) => {
|
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
let type = obj.type || "text",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
id = obj.isTableModule ? "" : Form.addProperty("id", [obj.id]),
|
|
75
|
+
name = obj.name ? ` name="${obj.name}" ` : "",
|
|
76
|
+
title = obj.title || "",
|
|
77
|
+
prepend = obj.prepend || "",
|
|
78
|
+
append = obj.append || "",
|
|
79
|
+
placeholder = Form.addProperty("placeholder", [obj.placeholder]),
|
|
80
|
+
tabindex = Form.addProperty("tabindex", [obj.tabindex]),
|
|
81
|
+
value = obj.value == undefined ? "" : obj.value,
|
|
82
|
+
classview = obj.class ? ` class="${obj.class}" ` : ` class=" " `,
|
|
83
|
+
disabled = obj.disabled ? ` disabled="disabled" ` : "",
|
|
84
|
+
data = obj.data,
|
|
85
|
+
required = obj.required == true ? ` required ` : "",
|
|
86
|
+
table = !obj.table ? "" : obj.table,
|
|
87
|
+
frameworkcss = !obj.frameworkcss ? "bootstrap5" : obj.frameworkcss,
|
|
88
|
+
form_css = !obj.form_css ? "bootstrap" : obj.form_css,
|
|
89
|
+
attributes = !obj.attributes ? {} : obj.attributes,
|
|
90
|
+
style = !obj.style ? "" : ` style=${obj.style} `,
|
|
91
|
+
additional_attributes = !obj.additional_attributes
|
|
92
|
+
? ""
|
|
93
|
+
: obj.additional_attributes,
|
|
94
|
+
information = !obj.information
|
|
95
|
+
? ""
|
|
96
|
+
: `<div id="information-${obj.id}" class="form-text">${Util.replaceAll(
|
|
97
|
+
obj.information.substring(1, obj.information.length - 1),
|
|
98
|
+
"\r\n",
|
|
99
|
+
"<br>"
|
|
100
|
+
)}</div>`;
|
|
94
101
|
//replaceAll("\r\n","<br>")
|
|
95
102
|
let attributeDate = "";
|
|
96
103
|
if (obj.hasOwnProperty.attributeData) {
|
|
@@ -100,21 +107,21 @@ Form.field = (obj) => {
|
|
|
100
107
|
}
|
|
101
108
|
let hasInputGroup = false;
|
|
102
109
|
let inputGroupLeft = "",
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
inputGroupRight = "",
|
|
111
|
+
inputGroupDivLeft = "";
|
|
105
112
|
if (attributes.hasOwnProperty("hasInputGroup") && attributes.hasInputGroup) {
|
|
106
113
|
hasInputGroup = true;
|
|
107
114
|
prepend = `<div class="input-group mb-3">`;
|
|
108
115
|
append = `</div>`;
|
|
109
116
|
if (
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
attributes.hasOwnProperty("inputGroupLeft") &&
|
|
118
|
+
attributes.inputGroupLeft
|
|
112
119
|
) {
|
|
113
120
|
inputGroupLeft = `<span class="input-group-text">${attributes.inputGroupLeft}</span>`;
|
|
114
121
|
}
|
|
115
122
|
if (
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
attributes.hasOwnProperty("inputGroupRight") &&
|
|
124
|
+
attributes.inputGroupRight
|
|
118
125
|
) {
|
|
119
126
|
inputGroupRight = `<span class="input-group-text">${attributes.inputGroupRight}</span>`;
|
|
120
127
|
}
|
|
@@ -122,8 +129,8 @@ Form.field = (obj) => {
|
|
|
122
129
|
let displayForm = "";
|
|
123
130
|
let readonly = obj.readonly ? `readonly` : ``;
|
|
124
131
|
let boxyclass = "",
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
checked = "",
|
|
133
|
+
selects = "";
|
|
127
134
|
switch (type) {
|
|
128
135
|
case "text":
|
|
129
136
|
displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" ${disabled} ${readonly} autofocus="" ${tabindex} ${additional_attributes} type="${type}" class="form-control ${obj.class}" ${id} ${name} ${placeholder} ${style} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
|
|
@@ -167,50 +174,36 @@ Form.field = (obj) => {
|
|
|
167
174
|
|
|
168
175
|
case "image":
|
|
169
176
|
boxyclass = value ? "boxy" : "";
|
|
170
|
-
let
|
|
171
|
-
let
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}" data-filename="${value}" data-required="${
|
|
184
|
-
obj.required
|
|
185
|
-
}"> <img class="mb-3" width="${obj.width}" id="file${
|
|
186
|
-
obj.id
|
|
187
|
-
}" /><br><a class="text-success" target="_blank" href="/uploads/${
|
|
188
|
-
obj.routeName
|
|
189
|
-
}/${value}"> ${stringvalue}</a> ${trashicon}</div>${append}`;
|
|
177
|
+
let imageLinkName = obj.name || ""
|
|
178
|
+
let bracketsImage = countOpenBrackets(imageLinkName);
|
|
179
|
+
let imageLinkParent = obj.routeName
|
|
180
|
+
if(bracketsImage>1){
|
|
181
|
+
const matchImage = imageLinkName.match(regex);
|
|
182
|
+
imageLinkParent = `${matchImage[1] ? matchImage[1] : '' }/${matchImage[2] ? matchImage[2] : ''}`;
|
|
183
|
+
}
|
|
184
|
+
let stringvalue = value ? value.replace(/^[^_]+_/, '') : "";
|
|
185
|
+
let trashicon = stringvalue ? `<img class="tabler-icons icons-filter-danger" src="/assets/icons/trash-filled.svg" onclick="removeimage(this)">`: "";
|
|
186
|
+
displayForm = `${prepend}<input ${tabindex} type="file" accept="image/*" onchange="loadFile(this,'${obj.id}' )" data-width="${obj.width}" class="form-control ${obj.class || ""}" ${id} ${name} ${placeholder} value="${value}" ${htmlOptions}>
|
|
187
|
+
<div id="body${obj.id}" class="isfile" data-id="${obj.id}" data-table="${obj.routeName}" data-width="${obj.width}" data-name="${obj.title}" data-filename="${value}" data-required="${obj.required}"> <img class="mb-3" width="${obj.width}" id="file${
|
|
188
|
+
obj.id
|
|
189
|
+
}" /><br><a class="text-success" target="_blank" href="/uploads/${imageLinkParent}/${value}"> ${stringvalue}</a> ${trashicon}</div>${append}`;
|
|
190
190
|
break;
|
|
191
191
|
|
|
192
192
|
case "file":
|
|
193
193
|
boxyclass = value ? "boxy" : "";
|
|
194
|
-
let
|
|
195
|
-
let
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}" data-filename="${value}" data-required="${
|
|
208
|
-
obj.required
|
|
209
|
-
}"> <img class="mb-3" id="file${
|
|
210
|
-
obj.id
|
|
211
|
-
}" /><a class="text-success" target="_blank" href="/uploads/${
|
|
212
|
-
obj.routeName
|
|
213
|
-
}/${value}"> ${stringvaluefile}</a>${trashiconfile}</div>${information}${append}`;
|
|
194
|
+
let fileLinkName = obj.name || ""
|
|
195
|
+
let bracketsFile = countOpenBrackets(fileLinkName);
|
|
196
|
+
let fileLinkParent = obj.routeName
|
|
197
|
+
if(bracketsFile>1){
|
|
198
|
+
const matchFile = fileLinkName.match(regex);
|
|
199
|
+
fileLinkParent = `${matchFile[1]?matchFile[1]:''}/${matchFile[2]?matchFile[2]:''}`;
|
|
200
|
+
}
|
|
201
|
+
let stringvaluefile = value ? value.replace(/^[^_]+_/, '') : "";
|
|
202
|
+
let trashiconfile = stringvaluefile? `<img class="tabler-icons icons-filter-danger" src="/assets/icons/trash-filled.svg" onclick="removeimage(this)">`: "";
|
|
203
|
+
displayForm = `${prepend}<input ${tabindex} type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint,text/plain, application/pdf,.css,.js,.jpg,.png,.gif" onchange="loadFile(this,'${obj.id}' )" class="form-control ${
|
|
204
|
+
obj.class || ""}" ${id} ${name} ${placeholder} value="${value}" ${htmlOptions}>
|
|
205
|
+
<div id="body${obj.id}" class="isfile" data-id="${obj.id}" data-name="${obj.title}" data-table="${obj.routeName}" data-filename="${value}" data-required="${obj.required}"> <img class="mb-3" id="file${obj.id}" />
|
|
206
|
+
<a class="text-success" target="_blank" href="/uploads/${fileLinkParent}/${value}"> ${stringvaluefile}</a>${trashiconfile}</div>${information}${append}`;
|
|
214
207
|
break;
|
|
215
208
|
|
|
216
209
|
case "email":
|
|
@@ -387,11 +380,11 @@ Form.field = (obj) => {
|
|
|
387
380
|
if (Array.isArray(arr)) {
|
|
388
381
|
arr.forEach(function (item, index) {
|
|
389
382
|
spanmulti += `<span class='span${obj.id}'>${
|
|
390
|
-
|
|
383
|
+
index + 1
|
|
391
384
|
}. <input type='hidden' name='${obj.name}[]' value='${item}' />${
|
|
392
|
-
|
|
385
|
+
obj.multi[item]
|
|
393
386
|
}<img class='tabler-icons icons-filter-danger pull-right' src='/assets/icons/trash-filled.svg' onclick='$(this).closest("span").remove();' title='${
|
|
394
|
-
|
|
387
|
+
LANGUAGE["delete"]
|
|
395
388
|
}' /><br></span>`;
|
|
396
389
|
});
|
|
397
390
|
}
|
|
@@ -469,9 +462,9 @@ Form.field = (obj) => {
|
|
|
469
462
|
for (var key in obj.fields) {
|
|
470
463
|
let val = !value[key] ? obj.fields[key] : value[key];
|
|
471
464
|
description = Util.replaceAll(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
465
|
+
description,
|
|
466
|
+
`[[[${key}]]]`,
|
|
467
|
+
`<span class="text-danger text-toggle" id="a_${key}" data-id="${key}" style="text-decoration: underline; cursor: pointer">${val}</span> <input type="hidden" name="${obj.name}[${key}]" class="editor-value" id="${key}" data-id="${key}" value="${val}" >`
|
|
475
468
|
);
|
|
476
469
|
}
|
|
477
470
|
displayForm = `${prepend}<div class="boxy">${description}</div>${information}${append}`;
|
|
@@ -484,17 +477,17 @@ Form.field = (obj) => {
|
|
|
484
477
|
|
|
485
478
|
case "json":
|
|
486
479
|
displayForm += `<textarea ${additional_attributes} class="form-control ${
|
|
487
|
-
|
|
480
|
+
obj.class
|
|
488
481
|
}" ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4">${JSON.stringify(
|
|
489
|
-
|
|
482
|
+
obj.value
|
|
490
483
|
)}</textarea>${information}${append}`;
|
|
491
484
|
break;
|
|
492
485
|
|
|
493
486
|
case "json_array":
|
|
494
487
|
displayForm += `<textarea ${additional_attributes} class="form-control ${
|
|
495
|
-
|
|
488
|
+
obj.class
|
|
496
489
|
}" ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4">${JSON.stringify(
|
|
497
|
-
|
|
490
|
+
obj.value
|
|
498
491
|
)}</textarea>${information}${append}`;
|
|
499
492
|
break;
|
|
500
493
|
|
|
@@ -529,9 +522,9 @@ Form.field = (obj) => {
|
|
|
529
522
|
|
|
530
523
|
case "array":
|
|
531
524
|
displayForm += `<textarea ${additional_attributes} class="form-control ${
|
|
532
|
-
|
|
525
|
+
obj.class
|
|
533
526
|
}" ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4">${JSON.stringify(
|
|
534
|
-
|
|
527
|
+
obj.value
|
|
535
528
|
)}</textarea>${information}${append}`;
|
|
536
529
|
break;
|
|
537
530
|
|
|
@@ -539,7 +532,7 @@ Form.field = (obj) => {
|
|
|
539
532
|
displayForm = `${prepend}<input ${additional_attributes} autocomplete="off" autofocus="" ${tabindex} ${style} type="text" ${classview} readonly ${id} ${placeholder} ${required} value="${value}" ${htmlOptions}>${information}${append}`;
|
|
540
533
|
break;
|
|
541
534
|
|
|
542
|
-
|
|
535
|
+
//additionals for form view in view
|
|
543
536
|
case "plaintext":
|
|
544
537
|
displayForm = `<span class="">${obj.value || ""}</span>`;
|
|
545
538
|
break;
|
|
@@ -554,13 +547,13 @@ Form.field = (obj) => {
|
|
|
554
547
|
|
|
555
548
|
case "location":
|
|
556
549
|
displayForm = `${prepend}<input type="text" class="form-control ${
|
|
557
|
-
|
|
550
|
+
obj.class
|
|
558
551
|
}" id="search_map_location" placeholder="type a place" ${required} value="" ${htmlOptions}>${information}${append}
|
|
559
552
|
<textarea ${id} ${name} style="display: none" ${readonly} rows="2">${JSON.stringify(
|
|
560
|
-
|
|
553
|
+
obj.value
|
|
561
554
|
)}</textarea>
|
|
562
555
|
<div id="map_${obj.id}" style="background-color:#C3C3C3;width: 100%;height: ${
|
|
563
|
-
|
|
556
|
+
obj.height
|
|
564
557
|
}px"></div>`;
|
|
565
558
|
break;
|
|
566
559
|
|
|
@@ -575,11 +568,11 @@ Form.field = (obj) => {
|
|
|
575
568
|
|
|
576
569
|
case "dropzoneview":
|
|
577
570
|
let countFiles =
|
|
578
|
-
|
|
571
|
+
obj.value && obj.value.length ? obj.value.length + " Files" : "";
|
|
579
572
|
let bodydropzoneview =
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
573
|
+
countFiles == ""
|
|
574
|
+
? ""
|
|
575
|
+
: `<div class="card-header">${countFiles} <div class="float-end">
|
|
583
576
|
<span class="icon-small icons-light" title="Download"><img onclick="location.href= '/zdownloads-dropzone/${obj.routeName}/${obj.key}/${obj.dataId}'" class="icons-bg-black gridview icon-image" src="/assets/icons/download.svg"></span>
|
|
584
577
|
<span class="icon-small icons-light" title="Compress Images"><img onclick="if(window.confirm('Compress Images ?')) {ajaxPost('/zcompress-dropzone',{table:'${obj.routeName}',field:'${obj.key}',id:${obj.dataId}},(data) => toastrForm(data))}" class="icons-bg-black gridextract icon-image" src="/assets/icons/file-zip.svg"></span>
|
|
585
578
|
</div></div>`;
|
|
@@ -594,11 +587,11 @@ Form.field = (obj) => {
|
|
|
594
587
|
displayForm += `<img src="${filename}" class="boxy zoom mx-2 my-2" width="200px">`;
|
|
595
588
|
} else {
|
|
596
589
|
displayForm +=
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
590
|
+
"<br>" +
|
|
591
|
+
Util.fileView(`/uploads/${obj.table}/${obj.key}/`, item, {
|
|
592
|
+
withIcon: true,
|
|
593
|
+
}) +
|
|
594
|
+
"<br>";
|
|
602
595
|
}
|
|
603
596
|
});
|
|
604
597
|
}
|
|
@@ -616,11 +609,11 @@ Form.field = (obj) => {
|
|
|
616
609
|
|
|
617
610
|
case "dropboxview":
|
|
618
611
|
let countdropboxFiles =
|
|
619
|
-
|
|
612
|
+
obj.value && obj.value.length ? obj.value.length + " Files" : "";
|
|
620
613
|
let bodydropboxview =
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
614
|
+
countdropboxFiles == ""
|
|
615
|
+
? ""
|
|
616
|
+
: `<div class="card-header">${countdropboxFiles} <div class="float-end">
|
|
624
617
|
<span class="icon-small icons-light" title="Download"><img onclick="location.href= '/zdownloads-dropbox/${obj.routeName}/${obj.key}/${obj.dataId}'" class="icons-bg-black gridview icon-image" src="/assets/icons/download.svg"></span>
|
|
625
618
|
<span class="icon-small icons-light" title="Compress Images"><img onclick="if(window.confirm('Compress Images ?')) {ajaxPost('/zcompress-dropbox',{table:'${obj.routeName}',field:'${obj.key}',id:${obj.dataId}},(data) => toastrForm(data))}" class="icons-bg-black gridextract icon-image" src="/assets/icons/file-zip.svg"></span>
|
|
626
619
|
</div></div>`;
|
|
@@ -792,13 +785,13 @@ const card45 = (obj) => {
|
|
|
792
785
|
let html = obj.prepend;
|
|
793
786
|
let objHeader = obj.headerOptions || {};
|
|
794
787
|
let headerOptions = obj.headerOptions
|
|
795
|
-
|
|
796
|
-
|
|
788
|
+
? addProperties(obj.headerOptions, { class: "card" })
|
|
789
|
+
: addProperties({ class: "card" });
|
|
797
790
|
let img = obj.img ? `<img ${addProperties(obj.img)} >` : "";
|
|
798
791
|
let title = `<div class="card-header"><h5 class="card-title">${obj.title}</h5></div>`;
|
|
799
792
|
let footer = (obj.footer = obj.footer
|
|
800
|
-
|
|
801
|
-
|
|
793
|
+
? `<div class="card-footer">${obj.footer}</div>`
|
|
794
|
+
: ``);
|
|
802
795
|
let append = !obj.append ? "" : obj.append;
|
|
803
796
|
html += `<div ${headerOptions}>
|
|
804
797
|
${img}
|
|
@@ -839,11 +832,11 @@ const gridBootstrap5 = (obj) => {
|
|
|
839
832
|
let routeName = obj.routeName;
|
|
840
833
|
let advanceSearch = !obj.advanceSearch ? "" : obj.advanceSearch;
|
|
841
834
|
let createBtn = "",
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
835
|
+
exportBtn = "",
|
|
836
|
+
importBtn = "",
|
|
837
|
+
superBtn = "",
|
|
838
|
+
exportBtnGroup = "",
|
|
839
|
+
selectPagesize = "";
|
|
847
840
|
if (levels.create) {
|
|
848
841
|
createBtn = `<button type="button" id="create_btn" class="btn btn-success btn-xs"><i class="fa fa-plus white-icon"></i></button>`;
|
|
849
842
|
}
|
|
@@ -926,7 +919,7 @@ const tabBootstrap5 = (arr = []) => {
|
|
|
926
919
|
html += `<ul class="nav nav-tabs" id="myTab" role="tablist">${Util.newLine}`;
|
|
927
920
|
arr.forEach(function (item, index) {
|
|
928
921
|
var active = "",
|
|
929
|
-
|
|
922
|
+
selected = "false";
|
|
930
923
|
if (item.active) {
|
|
931
924
|
active = "active";
|
|
932
925
|
selected = "true";
|
|
@@ -953,20 +946,20 @@ Form.build = (obj) => {
|
|
|
953
946
|
let float = false;
|
|
954
947
|
let inline = false;
|
|
955
948
|
let attributes = Object.prototype.hasOwnProperty.call(obj, "attributes")
|
|
956
|
-
|
|
957
|
-
|
|
949
|
+
? obj.attributes
|
|
950
|
+
: {};
|
|
958
951
|
let view_only = Object.prototype.hasOwnProperty.call(obj, "view_only")
|
|
959
|
-
|
|
960
|
-
|
|
952
|
+
? obj.view_only
|
|
953
|
+
: false;
|
|
961
954
|
if (!view_only) {
|
|
962
955
|
if (
|
|
963
|
-
|
|
964
|
-
|
|
956
|
+
attributes &&
|
|
957
|
+
Object.prototype.hasOwnProperty.call(attributes, "name")
|
|
965
958
|
) {
|
|
966
959
|
if (
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
960
|
+
obj.attributes.name == "relation" ||
|
|
961
|
+
obj.attributes.name == "typeahead" ||
|
|
962
|
+
obj.attributes.name == "dropdown_multi"
|
|
970
963
|
) {
|
|
971
964
|
relation = `<a target="_blank" href="/${obj.attributes.table}"> > </a>`;
|
|
972
965
|
}
|
|
@@ -977,8 +970,8 @@ Form.build = (obj) => {
|
|
|
977
970
|
float = obj.attributes.float || false;
|
|
978
971
|
}
|
|
979
972
|
if (
|
|
980
|
-
|
|
981
|
-
|
|
973
|
+
attributes &&
|
|
974
|
+
Object.prototype.hasOwnProperty.call(attributes, "inline")
|
|
982
975
|
) {
|
|
983
976
|
inline = obj.attributes.inline || false;
|
|
984
977
|
}
|
|
@@ -987,50 +980,50 @@ Form.build = (obj) => {
|
|
|
987
980
|
//obj.class = "nice-float"
|
|
988
981
|
if (obj.type == "checkbox") {
|
|
989
982
|
html += `<div class="form-switch mx-auto div${obj.id} mb-3">${Form.field(
|
|
990
|
-
|
|
983
|
+
obj
|
|
991
984
|
)}<label class="form-check-label" for="">${
|
|
992
|
-
|
|
985
|
+
obj.id
|
|
993
986
|
} ${required}</label></div>`;
|
|
994
987
|
} else {
|
|
995
988
|
html += `<div class="form-floating mx-auto mb-3 mt-3 div${
|
|
996
|
-
|
|
989
|
+
obj.id
|
|
997
990
|
} mb-3">${Form.field(obj)}<label for="${obj.id}">${
|
|
998
|
-
|
|
991
|
+
obj.title
|
|
999
992
|
} ${required} ${relation}</label></div>`;
|
|
1000
993
|
}
|
|
1001
994
|
} else {
|
|
1002
995
|
if (inline) {
|
|
1003
996
|
if (obj.type == "checkbox") {
|
|
1004
997
|
html += ` <div class="mb-3 row"><label for="${
|
|
1005
|
-
|
|
998
|
+
obj.id
|
|
1006
999
|
}" class="col form-check-label">${
|
|
1007
|
-
|
|
1000
|
+
obj.title
|
|
1008
1001
|
} ${labelOptions} ${required} ${relation}</label><div class="col-8">${Form.field(
|
|
1009
|
-
|
|
1002
|
+
obj
|
|
1010
1003
|
)}</div></div>`;
|
|
1011
1004
|
} else {
|
|
1012
1005
|
html += ` <div class="mb-3 row"><label for="${
|
|
1013
|
-
|
|
1006
|
+
obj.id
|
|
1014
1007
|
}" class="col col-form-label">${
|
|
1015
|
-
|
|
1008
|
+
obj.title
|
|
1016
1009
|
} ${labelOptions} ${required} ${relation}</label><div class="col-8">${Form.field(
|
|
1017
|
-
|
|
1010
|
+
obj
|
|
1018
1011
|
)}</div></div>`;
|
|
1019
1012
|
}
|
|
1020
1013
|
} else {
|
|
1021
1014
|
if (obj.type == "checkbox") {
|
|
1022
1015
|
html += `<div class="form-check div${obj.id} mb-3">${Form.field(
|
|
1023
|
-
|
|
1016
|
+
obj
|
|
1024
1017
|
)}<label class="form-check-label" for="${obj.id}">${
|
|
1025
|
-
|
|
1018
|
+
obj.title
|
|
1026
1019
|
} ${labelOptions} ${required}</label></div>`;
|
|
1027
1020
|
} else {
|
|
1028
1021
|
html += `<div class="form-group div${obj.id} mb-3"><label for="${
|
|
1029
|
-
|
|
1022
|
+
obj.id
|
|
1030
1023
|
}">${
|
|
1031
|
-
|
|
1024
|
+
obj.title
|
|
1032
1025
|
} ${labelOptions} ${required} ${relation}</label>${Form.field(
|
|
1033
|
-
|
|
1026
|
+
obj
|
|
1034
1027
|
)}</div>`;
|
|
1035
1028
|
}
|
|
1036
1029
|
}
|
|
@@ -1040,11 +1033,11 @@ Form.build = (obj) => {
|
|
|
1040
1033
|
|
|
1041
1034
|
Form.modal = (obj, LANGUAGE = {}) => {
|
|
1042
1035
|
let attributeData = obj.attributeData,
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1036
|
+
visibles = obj.visibles || [],
|
|
1037
|
+
invisibles = obj.invisibles || [],
|
|
1038
|
+
visiblesHtml = "",
|
|
1039
|
+
invisiblesHtml = "",
|
|
1040
|
+
labelsHtml = "";
|
|
1048
1041
|
visibles.map((item) => {
|
|
1049
1042
|
visiblesHtml += `<li data-name="${item}" draggable="true" class="image-li" role="option" aria-grabbed="false"><img src="/assets/icons/eye.svg" class="icons-bg-black"> ${attributeData.labels[item]}</li>`;
|
|
1050
1043
|
});
|
|
@@ -1061,28 +1054,28 @@ Form.modal = (obj, LANGUAGE = {}) => {
|
|
|
1061
1054
|
size: "modal-xl",
|
|
1062
1055
|
header: `<h5 id="dynagrid-1-grid-modal-label" class="modal-title">
|
|
1063
1056
|
<i class="fa fa-cog"></i> ${
|
|
1064
|
-
|
|
1065
|
-
|
|
1057
|
+
LANGUAGE.grid_settings || "Settings Grid"
|
|
1058
|
+
}
|
|
1066
1059
|
</h5>`,
|
|
1067
1060
|
body: `<div class="container">
|
|
1068
1061
|
<form id="form-grid" class="form-vertical kv-form-bs4" action="/${
|
|
1069
|
-
|
|
1070
|
-
|
|
1062
|
+
obj.routeName
|
|
1063
|
+
}/grid" method="post">
|
|
1071
1064
|
<input type="hidden" name="_csrf" value="">
|
|
1072
1065
|
<div class="dynagrid-column-label">
|
|
1073
1066
|
${
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1067
|
+
LANGUAGE.grid_configure ||
|
|
1068
|
+
"Configure Order and Display of Grid Columns"
|
|
1069
|
+
}
|
|
1077
1070
|
</div>
|
|
1078
1071
|
<div class="row">
|
|
1079
1072
|
<div class="col-sm-5">
|
|
1080
1073
|
<ul id="gridleft" class="sortable-visible sortable list kv-connected cursor-move gridsortable" aria-dropeffect="move">
|
|
1081
1074
|
<li data-name="" class="alert alert-info dynagrid-sortable-header disabled">
|
|
1082
1075
|
${
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1076
|
+
LANGUAGE.grid_visible ||
|
|
1077
|
+
"Visible Columns"
|
|
1078
|
+
}
|
|
1086
1079
|
</li>
|
|
1087
1080
|
${visiblesHtml}
|
|
1088
1081
|
</ul>
|
|
@@ -1094,9 +1087,9 @@ Form.modal = (obj, LANGUAGE = {}) => {
|
|
|
1094
1087
|
<ul id="gridright"
|
|
1095
1088
|
class="sortable-hidden sortable list kv-connected cursor-move gridsortable" aria-dropeffect="move">
|
|
1096
1089
|
<li data-name="" class="alert alert-info dynagrid-sortable-header disabled">${
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1090
|
+
LANGUAGE.grid_invisible ||
|
|
1091
|
+
"Hidden / Fixed Columns"
|
|
1092
|
+
}
|
|
1100
1093
|
</li>
|
|
1101
1094
|
${invisiblesHtml}
|
|
1102
1095
|
</ul>
|
|
@@ -1109,13 +1102,13 @@ Form.modal = (obj, LANGUAGE = {}) => {
|
|
|
1109
1102
|
footer: `<select id="zgrid_default_type" class="form-control select-sm" style="width:100px"><option value="1">Standart</option><option value="2">Fixed Header</option><option value="3">Footer Total</option><option value="4">No Wrap</option><option value="5">Fixed Header & No Wrap</option><option value="6">Footer Total & No Wrap</option><option value="7">Fixed Header & Footer & No Wrap</option></select>
|
|
1110
1103
|
<button type="reset" class="btn btn-default refresh gridreload image-button" title="Abort any changes and reset settings">
|
|
1111
1104
|
<img src="/assets/icons/refresh.svg" class="icons-bg-black"> ${
|
|
1112
|
-
|
|
1113
|
-
|
|
1105
|
+
LANGUAGE.reset || "Reset"
|
|
1106
|
+
}
|
|
1114
1107
|
</button>
|
|
1115
1108
|
<button type="button" class="btn btn-primary grid-submit boxy image-button" title="Save grid settings">
|
|
1116
1109
|
<img src="/assets/icons/send.svg" class="icons-bg-white"> ${
|
|
1117
|
-
|
|
1118
|
-
|
|
1110
|
+
LANGUAGE.apply || "Apply"
|
|
1111
|
+
}
|
|
1119
1112
|
</button>`,
|
|
1120
1113
|
});
|
|
1121
1114
|
|
|
@@ -1178,8 +1171,8 @@ Form.modalBuild = (obj) => {
|
|
|
1178
1171
|
class: "modal-header",
|
|
1179
1172
|
});
|
|
1180
1173
|
const header = obj.header
|
|
1181
|
-
|
|
1182
|
-
|
|
1174
|
+
? `<div ${headerOptions} >${obj.header}<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div>`
|
|
1175
|
+
: "";
|
|
1183
1176
|
const body = obj.body ? obj.body : "";
|
|
1184
1177
|
const bodyOptions = Util.attributeOptions(obj.bodyOptions || {}, {
|
|
1185
1178
|
class: "modal-body",
|
|
@@ -1188,8 +1181,8 @@ Form.modalBuild = (obj) => {
|
|
|
1188
1181
|
class: "modal-footer",
|
|
1189
1182
|
});
|
|
1190
1183
|
const footer = obj.footer
|
|
1191
|
-
|
|
1192
|
-
|
|
1184
|
+
? `<div ${footerOptions} >${obj.footer}</div>`
|
|
1185
|
+
: "";
|
|
1193
1186
|
html += `${Util.newLine}<div class="modal fade " ${id} role="dialog" tabindex="-1">
|
|
1194
1187
|
<div class="modal-dialog ${size}">
|
|
1195
1188
|
<div class="modal-content">
|
package/lib/Util.js
CHANGED
|
@@ -55,7 +55,7 @@ Util.newLines = (n) => Util.newLine.repeat(n);
|
|
|
55
55
|
// Hashing functions
|
|
56
56
|
Util.hash = (string) => sha256(string);
|
|
57
57
|
Util.hashCompare = (myPlaintextPassword, hash) =>
|
|
58
|
-
|
|
58
|
+
Util.hash(myPlaintextPassword) === hash;
|
|
59
59
|
|
|
60
60
|
// Excel sequence generator - optimized with memoization
|
|
61
61
|
const excelSequenceCache = new Map();
|
|
@@ -65,7 +65,7 @@ Util.excelSequence = function () {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const abjads = Array.from({ length: 26 }, (_, i) =>
|
|
68
|
-
|
|
68
|
+
String.fromCharCode(65 + i)
|
|
69
69
|
);
|
|
70
70
|
const arr = [...abjads];
|
|
71
71
|
let num = 26;
|
|
@@ -90,22 +90,22 @@ const defaultDateFormat = "YYYY-MM-DD";
|
|
|
90
90
|
const defaultTimeFormat = "YYYY-MM-DD HH:mm:ss";
|
|
91
91
|
|
|
92
92
|
Util.dateSql = (date, format = defaultDateFormat) =>
|
|
93
|
-
|
|
93
|
+
date && date !== "0000-00-00" ? moment(date).format(format) : "";
|
|
94
94
|
|
|
95
95
|
Util.dateOriginal = (date) =>
|
|
96
|
-
|
|
96
|
+
date && date !== "0000-00-00" ? moment(date).utc(false) : "";
|
|
97
97
|
|
|
98
98
|
Util.dateFormat = (date, format = defaultDateFormat) =>
|
|
99
|
-
|
|
99
|
+
date && date !== "0000-00-00" ? moment(date).format(format) : "";
|
|
100
100
|
|
|
101
101
|
Util.timePublic = (date) => (date ? moment(date).format("DD MMM YYYY") : "");
|
|
102
102
|
|
|
103
103
|
Util.timeSql = (date, format = defaultTimeFormat) =>
|
|
104
|
-
|
|
104
|
+
date && date !== "0000-00-00 00:00:00" ? moment(date).format(format) : "";
|
|
105
105
|
|
|
106
106
|
// Optimized date difference calculation
|
|
107
107
|
Util.dateDiff = (start, end, format = "months") =>
|
|
108
|
-
|
|
108
|
+
start && end ? moment(end).diff(moment(start), format, true) : 0;
|
|
109
109
|
|
|
110
110
|
// Optimized date parsing
|
|
111
111
|
Util.getDate = (date = "") => {
|
|
@@ -124,15 +124,15 @@ Util.dateIsBetween = (compare, start, end) => {
|
|
|
124
124
|
const endDate = moment(end);
|
|
125
125
|
|
|
126
126
|
return (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
compareDate.isSame(startDate) ||
|
|
128
|
+
compareDate.isSame(endDate) ||
|
|
129
|
+
compareDate.isBetween(startDate, endDate)
|
|
130
130
|
);
|
|
131
131
|
};
|
|
132
132
|
|
|
133
133
|
// Optimized month and year extraction
|
|
134
134
|
Util.getMonth = (date) =>
|
|
135
|
-
|
|
135
|
+
date?.length > 5 ? new Date(date).getMonth() + 1 : 0;
|
|
136
136
|
|
|
137
137
|
Util.getYear = (date) => Util.dateSql(date)?.slice(0, 4) || "";
|
|
138
138
|
|
|
@@ -149,14 +149,14 @@ Util.calculateDay = function (from, to, holidayInWeek = 0) {
|
|
|
149
149
|
|
|
150
150
|
if (holidayInWeek === 1) {
|
|
151
151
|
const days = Util.enumerateDaysBetweenDates(
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
moment(from).format("YYYY-MM-DD"),
|
|
153
|
+
moment(to).format("YYYY-MM-DD")
|
|
154
154
|
);
|
|
155
155
|
count = days.filter((item) => moment(item).day() !== 0).length;
|
|
156
156
|
} else if (holidayInWeek === 2) {
|
|
157
157
|
const days = Util.enumerateDaysBetweenDates(
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
moment(from).format("YYYY-MM-DD"),
|
|
159
|
+
moment(to).format("YYYY-MM-DD")
|
|
160
160
|
);
|
|
161
161
|
count = days.filter((item) => {
|
|
162
162
|
const day = moment(item).day();
|
|
@@ -209,7 +209,7 @@ Util.escapeRegExp = function (str = "") {
|
|
|
209
209
|
|
|
210
210
|
Util.validateEmail = function (email) {
|
|
211
211
|
let re =
|
|
212
|
-
|
|
212
|
+
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
213
213
|
return re.test(email);
|
|
214
214
|
};
|
|
215
215
|
|
|
@@ -296,13 +296,13 @@ Util.arrayToObject = (array = [], keyField, isInteger = false) => {
|
|
|
296
296
|
if (array.length) {
|
|
297
297
|
array.forEach(function (item) {
|
|
298
298
|
var name =
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
299
|
+
item[keyField] == null
|
|
300
|
+
? "xxxxxx"
|
|
301
|
+
: item[keyField] == "null"
|
|
302
|
+
? "xxxxxx"
|
|
303
|
+
: isInteger
|
|
304
|
+
? item[keyField]
|
|
305
|
+
: item[keyField] + "";
|
|
306
306
|
obj[name] = item;
|
|
307
307
|
});
|
|
308
308
|
}
|
|
@@ -374,7 +374,7 @@ Util.random = function (length) {
|
|
|
374
374
|
length = length || 5;
|
|
375
375
|
let text = "";
|
|
376
376
|
const possible =
|
|
377
|
-
|
|
377
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
378
378
|
for (let i = 0; i < length; i++)
|
|
379
379
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
380
380
|
|
|
@@ -403,13 +403,13 @@ Util.getFormattedDate = function (date) {
|
|
|
403
403
|
let day = date.getDate().toString();
|
|
404
404
|
day = day.length > 1 ? day : "0" + day;
|
|
405
405
|
let time =
|
|
406
|
-
|
|
406
|
+
date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
|
|
407
407
|
return year + "-" + month + "-" + day + " " + time;
|
|
408
408
|
};
|
|
409
409
|
|
|
410
410
|
Util.uniqueId = function () {
|
|
411
411
|
return (
|
|
412
|
-
|
|
412
|
+
Date.now().toString(36) + Math.random().toString(36).substr(2, 5)
|
|
413
413
|
).toUpperCase();
|
|
414
414
|
};
|
|
415
415
|
|
|
@@ -460,7 +460,7 @@ Util.objectToGridFormat = function (obj = {}, isInteger = false) {
|
|
|
460
460
|
Util.random = function (length = 5) {
|
|
461
461
|
let text = "";
|
|
462
462
|
const possible =
|
|
463
|
-
|
|
463
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
464
464
|
for (let i = 0; i < length; i++)
|
|
465
465
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
466
466
|
|
|
@@ -469,26 +469,26 @@ Util.random = function (length = 5) {
|
|
|
469
469
|
|
|
470
470
|
Util.typePrint = {
|
|
471
471
|
register:
|
|
472
|
-
|
|
472
|
+
'{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"10","header":"SURAT PERINTAH KERJA","header_font":"0","header_font_size":"26"}',
|
|
473
473
|
estimation:
|
|
474
|
-
|
|
474
|
+
'{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"ESTIMASI BIAYA PERBAIKAN","header_font":"0","header_font_size":"18"}',
|
|
475
475
|
invoice:
|
|
476
|
-
|
|
476
|
+
'{"paper_size":"A5","paper_size_width":"148","paper_size_height":"210","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"INVOICE","header_font":"0","header_font_size":"18"}',
|
|
477
477
|
currency: '{"symbol":"Rp","name":"Rupiah","thousand":"."}',
|
|
478
478
|
};
|
|
479
479
|
|
|
480
480
|
Util.isJson = function (text) {
|
|
481
481
|
if (text) {
|
|
482
482
|
if (
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
483
|
+
/^[\],:{}\s]*$/.test(
|
|
484
|
+
text
|
|
485
|
+
.replace(/\\["\\\/bfnrtu]/g, "@")
|
|
486
|
+
.replace(
|
|
487
|
+
/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
|
|
488
|
+
"]"
|
|
489
|
+
)
|
|
490
|
+
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")
|
|
491
|
+
)
|
|
492
492
|
) {
|
|
493
493
|
//the json is ok
|
|
494
494
|
return true;
|
|
@@ -526,20 +526,20 @@ Util.getKey = function (obj = {}, field = "") {
|
|
|
526
526
|
|
|
527
527
|
Util.camelize = function (text = "") {
|
|
528
528
|
return text.replace(
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
529
|
+
/^([A-Z])|[\s-_]+(\w)/g,
|
|
530
|
+
function (match, p1, p2, offset) {
|
|
531
|
+
if (p2) return p2.toUpperCase();
|
|
532
|
+
return p1.toLowerCase();
|
|
533
|
+
}
|
|
534
534
|
);
|
|
535
535
|
};
|
|
536
536
|
|
|
537
537
|
Util.decamelize = function (str = "", separator = "_") {
|
|
538
538
|
return str
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
539
|
+
.replace(/([a-z\d])([A-Z])/g, "$1" + separator + "$2")
|
|
540
|
+
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, "$1" + separator + "$2")
|
|
541
|
+
.replace("_", separator)
|
|
542
|
+
.toLowerCase();
|
|
543
543
|
};
|
|
544
544
|
|
|
545
545
|
/*
|
|
@@ -582,9 +582,9 @@ Util.fieldToName = function (str = "") {
|
|
|
582
582
|
|
|
583
583
|
Util.capitalizeWord = (string = "") => {
|
|
584
584
|
return string
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
585
|
+
.split(" ")
|
|
586
|
+
.map((m) => m[0].toUpperCase() + m.substr(1))
|
|
587
|
+
.join(" ");
|
|
588
588
|
};
|
|
589
589
|
|
|
590
590
|
Util.capitalizeFirstLetter = (string = "") => {
|
|
@@ -648,7 +648,7 @@ Util.gridSearch = function (visibles, relations, name, value) {
|
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
return (
|
|
651
|
-
|
|
651
|
+
"searchValue.eq(" + index + ').find("' + elm + '").val("' + value + '");'
|
|
652
652
|
);
|
|
653
653
|
};
|
|
654
654
|
|
|
@@ -664,8 +664,8 @@ Util.formatNumber = function (num, thousandSeparator = ".") {
|
|
|
664
664
|
const parts = strValue.split(",");
|
|
665
665
|
// Format integer part with thousand separators
|
|
666
666
|
const integerPart = parts[0].replace(
|
|
667
|
-
|
|
668
|
-
|
|
667
|
+
/\B(?=(\d{3})+(?!\d))/g,
|
|
668
|
+
thousandSeparator
|
|
669
669
|
);
|
|
670
670
|
// If there's a decimal part, add it back
|
|
671
671
|
if (parts.length > 1) {
|
|
@@ -749,8 +749,8 @@ Util.fileView = function (dir = "", file = "", attributes = {}) {
|
|
|
749
749
|
let withIcon = attributes.hasOwnProperty("withIcon") ? true : false;
|
|
750
750
|
let obj = Util.fileExtension(filename);
|
|
751
751
|
let className = attributes.hasOwnProperty("class")
|
|
752
|
-
|
|
753
|
-
|
|
752
|
+
? ` class="${attributes.class}" `
|
|
753
|
+
: "";
|
|
754
754
|
if (filename.includes("https")) {
|
|
755
755
|
html = `<img src="${file}" ${className} class="img-responsive">`;
|
|
756
756
|
} else {
|
|
@@ -760,14 +760,10 @@ Util.fileView = function (dir = "", file = "", attributes = {}) {
|
|
|
760
760
|
if (file) {
|
|
761
761
|
if (withIcon) {
|
|
762
762
|
html = `<img class="mb-3 boxy-small" src="/img/${
|
|
763
|
-
|
|
764
|
-
}" height="45px" width="45px"><a class="text-success" target="_blank" href="${filename}"> ${file.
|
|
765
|
-
13
|
|
766
|
-
)}</a>`;
|
|
763
|
+
obj.file
|
|
764
|
+
}" height="45px" width="45px"><a class="text-success" target="_blank" href="${filename}"> ${file.replace(/^[^_]+_/,'')}</a>`;
|
|
767
765
|
} else {
|
|
768
|
-
html = `<a class="text-success" target="_blank" href="${filename}"> ${file.
|
|
769
|
-
13
|
|
770
|
-
)}</a>`;
|
|
766
|
+
html = `<a class="text-success" target="_blank" href="${filename}"> ${file.replace(/^[^_]+_/,'')}</a>`;
|
|
771
767
|
}
|
|
772
768
|
}
|
|
773
769
|
}
|
|
@@ -792,9 +788,9 @@ Util.arrayToList = function (arr, array, delimiter, isCount) {
|
|
|
792
788
|
if (arr) {
|
|
793
789
|
for (var i = 0; i < arr.length; i++) {
|
|
794
790
|
html +=
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
791
|
+
isCount == 1
|
|
792
|
+
? i + 1 + ". " + array[arr[i]] + delimiter
|
|
793
|
+
: " " + array[arr[i]] + delimiter;
|
|
798
794
|
}
|
|
799
795
|
html = html.slice(0, delimiter.length * -1);
|
|
800
796
|
}
|
|
@@ -817,14 +813,14 @@ Util.dropdownHelper = function (data, field, model) {
|
|
|
817
813
|
let fieldsx = field + "[]";
|
|
818
814
|
let name = field + "[]";
|
|
819
815
|
let myvalue =
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
816
|
+
typeof data[fieldsx] == undefined
|
|
817
|
+
? " "
|
|
818
|
+
: typeof data[fieldsx] == "string"
|
|
819
|
+
? '["' + data[fieldsx] + '"]'
|
|
820
|
+
: JSON.stringify(data[name]);
|
|
825
821
|
if (myvalue) {
|
|
826
822
|
let unique =
|
|
827
|
-
|
|
823
|
+
myvalue.indexOf("[") > -1 ? myvalue : !myvalue ? "" : "[" + myvalue + "]";
|
|
828
824
|
unique = JSON.parse(unique);
|
|
829
825
|
data[field] = JSON.stringify(unique.filter(Util.arrayUnique));
|
|
830
826
|
delete data[name];
|
|
@@ -840,14 +836,14 @@ Util.dropdownHelper = function (data, field, model) {
|
|
|
840
836
|
Util.dropdownAdd = function (data, field, model, datas) {
|
|
841
837
|
let name = field + "[]";
|
|
842
838
|
let myvalue =
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
839
|
+
typeof datas == undefined
|
|
840
|
+
? " "
|
|
841
|
+
: typeof datas == "string"
|
|
842
|
+
? '["' + datas + '"]'
|
|
843
|
+
: JSON.stringify(datas);
|
|
848
844
|
if (myvalue) {
|
|
849
845
|
let unique =
|
|
850
|
-
|
|
846
|
+
myvalue.indexOf("[") > -1 ? myvalue : !myvalue ? "" : "[" + myvalue + "]";
|
|
851
847
|
unique = JSON.parse(unique);
|
|
852
848
|
myvalue = JSON.stringify(unique.filter(Util.arrayUnique));
|
|
853
849
|
delete data[name];
|
|
@@ -946,7 +942,7 @@ Util.arrayToConcat = function (arr = []) {
|
|
|
946
942
|
Util.arraySequence = function (arr = [], left = [], right = []) {
|
|
947
943
|
let obj = Util.arrayToObject(arr, "Field");
|
|
948
944
|
let temp = [],
|
|
949
|
-
|
|
945
|
+
stores = [];
|
|
950
946
|
for (let i = 0; i < arr.length; i++) {
|
|
951
947
|
if (arr[i].Field == "id") {
|
|
952
948
|
stores.push(arr[i].Field);
|
|
@@ -998,10 +994,10 @@ Util.arraySequence = function (arr = [], left = [], right = []) {
|
|
|
998
994
|
|
|
999
995
|
Util.isInteger = (value) => {
|
|
1000
996
|
return (
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
997
|
+
!isNaN(value) &&
|
|
998
|
+
(function (x) {
|
|
999
|
+
return (x | 0) === x;
|
|
1000
|
+
})(parseFloat(value))
|
|
1005
1001
|
);
|
|
1006
1002
|
};
|
|
1007
1003
|
|
|
@@ -1078,8 +1074,8 @@ Util.regexPassword = (lengthMin, lengthMax) => {
|
|
|
1078
1074
|
lengthMax = lengthMax || 20;
|
|
1079
1075
|
|
|
1080
1076
|
return new RegExp(
|
|
1081
|
-
|
|
1082
|
-
|
|
1077
|
+
"^[a-zA-Z0-9_-]{" + lengthMin + "," + lengthMax + "}$",
|
|
1078
|
+
"i"
|
|
1083
1079
|
);
|
|
1084
1080
|
};
|
|
1085
1081
|
|
|
@@ -1093,10 +1089,10 @@ Util.regexCode = (lengthMin, lengthMax) => {
|
|
|
1093
1089
|
|
|
1094
1090
|
Util.imageProfile = function (image = "") {
|
|
1095
1091
|
return image
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1092
|
+
? image.indexOf("http") > -1
|
|
1093
|
+
? image
|
|
1094
|
+
: "/uploads/zuser/" + image
|
|
1095
|
+
: "/img/user.png";
|
|
1100
1096
|
};
|
|
1101
1097
|
|
|
1102
1098
|
/*
|
|
@@ -1262,10 +1258,10 @@ Util.array_to_arraypg = (arr = []) => {
|
|
|
1262
1258
|
|
|
1263
1259
|
Util.userAvatar = (img = "") => {
|
|
1264
1260
|
return img
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1261
|
+
? img.includes("http")
|
|
1262
|
+
? img
|
|
1263
|
+
: `/uploads/user/${img}`
|
|
1264
|
+
: `/img/user.png`;
|
|
1269
1265
|
};
|
|
1270
1266
|
|
|
1271
1267
|
/*
|
|
@@ -1306,7 +1302,7 @@ Util.selectParser = (fields = [], MYMODEL = {}) => {
|
|
|
1306
1302
|
Util.fieldWithTable = (field, MYMODEL, isWhere = false) => {
|
|
1307
1303
|
let name = "";
|
|
1308
1304
|
let joinList =
|
|
1309
|
-
|
|
1305
|
+
MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.list : [];
|
|
1310
1306
|
if (joinList.length > 0) {
|
|
1311
1307
|
if (joinList.includes(field)) {
|
|
1312
1308
|
let split = field.split("___");
|
|
@@ -1326,8 +1322,8 @@ Util.fieldWithTable = (field, MYMODEL, isWhere = false) => {
|
|
|
1326
1322
|
|
|
1327
1323
|
Util.tableWithJoin = (MYMODEL) => {
|
|
1328
1324
|
return MYMODEL.joins && MYMODEL.joins.list.length > 0
|
|
1329
|
-
|
|
1330
|
-
|
|
1325
|
+
? MYMODEL.joins.sql
|
|
1326
|
+
: [];
|
|
1331
1327
|
};
|
|
1332
1328
|
|
|
1333
1329
|
Util.selectMysql = (fields = [], relations = {}) => {
|
|
@@ -1383,10 +1379,10 @@ Util.sortArray = (arr, key) => {
|
|
|
1383
1379
|
|
|
1384
1380
|
Util.cleanString = (str = "") => {
|
|
1385
1381
|
return str
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1382
|
+
.replaceAll("(", "")
|
|
1383
|
+
.replaceAll(")", "")
|
|
1384
|
+
.replaceAll("%", "")
|
|
1385
|
+
.replaceAll("-", "");
|
|
1390
1386
|
};
|
|
1391
1387
|
|
|
1392
1388
|
Util.encrypt = (str, key) => {
|
|
@@ -1444,17 +1440,17 @@ Util.terbilang = (nilai) => {
|
|
|
1444
1440
|
} else if (nilai < 1000000000) {
|
|
1445
1441
|
bagi = Math.floor(nilai / 1000000);
|
|
1446
1442
|
penyimpanan =
|
|
1447
|
-
|
|
1443
|
+
Util.terbilang(bagi) + " Juta" + Util.terbilang(nilai % 1000000);
|
|
1448
1444
|
} else if (nilai < 1000000000000) {
|
|
1449
1445
|
bagi = Math.floor(nilai / 1000000000);
|
|
1450
1446
|
penyimpanan =
|
|
1451
|
-
|
|
1447
|
+
Util.terbilang(bagi) + " Miliar" + Util.terbilang(nilai % 1000000000);
|
|
1452
1448
|
} else if (nilai < 1000000000000000) {
|
|
1453
1449
|
bagi = Math.floor(nilai / 1000000000000);
|
|
1454
1450
|
penyimpanan =
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1451
|
+
Util.terbilang(nilai / 1000000000000) +
|
|
1452
|
+
" Triliun" +
|
|
1453
|
+
Util.terbilang(nilai % 1000000000000);
|
|
1458
1454
|
}
|
|
1459
1455
|
return penyimpanan;
|
|
1460
1456
|
};
|
|
@@ -1499,12 +1495,12 @@ Util.tableShowInGrid = (arr, qey, MYMODEL, myCache, companyId) => {
|
|
|
1499
1495
|
value = value ? mywidget[key].fields[value] : "";
|
|
1500
1496
|
} else if (mywidget[key].name == "relation") {
|
|
1501
1497
|
value = value
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1498
|
+
? Util.array_id_to_zname(
|
|
1499
|
+
myCache.get(
|
|
1500
|
+
`${mywidget[key].table}_${MYMODEL.widgets[qey].table}___${key}_${companyId}`
|
|
1501
|
+
)
|
|
1506
1502
|
)[value]
|
|
1507
|
-
|
|
1503
|
+
: "";
|
|
1508
1504
|
} else {
|
|
1509
1505
|
if (Util.isNumeric(value)) {
|
|
1510
1506
|
value = Util.formatNumber(value, ".");
|