zet-lib 1.0.0

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 ADDED
@@ -0,0 +1,717 @@
1
+ /**
2
+ * Universal class Form UI HTML
3
+ * Created by sintret dev on 8/23/2021.
4
+ */
5
+
6
+ const Util = require("./Util");
7
+
8
+ const Form = {};
9
+ const addProperties = (obj, defaultObj = {}) => {
10
+ let html = '';
11
+ for (var key in obj) {
12
+ var value = defaultObj.hasOwnProperty(key) ? defaultObj[key] + obj[key] : obj[key];
13
+ html += ` ${key}="${obj[key]}" `;
14
+ }
15
+ return html;
16
+ };
17
+
18
+ Form.options = {
19
+ button: {
20
+ id: "form-submit",
21
+ type: "button",
22
+ class: "btn btn-success boxy",
23
+ label: `<img src="/assets/icons/send.svg" class="icons-bg-white" > Submit`
24
+ },
25
+ field: {}
26
+ };
27
+
28
+
29
+ Form.label = (field, label, required, htmlOptions = "") => {
30
+ required = required || false;
31
+ const mark = required ? "*" : "";
32
+ return `<label for="${field}">${label} ${mark} ${htmlOptions}</label>`;
33
+ };
34
+
35
+ Form.textarea = (obj) => {
36
+ obj.type = "textarea";
37
+ return Form.field(obj);
38
+ };
39
+
40
+ Form.input = (obj) => {
41
+ obj.type = "input";
42
+ return Form.field(obj);
43
+ };
44
+
45
+ Form.addProperty = (property, options = []) => {
46
+ ///We expect options to be a non-empty Array
47
+ if (!options.length) return;
48
+ var optionsString = options.join(" ");
49
+ return ` ${property}="${optionsString}" `;
50
+ };
51
+
52
+ Form.field = (obj) => {
53
+ //options and default options
54
+ let options = obj.options || {};
55
+ let htmlOptions = '';
56
+ for (let key in options) {
57
+ let val = options[key];
58
+ val = Util.replaceAll(val, '"', "");
59
+ if (obj.hasOwnProperty(key)) {
60
+ obj[key] = options[key];
61
+ } else {
62
+ htmlOptions += ` ${key}=${val} `;
63
+ }
64
+ }
65
+ let type = obj.type || "text",
66
+ id = Form.addProperty("id", [obj.id]),
67
+ name = obj.name ? ` name="${obj.name}" ` : "",
68
+ title = obj.title || "",
69
+ prepend = obj.prepend || "",
70
+ append = obj.append || "",
71
+ placeholder = Form.addProperty("placeholder", [obj.placeholder]),
72
+ tabindex = Form.addProperty("tabindex", [obj.tabindex]),
73
+ value = obj.value == undefined ? "" : obj.value,
74
+ classview = obj.class ? ` class="${obj.class}" ` : ` class=" " `,
75
+ disabled = obj.disabled ? ` disabled="disabled" ` : '',
76
+ data = obj.data,
77
+ required = obj.required == true ? ` required ` : '',
78
+ table = !obj.table ? "" : obj.table,
79
+ frameworkcss = !obj.frameworkcss ? "bootstrap5" : obj.frameworkcss,
80
+ form_css = !obj.form_css ? "bootstrap" : obj.form_css,
81
+ attributes = !obj.attributes ? {} : obj.attributes,
82
+ style = !obj.style ? "" : ` style=${obj.style} `,
83
+ information = !obj.information ? "" : `<div id="information-${obj.id}" class="form-text">${Util.replaceAll(obj.information.substring(1, (obj.information.length - 1)), "\r\n", "<br>")}</div>`
84
+ ;
85
+ //replaceAll("\r\n","<br>")
86
+ let attributeDate = "";
87
+ if (obj.hasOwnProperty.attributeData) {
88
+ for (let key in obj.attributeData) {
89
+ attributeDate += ` data-${key}="${obj.attributeData[key]}" `;
90
+ }
91
+ }
92
+ let hasInputGroup = false;
93
+ let inputGroupLeft="",inputGroupRight="",inputGroupDivLeft="";
94
+ if(attributes.hasOwnProperty("hasInputGroup") && attributes.hasInputGroup) {
95
+ hasInputGroup = true;
96
+ prepend = `<div class="input-group mb-3">`
97
+ append = `</div>`
98
+ if(attributes.hasOwnProperty("inputGroupLeft") && attributes.inputGroupLeft) {
99
+ inputGroupLeft = `<span class="input-group-text">${attributes.inputGroupLeft}</span>`
100
+ }
101
+ if(attributes.hasOwnProperty("inputGroupRight") && attributes.inputGroupRight) {
102
+ inputGroupRight = `<span class="input-group-text">${attributes.inputGroupRight}</span>`
103
+ }
104
+ }
105
+ let displayForm = '';
106
+ let readonly = obj.readonly ? `readonly` : ``;
107
+ let boxyclass = '', checked = '',selects = '';
108
+ switch (type) {
109
+ case "text" :
110
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" ${disabled} ${readonly} autofocus="" ${tabindex} type="${type}" ${classview} ${id} ${name} ${placeholder} ${style} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
111
+ break;
112
+
113
+ case "checkbox" :
114
+ checked = value == 1 ? "checked" : "";
115
+ displayForm = `${prepend}<input autocomplete="off" autofocus="" ${tabindex} ${disabled} ${readonly} ${style} type="checkbox" class="form-check-input ${obj.class}" ${id} ${name} ${checked} ${htmlOptions}>${information}${append}`;
116
+ break;
117
+
118
+ case "tags" :
119
+ classview = ` class="form-control tags ${obj.class ? obj.class : ''} " `;
120
+ let datahtml = "";
121
+ if (value) {
122
+ let dataValue = [];
123
+ if(typeof value == "string") {
124
+ dataValue= JSON.parse(value) || [];
125
+ } else {
126
+ dataValue = value || [];
127
+ }
128
+ dataValue.forEach(function (item) {
129
+ datahtml += `<option value="${item}" selected="selected">${item}</option>`
130
+ });
131
+ }
132
+ displayForm = `${prepend}<select ${classview} ${id} ${name} ${placeholder} multiple data-allow-new="true">${datahtml}</select>${information}${append}`;
133
+ break;
134
+
135
+ case "range" :
136
+ let min = !obj.min ? 0 : obj.min;
137
+ let max = !obj.max ? 100 : obj.max;
138
+ displayForm = `${prepend}${inputGroupLeft}<input onmouseover="titlerange(this)" onchange="titlerange(this)" autocomplete="off" autofocus="" ${tabindex} type="${type}" class="form-range" step="1" ${id} ${name} ${placeholder} ${style} ${required} value="${value}" data-t="${value}" min="${min}" max="${max}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
139
+ break;
140
+
141
+ case "hidden" :
142
+ displayForm = `${prepend}<input autocomplete="off" autofocus="" ${tabindex} type="${type}" ${style} ${classview} ${id} ${name} ${placeholder} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${append}`;
143
+ break;
144
+
145
+ case "textarea" :
146
+ displayForm = `${prepend}${inputGroupLeft}<textarea ${tabindex} ${disabled} ${classview} ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4">${value}</textarea>${inputGroupRight}${information}${append}`;
147
+ break;
148
+
149
+ case "image" :
150
+ boxyclass = value ? "boxy" : "";
151
+ let stringvalue = value ? value.substring(13) : '';
152
+ let trashicon = stringvalue ? `<img class="tabler-icons icons-filter-danger" src="/assets/icons/trash-filled.svg" onclick="removeimage(this)">` : '';
153
+ 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}>
154
+ <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" id="file${obj.id}" /><br><a class="text-success" target="_blank" href="/uploads/${obj.routeName}/${value}"> ${stringvalue}</a> ${trashicon}</div>${append}`;
155
+ break;
156
+
157
+ case "file" :
158
+ boxyclass = value ? "boxy" : "";
159
+ let stringvaluefile = value ? value.substring(13) : '';
160
+ let trashiconfile = stringvaluefile ? `<img class="tabler-icons icons-filter-danger" src="/assets/icons/trash-filled.svg" onclick="removeimage(this)">` : '';
161
+ 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 ${obj.class || ''}" ${id} ${name} ${placeholder} value="${value}" ${htmlOptions}>
162
+ <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}" /><a class="text-success" target="_blank" href="/uploads/${obj.routeName}/${value}"> ${stringvaluefile}</a>${trashiconfile}</div>${information}${append}`;
163
+ break;
164
+
165
+ case "email" :
166
+ displayForm = `${prepend}<input autocomplete="off" autofocus="" ${readonly} ${disabled} ${tabindex} ${style} type="email" ${classview} ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${information}${append}`;
167
+ break;
168
+
169
+ case "number" :
170
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${tabindex} ${style} type="text" class="form-control number ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
171
+ break;
172
+
173
+ case "integer" :
174
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${tabindex} ${style} type="text" class="form-control ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
175
+ break;
176
+
177
+ case "datepicker" :
178
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${tabindex} ${style} type="text" class="form-control datepicker ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
179
+ break;
180
+
181
+ case "datetimepicker" :
182
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${tabindex} type="text" ${style} class="form-control datetimepicker ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
183
+ break;
184
+
185
+ case "password" :
186
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${tabindex} ${style} type="password" ${classview} ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}><span toggle="#password" class="bx bi-eye field-icon toggle-password"></span>${inputGroupRight}${information}${append}`;
187
+ break;
188
+
189
+ case "switch" :
190
+ checked = value == 1 ? " checked " : "";
191
+ displayForm = `${prepend}<p><input ${tabindex} type="checkbox" ${classview} ${readonly} ${style} ${id} ${name} ${checked} ></p>${information}${append}`;
192
+ break;
193
+
194
+ case "lexical" :
195
+ displayForm = `${prepend}<div ${id}>${information}${append}`;
196
+ break;
197
+
198
+ case "checkbox" :
199
+ checked = value == 1 ? " checked " : "";
200
+ displayForm = `${prepend}<input ${tabindex} type="${type}" ${classview} ${readonly} ${style} ${id} ${name} ${checked} >${information}${append}`;
201
+ break;
202
+
203
+ case "dropdown_checkbox" :
204
+ let checkboxes = "";
205
+ let val = [];
206
+ if (typeof value == "object") {
207
+ val = value;
208
+ } else if (typeof value == "string") {
209
+ if (value) {
210
+ val = JSON.parse(value);
211
+ }
212
+ }
213
+ data.forEach(function (item) {
214
+ const checked = Util.in_array(item, val) ? " checked " : "";
215
+ checkboxes += `<div class="checkbox">
216
+ <label class="">
217
+ <input type="checkbox" name="${obj.name}[${item}]" ${checked} value="${item}">
218
+ ${item}
219
+ </label>
220
+ </div>`;
221
+ });
222
+ displayForm = `${prepend}<div class="form-check">${checkboxes}</div>${information}${append}`;
223
+ break;
224
+
225
+ case "select" :
226
+ if(obj.hasOwnProperty("array")) {
227
+ var items = obj.array || [];
228
+ var please_select = obj.please_select;
229
+ if(please_select != undefined) {
230
+ if(please_select != "") {
231
+ selects += `<option value="">${please_select}</option>`;
232
+ }
233
+ }
234
+ if(items.length) {
235
+ items.forEach(function (item) {
236
+ const selected = item.value == value ? ' selected ' : '';
237
+ selects += `<option value="${item.value}" ${selected}>${item.label}</option>`;
238
+ });
239
+ } else {
240
+ if (Array.isArray(data)) {
241
+ data.map((item) => {
242
+ var selected = item.id == value ? ' selected ' : '';
243
+ selects += `<option value="${item.id}" ${selected}>${item.zname}</option>`;
244
+ });
245
+ } else {
246
+ for (var keys in data) {
247
+ var selected = keys == value ? ' selected ' : '';
248
+ selects += `<option value="${keys}" ${selected}>${data[keys]}</option>`;
249
+ }
250
+ }
251
+ }
252
+ } else {
253
+ if (Array.isArray(data)) {
254
+ data.map((item) => {
255
+ const selected = item.id == value ? ' selected ' : '';
256
+ selects += `<option value="${item.id}" ${selected}>${item.zname}</option>`;
257
+ });
258
+ } else {
259
+ for (let keys in data) {
260
+ let selected = keys == value ? ' selected ' : '';
261
+ selects += `<option value="${keys}" ${selected}>${data[keys]}</option>`;
262
+ }
263
+ }
264
+ }
265
+ if (form_css == "material_design") {
266
+ classview = Form.addProperty("class", ["selectpicker", obj.class]);
267
+ }
268
+ displayForm = `${prepend}<select ${tabindex} ${style} ${disabled} ${readonly} class="form-control form-select ${obj.class}" ${id} ${name} ${placeholder} ${required} ${htmlOptions} >${selects}</select>${information}${append}`;
269
+ break;
270
+
271
+ case "radio" :
272
+ let radios = '';
273
+ let arr = obj.array || [];
274
+ arr.map((item, index) => {
275
+ //var selected = item.value == value ? ' selected ' : '';
276
+ const checked = item.value == value ? ' checked ' : '';
277
+ radios += `<div class="form-check">
278
+ <input class="form-check-input" type="radio" name="${obj.name}" value="${item.value}" id="${obj.id}${index}" ${checked}>
279
+ <label class="form-check-label" for="${obj.id}${index}">
280
+ ${item.label}
281
+ </label>
282
+ </div>`;
283
+ });
284
+ displayForm = `${prepend} ${radios} ${information}${append}`;
285
+ break;
286
+
287
+ case "select_user" :
288
+ selects = '';
289
+ data.map((item) => {
290
+ const selected = item.value == value ? ' selected ' : '';
291
+ selects += `<option value="${item.id}" ${selected}>${item.fullname}</option>`;
292
+ });
293
+
294
+ if (form_css == "material_design") {
295
+ classview = Form.addProperty("class", ["selectpicker", obj.class]);
296
+ }
297
+ displayForm = `${prepend}<select ${tabindex} class="form-control form-select ${obj.class}" ${id} ${name} ${placeholder} ${required} ${htmlOptions} >${selects}</select>${information}${append}`;
298
+ break;
299
+
300
+ case "chain" :
301
+ selects = '';
302
+ // for array item.value and item.text
303
+ // proptery is value and text
304
+ data.map((item) => {
305
+ var selected = item.id == value ? ' selected ' : '';
306
+ selects += `<option value="${item.id}" ${selected}>${item.zname}</option>`;
307
+ });
308
+ if (form_css == "material_design") {
309
+ classview = Form.addProperty("class", ["selectpicker", obj.class]);
310
+ }
311
+ displayForm = `${prepend}<select ${tabindex} class="form-control form-select ${obj.class}" ${id} ${name} ${placeholder} ${required} ${htmlOptions} >${selects}</select>${information}${append}`;
312
+ break;
313
+
314
+ case "multi" :
315
+ selects = "";
316
+ if (data) {
317
+ data.map((item) => {
318
+ var selected = value == item.id ? " selected " : "";
319
+ selects += `<option value="${item.id}" ${selected} >${item.zname}</option>`;
320
+ });
321
+ }
322
+
323
+ var spanmulti = '';
324
+ if (value) {
325
+ let arr = [];
326
+ arr = typeof value == "string" ? JSON.parse(value) : value;
327
+ if (Array.isArray(arr)) {
328
+ arr.forEach(function (item, index) {
329
+ spanmulti += `<span class='span${obj.id}'>${index + 1}. <input type='hidden' name='${obj.name}[]' value='${item}' />${obj.multi[item]}<i class='fa fa-trash pointer text-danger pull-right' onclick='$(this).closest("span").remove();' title='${LANGUAGE['delete']}'></i><br></span>`;
330
+ });
331
+ }
332
+ }
333
+ if (form_css == "material_design") {
334
+ classview = Form.addProperty("class", ["selectpicker", obj.class]);
335
+ }
336
+
337
+ let g = `<div class="input-group ">
338
+ <span class="input-group-text" id="dropdownadd${id}" class="dropdownadd" data-id="${id}" style="cursor: pointer" title="Add Data">+</span>
339
+ </div>
340
+ <div id="dropdownbox${id}" class="boxy">
341
+ <span class="span${id}">
342
+ </span>
343
+ </div>`
344
+ return `<div class="input-group">
345
+ <select ${tabindex} class="form-control" ${id} ${placeholder} ${required} ${htmlOptions} >${selects}</select>
346
+ <span id="dropdownadd${obj.id}" class="input-group-text dropdownadd" data-id="${obj.id}" style="cursor: pointer;" title=" ${LANGUAGE["form_add_data"]} ">+</span>
347
+ </div>
348
+ <div id="dropdownbox${obj.id}" class="boxy mb-3">${spanmulti}</div>`;
349
+ break;
350
+
351
+ case "typeahead" :
352
+ let typeahead_value = Util.replaceAll(obj.typeaheadvalue,'"',`'`)
353
+ displayForm = `${prepend}<div class="input-group">
354
+ <input ${tabindex} type="text" class="form-control" id="${obj.id}Typeahead" autocomplete="off" data-provide="typeahead" id="${obj.id}Typeahead" placeholder="Please type a word" value="${typeahead_value}" >
355
+ <input type="hidden" ${id} ${name} ${placeholder} ${classview} ${required} value="${value}">
356
+ <span id="${obj.id}Clear" class="input-group-addon input-group-text dropdownadd" title="Clear" style="cursor: pointer;" title=" Add Data "><img src="/assets/icons/ban.svg" class="icons-bg-black" ></span>
357
+ </div>${information}${append}`;
358
+ break;
359
+
360
+ case "table" :
361
+ let html = '';
362
+ /*console.log(`table : ${obj.data}`)
363
+ console.log(JSON.stringify(obj.data))
364
+ console.log(JSON.stringify(obj.properties));*/
365
+ for (let key in obj.data) {
366
+ if (obj.properties[key].hidden) {
367
+ html += `<th></th>`;
368
+ } else {
369
+ html += `<th>${obj.data[key]}</th>`;
370
+ }
371
+ }
372
+ let btnAdd = '';
373
+ if (!obj.isAddButton && !obj.viewOnly) {
374
+ btnAdd = `<th><button type="button" class="btn" title="Add" id="add${obj.id}"><img src="/assets/icons/plus.svg" class="icons-bg-black" ></button></th>`;
375
+ }
376
+ obj.btnAdd = btnAdd;
377
+ obj.html = html;
378
+ obj.title = title;
379
+ obj.table = table;
380
+ obj.value = value;
381
+ let datavalue = "";
382
+ if (obj.value) {
383
+ datavalue = JSON.stringify(obj.value);
384
+ datavalue = Util.replaceAll(datavalue, "'", "`");
385
+ }
386
+ obj.prepend = prepend;
387
+ obj.body = `<div class="table-responsive">
388
+ <table id="table${obj.id}" class="table table-hover table-sm">
389
+ <thead>
390
+ <tr>
391
+ ${html}
392
+ ${obj.btnAdd}
393
+ </tr>
394
+ </thead>
395
+ <tbody id="body-${obj.id}" data-value='${datavalue}'>${obj.table}</tbody>
396
+ </table></div>`;
397
+ displayForm = Form.card(frameworkcss, obj);
398
+ break;
399
+
400
+ case "multi_line_editor" :
401
+ value = obj.value ? obj.value : {};
402
+ let description = obj.description || "";
403
+ for (var key in obj.fields) {
404
+ let val = !value[key] ? obj.fields[key] : value[key];
405
+ description = Util.replaceAll(description, `[[[${key}]]]`, `<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}" >`);
406
+ }
407
+ displayForm = `${prepend}<div class="boxy">${description}</div>${information}${append}`;
408
+ break;
409
+
410
+ case "ide_editor" :
411
+ displayForm = `<div class="ide_editor" id="editor_${obj.id}"></div>`
412
+ displayForm += `<textarea hidden ${classview} ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4"></textarea>${information}${append}`;
413
+ break;
414
+
415
+ case "json" :
416
+ displayForm += `<textarea ${classview} ${id} ${name} ${placeholder} ${readonly} ${style} ${htmlOptions} rows="4">${JSON.stringify(obj.value)}</textarea>${information}${append}`;
417
+ break;
418
+
419
+ case "virtual" :
420
+ displayForm = `${prepend}<input autocomplete="off" autofocus="" ${tabindex} ${style} type="text" ${classview} readonly ${id} ${placeholder} ${required} value="${value}" ${htmlOptions}>${information}${append}`;
421
+ break;
422
+
423
+ //additionals for form view in view
424
+ case "plaintext" :
425
+ displayForm = `<span class="">${obj.value || ""}</span>`;
426
+ break;
427
+
428
+ case "div" :
429
+ displayForm = `<div id="${obj.id}" class="${obj.class}">${obj.value}</div>`
430
+ break;
431
+
432
+ case "data_table" :
433
+ displayForm = obj.html;
434
+ break;
435
+
436
+ default :
437
+ displayForm = `${prepend}${inputGroupLeft}<input ${disabled} autocomplete="nope" autofocus="" ${readonly} ${tabindex} type="${type}" ${classview} ${id} ${name} ${placeholder} ${required} value="${value}" data-t="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
438
+ break;
439
+ }
440
+
441
+ return displayForm;
442
+ };
443
+
444
+ Form.group = (name, label, field) => {
445
+ return `<div class="form-group div${name} mb-3">${label}${field}</div>`;
446
+ };
447
+
448
+ Form.button = (optionsExtends = {}) => {
449
+ let options = Form.options.button;
450
+ let htmlOptions = "";
451
+ for (let key in optionsExtends) {
452
+ let val = optionsExtends[key];
453
+ val = Util.replaceAll(val, '"', "");
454
+ if (options.hasOwnProperty(key)) {
455
+ options[key] = optionsExtends[key]
456
+ } else {
457
+ htmlOptions += ` ${key}=${val} `;
458
+ }
459
+ }
460
+ return `<button id="${options.id}" type="${options.type}" class="${options.class}" ${htmlOptions}>${options.label}</button>`;
461
+ };
462
+
463
+ Form.buttonGroup = (buttons = []) => {
464
+ let html = `<div class="btn-group" role="group" aria-label="...">`;
465
+ html += buttons.join(" ");
466
+ html += `</div>`;
467
+ return html;
468
+ };
469
+
470
+ Form.submit = (optionsExtends = {}) => {
471
+ let options = {
472
+ id: "form-submit",
473
+ type: "submit",
474
+ class: "btn btn btn-success boxy image-button ",
475
+ label: `<img src="/assets/icons/send.svg" class="icons-bg-white" > <span>${LANGUAGE['submit']}</span>`
476
+ };
477
+ let settings = {...options, ...optionsExtends}
478
+ return Form.button(settings);
479
+ };
480
+
481
+ Form.pullRight = (frameworkcss) => {
482
+ if (frameworkcss == "bootstrap3") {
483
+ return "pull-right";
484
+ } else if (frameworkcss == "bootstrap4") {
485
+ return "float-right";
486
+ } else {
487
+ return "float-end"
488
+ }
489
+ };
490
+
491
+ Form.breadcrumb = (type, arr) => {
492
+ let html = `<nav style="--bs-breadcrumb-divider: url(&#34;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='currentColor'/%3E%3C/svg%3E&#34;);" aria-label="breadcrumb"><ol class="breadcrumb float-end">`;
493
+ arr.map((item) => {
494
+ if (item.active == true) {
495
+ html += `<li class="breadcrumb-item active" aria-current="page">${item.text}</li>`;
496
+ } else {
497
+ html += `<li class="breadcrumb-item"><a href="${item.href}">${item.text}</a></li>`;
498
+ }
499
+ });
500
+ html += `</ol></nav>`;
501
+ return html;
502
+ };
503
+
504
+ Form.grid = (type, obj) => {
505
+ return gridBootstrap5(obj);
506
+ };
507
+
508
+ /*
509
+ tab property
510
+ label,active,content,headerOptions
511
+ */
512
+ Form.tab = (type, obj) => {
513
+ return tabBootstrap5(obj);
514
+ };
515
+
516
+ Form.card = (type, obj) => {
517
+ return card45(obj);
518
+ };
519
+
520
+ //card 4 & 5 bootstrap
521
+ const card45 = (obj) => {
522
+ let html = obj.prepend;
523
+ let objHeader = obj.headerOptions || {}
524
+ let headerOptions = obj.headerOptions ? addProperties(obj.headerOptions, {class: "card"}) : addProperties({class: "card"});
525
+ let img = obj.img ? `<img ${addProperties(obj.img)} >` : "";
526
+ let title = `<div class="card-header"><h5 class="card-title">${obj.title}</h5></div>`;
527
+ let footer = obj.footer = obj.footer ? `<div class="card-footer">${obj.footer}</div>` : ``;
528
+ let append = !obj.append ? "" : obj.append;
529
+ html += `<div ${headerOptions}>
530
+ ${img}
531
+ ${title}
532
+ <div class="card-body">
533
+ ${obj.body}
534
+ </div>
535
+ ${footer}
536
+ </div>`;
537
+
538
+ html += append;
539
+ return html;
540
+ };
541
+
542
+ const cardBootstrap5 = (obj) => {
543
+ return `${obj.prepend}<div class="card div${obj.id}">
544
+ <div class="card-content">
545
+ <div class="card-body">
546
+ <div class="card-title">${obj.title}</div>
547
+ <div class="table-responsive">
548
+ <table id="table${obj.id}" class="table">
549
+ <thead>
550
+ <tr>
551
+ ${obj.html}
552
+ ${obj.btnAdd}
553
+ </tr>
554
+ </thead>
555
+ <tbody id="body-${obj.id}" data-value='${obj.value}'>${obj.table}</tbody>
556
+ </table>
557
+ </div>
558
+ </div>
559
+ </div>
560
+ </div>`;
561
+ }
562
+
563
+ const gridBootstrap5 = (obj) => {
564
+ let levels = obj.levels;
565
+ let routeName = obj.routeName;
566
+ let advanceSearch = !obj.advanceSearch ? "" : obj.advanceSearch;
567
+ let createBtn = "", exportBtn = "", importBtn = "", superBtn = '', exportBtnGroup = "", selectPagesize = "";
568
+ if (levels.create) {
569
+ createBtn = `<button type="button" id="create_btn" class="btn btn-success btn-xs"><i class="fa fa-plus white-icon"></i></button>`;
570
+ }
571
+ if (levels.export) {
572
+ exportBtn = `<button type="button" id="backupExcel" class="btn btn-info btn-xs" title="${obj.LANGUAGE['download_excel']}"><i class="fas fa-file-excel"></i></button>`;
573
+
574
+ exportBtnGroup = `<div class="btn-group" role="group">
575
+ <button id="dropdownExport" type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
576
+ ${obj.LANGUAGE['grid_export_data']}
577
+ </button>
578
+ <div class="dropdown-menu" aria-labelledby="dropdownExport">
579
+ <a class="dropdown-item export-xls" href="#"><i class="text-success fa fa-file-excel-o"></i> Excel </a>
580
+ <a class="dropdown-item export-pdf" href="#"><i class="text-danger fa fa-file-pdf-o"></i> PDF </a>
581
+ </div>
582
+ </div>`;
583
+ }
584
+ if (levels.import) {
585
+ importBtn = `<button type="button" id="importExcel" class="btn btn-warning btn-xs" title="<%- LANGUAGE['data_import'] %>"><i class="fas fa-file-import"></i></button>`;
586
+ }
587
+ selectPagesize = `<div class="dropdown-menu" aria-labelledby="dropdownPagination">`;
588
+ let pageSize = obj.gridFilters.pageSize || 20;
589
+
590
+ for (var i = 0; i < obj.paginationApp.length; i++) {
591
+ var actived = pageSize == obj.paginationApp[i] ? " active " : "";
592
+ selectPagesize += `<a data-value="${obj.paginationApp[i]}" class="dropdown-item pageSizeGrid ${actived}" id="pagination${obj.paginationApp[i]}" href="#" >${obj.paginationApp[i]}</a>`;
593
+ }
594
+ selectPagesize += `</div>`;
595
+
596
+ let toolbarDefault = `<div class="float">
597
+ <div class="btn-group float-end" role="group" aria-label="Button group with nested dropdown">
598
+ ${createBtn}
599
+ ${exportBtn}
600
+ ${importBtn}
601
+ <button type="button" class="btn btn-secondary btn-xs" title="${LANGUAGE['grid_personalize_labeling']}" data-bs-toggle="modal" data-bs-target="#grid-labels" ><i class="fa fa-font"></i></button>
602
+ <button type="button" class="btn btn-info btn-xs" title="${LANGUAGE['grid_personalize_setting']}" data-bs-toggle="modal" data-bs-target="#grid-modal"><i class="fa fa-cog"></i></button>
603
+ <button type="button" id="reloadgrid" class="btn btn-default btn-xs" title="${LANGUAGE['grid_refresh']}"><i class="fas fa-redo"></i></button>
604
+ <div class="btn-group" role="group">
605
+ <button id="dropdownPagination" type="button" class="btn btn-info dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
606
+ Pagination ${pageSize}
607
+ </button>
608
+ ${selectPagesize}
609
+ </div>
610
+
611
+ <div class="btn-group" role="group">
612
+ <button id="dropdownExport" type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
613
+ ${obj.LANGUAGE['grid_export_data']}
614
+ </button>
615
+ <div class="dropdown-menu" aria-labelledby="dropdownExport">
616
+ <a class="dropdown-item export-xls" href="#"><i class="text-success fa fa-file-excel-o"></i> Excel </a>
617
+ <a class="dropdown-item export-pdf" href="#"><i class="text-danger fa fa-file-pdf-o"></i> PDF </a>
618
+ </div>
619
+ </div>
620
+
621
+ </div></div>`;
622
+ let toolbar = obj.toolbar ? obj.toolbar : toolbarDefault;
623
+ let html = '';
624
+ html += `<div class="card">
625
+ <div class="card-body">
626
+ <div class="float-end">
627
+ <div class="summary"></div>
628
+ </div>
629
+ <div class="card-title"><i class="fa fa-book"></i> ${obj.header}</div>
630
+ <div class="row">
631
+ ${toolbar}
632
+ <div style="padding-top: 7px;"><a href="#" class="open_advancesearch"> Advance Search</a></div>
633
+ ${advanceSearch}
634
+ </div>
635
+
636
+ <input type="hidden" id="pageSize" value="${pageSize}">
637
+ <div class="table-responsive pt-3 row">
638
+ <div id="jsGrid" class="table-responsive"></div>
639
+ </div>
640
+ </div>
641
+ </div>`;
642
+ return html;
643
+ };
644
+
645
+
646
+ const tabBootstrap5 = (arr = []) => {
647
+ let html = "";
648
+ html += `<ul class="nav nav-tabs" id="myTab" role="tablist">${Util.newLine}`;
649
+ arr.forEach(function (item, index) {
650
+ var active = "", selected = "false";
651
+ if (item.active) {
652
+ active = "active";
653
+ selected = "true";
654
+ }
655
+ html += `${Util.tab}
656
+ <li class="nav-item" role="presentation" >
657
+ <button class="nav-link ${active}" id="tab${index}" data-bs-toggle="tab" data-bs-target="#arr${index}" type="button" role="tab" aria-controls="arrtab${index}" aria-selected="true">${item.label}</button>
658
+ </li>${Util.newLine}`;
659
+ });
660
+ html += `</ul>`;
661
+ return {
662
+ html: html,
663
+ class: "tab-pane fade",
664
+ active: "show active"
665
+ };
666
+ };
667
+
668
+ Form.build = (obj) => {
669
+ let html = '';
670
+ let required = !obj.required ? "" : `<span class="required-mark">*</span>`;
671
+ let relation = "";
672
+ //form float
673
+ let float = false;
674
+ let inline = false;
675
+ let attributes = Object.prototype.hasOwnProperty.call(obj,"attributes") ? obj.attributes : {};
676
+ let view_only = Object.prototype.hasOwnProperty.call(obj,'view_only') ? obj.view_only : false;
677
+ if(!view_only) {
678
+ if (attributes && Object.prototype.hasOwnProperty.call(attributes, "name")) {
679
+ if(obj.attributes.name == "relation") {
680
+ relation = `<a target="_blank" href="/${obj.attributes.table}"> > </a>`
681
+ }
682
+ }
683
+ }
684
+
685
+ if (attributes && Object.prototype.hasOwnProperty.call(attributes, "float")) {
686
+ float = obj.attributes.float || false;
687
+ }
688
+ if (attributes && Object.prototype.hasOwnProperty.call(attributes, "inline")) {
689
+ inline = obj.attributes.inline || false;
690
+ }
691
+
692
+ if(float) {
693
+ //obj.class = "nice-float"
694
+ if(obj.type == "checkbox") {
695
+ html += `<div class="form-switch mx-auto div${obj.id} mb-3">${Form.field(obj)}<label class="form-check-label" for="">${obj.id} ${required}</label></div>`;
696
+ } else {
697
+ html += `<div class="form-floating mx-auto mb-3 mt-3 div${obj.id} mb-3">${Form.field(obj)}<label for="${obj.id}">${obj.title} ${required} ${relation}</label></div>`;
698
+ }
699
+ } else {
700
+ if(inline) {
701
+ if(obj.type == "checkbox") {
702
+ html += ` <div class="mb-3 row"><label for="${obj.id}" class="col form-check-label">${obj.title} ${obj.labelOptions} ${required} ${relation}</label><div class="col-8">${Form.field(obj)}</div></div>`
703
+ } else {
704
+ html += ` <div class="mb-3 row"><label for="${obj.id}" class="col col-form-label">${obj.title} ${obj.labelOptions} ${required} ${relation}</label><div class="col-8">${Form.field(obj)}</div></div>`
705
+ }
706
+ } else {
707
+ if(obj.type == "checkbox") {
708
+ html += `<div class="form-check div${obj.id} mb-3">${Form.field(obj)}<label class="form-check-label" for="${obj.id}">${obj.title} ${obj.labelOptions} ${required}</label></div>`;
709
+ } else {
710
+ html += `<div class="form-group div${obj.id} mb-3"><label for="${obj.id}">${obj.title} ${obj.labelOptions} ${required} ${relation}</label>${Form.field(obj)}</div>`;
711
+ }
712
+ }
713
+ }
714
+ return html;
715
+ };
716
+
717
+ module.exports = Form;