zet-lib 1.3.38 → 1.3.40

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/moduleLib.js CHANGED
@@ -1,661 +1,661 @@
1
- const Util = require('./Util')
2
- const newLine = Util.newLine
3
-
4
- const m = {}
5
-
6
- //module for ide code editor
7
- m.ideCDN = function (req, res) {
8
- let script = ''
9
- let head = ``
10
- let end = ``
11
- end += `<script src="/modules/ace.js"></script>${Util.newLine}`
12
-
13
- return {
14
- head: head,
15
- end: end,
16
- script: script,
17
- }
18
- }
19
-
20
- m.ide = function (req, res, elem) {
21
- let script = ''
22
- let head = ``
23
- let end = ``
24
- elem = elem || '#ide_editor'
25
- end += `<script> var editor_${elem} = ace.edit("${elem}");
26
- editor_${elem}.getSession().setMode("ace/mode/ejs");
27
- </script> ${Util.newLine}`
28
- return {
29
- head: head,
30
- end: end,
31
- script: script,
32
- }
33
- }
34
-
35
- m.tags = function (req, res, elem) {
36
- let script = ''
37
- let head = ``
38
- let end = ``
39
- elem = elem || '.tags'
40
- end += `<script type="module">import Tags from "/modules/tags.js";Tags.init("${elem}");</script>`
41
- return {
42
- head: head,
43
- end: end,
44
- script: script,
45
- }
46
- }
47
- //module for datepicker
48
- m.datepicker = function (req, res, elem) {
49
- let script = ''
50
- let head = ``
51
- let end = ``
52
- elem = elem || '.datepicker'
53
- /* head += '<link href="/css/bootstrap-datepicker.css" rel="stylesheet">';
54
- end += '<script src="/js/bootstrap-datepicker.min.js"></script>';*/
55
- head += '<link href="/modules/bootstrap-datepicker/bootstrap-datepicker.min.css" rel="stylesheet">'
56
- end += '<script src="/modules/bootstrap-datepicker/bootstrap-datepicker.min.js"></script>'
57
- script = `$.fn.datepicker.defaults.format = "yyyy-mm-dd";$.fn.datepicker.defaults.todayHighlight = true;$("body").on("click", "${elem}", function(){$(this).datepicker();$(this).datepicker("show");});`
58
-
59
- return {
60
- head: head,
61
- end: end,
62
- script: script,
63
- }
64
- }
65
-
66
- //module for selectize
67
- //https://selectize.dev
68
- //https://github.com/selectize/selectize.js
69
- m.selectize = function (req, res, elem) {
70
- let script = ''
71
- let head = ``
72
- let end = ``
73
- elem = elem || '.selectize'
74
- head += '<link href="/modules/selectizejs/css/selectize.bootstrap5.css" rel="stylesheet">'
75
- end += '<script src="/modules/selectizejs/js/selectize.min.js"></script>'
76
-
77
- script += `$(() => {
78
- $('${elem}').selectize({
79
- sortField: 'text'
80
- });
81
- });`
82
-
83
- return {
84
- head: head,
85
- end: end,
86
- script: script,
87
- }
88
- }
89
-
90
- //module for dropzone
91
- m.dropzone = function (req, res, elem) {
92
- let script = ''
93
- let head = ``
94
- let end = ``
95
- elem = elem || '.dropzone'
96
- head += '<link href="/modules/dropzone/dropzone.css" rel="stylesheet">'
97
- end += '<script src="/modules/dropzone/dropzone.min.js"></script>'
98
-
99
- return {
100
- head: head,
101
- end: end,
102
- script: script,
103
- }
104
- }
105
-
106
- //module for dragdrop
107
- m.dragdrop = function (req, res, elem) {
108
- let script = ''
109
- let head = ``
110
- let end = ``
111
- head += '<link href="/modules/drag/drag.css" rel="stylesheet">'
112
- end += '<script src="/modules/drag/jquery-sortable.js"></script>'
113
- script += `$(function () {
114
- $("ol.mydragable${elem}").sortable({
115
- group: 'mydragable${elem}',
116
- isValidTarget: function ($item, container) {
117
- return true;
118
- },
119
- onDrop: function ($item, container, _super) {
120
- var getidname = $item.parents().attr('id') || "";
121
- var iname = $item.find('input[type=text]').attr('data-name');
122
- var containertype = $item.parents().data('type');
123
- var containername = $item.parents().data('name');
124
- var newname = getidname ? iname + "___" + getidname : iname;
125
- $item.find('input[type=text]').attr('name', newname);
126
- $item.find('input[type=hidden]').attr('name', containername);
127
- $item.find('button').addClass(containertype == "left" ? "btn-primary" : "btn-danger");
128
- $item.find('button').removeClass(containertype == "right" ? "btn-primary" : "btn-danger");
129
- _super($item, container);
130
- }
131
- });
132
- });
133
-
134
- `
135
- return {
136
- head: head,
137
- end: end,
138
- script: script,
139
- }
140
- }
141
-
142
- //module for google map
143
- m.location = function (req, res, key) {
144
- let script = ``
145
- let head = ``
146
- let end = ``
147
- end += `<script src="https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_KEY}&callback=initAutocompleteZmap&libraries=places&language=ID" defer></script>`
148
- script += `let searchAddressMap;
149
- let autocompleteMap;
150
- function initAutocompleteZmap() {
151
- if(mapLocationJSON && mapLocationJSON.lat) {
152
- $("#search_map_location").val(mapLocationJSON.address1);
153
- initMap(mapLocationJSON.lat,mapLocationJSON.lon);
154
- } else {
155
- navigator.geolocation.getCurrentPosition(function(location) {
156
- initMap(location.coords.latitude,location.coords.longitude);
157
- $("#search_map_location").val("My Place");
158
- });
159
- }
160
- searchAddressMap = document.querySelector("#search_map_location");
161
- autocompleteMap = new google.maps.places.Autocomplete(searchAddressMap, {
162
- componentRestrictions: {country: ["ID"]},
163
- fields: ["address_component", "geometry"],
164
- });
165
- searchAddressMap.focus();
166
- autocompleteMap.addListener("place_changed", fillInAddress);
167
- }
168
-
169
- function fillInAddress() {
170
- const place = autocompleteMap.getPlace();
171
- let lat = place.geometry.location.lat();
172
- let lon = place.geometry.location.lng();
173
- initMap(lat, lon);
174
- mapLocationJSON = {
175
- lat:lat,
176
- lon:lon,
177
- address1: $("#search_map_location").val(),
178
- address2:place.address_components,
179
- }
180
- setAddress();
181
- }
182
- function setAddress() {
183
- $("#${key}").val(JSON.stringify(mapLocationJSON));
184
- }
185
- function initMap(lat, lon) {
186
- let position = {lat: lat, lng: lon}
187
- const map = new google.maps.Map(document.getElementById("map_${key}"), {
188
- zoom: 13,
189
- center: position,
190
- draggable: true
191
- });
192
- var marker;
193
- placeMarker(position, map);
194
- var infowindow = new google.maps.InfoWindow();
195
- function placeMarker(position, map) {
196
- marker = new google.maps.Marker({
197
- position: position,
198
- map: map,
199
- draggable: true,
200
- animation: google.maps.Animation.DROP,
201
- });
202
- map.panTo(position);
203
- }
204
- google.maps.event.addListener(marker, 'dragend', function () {
205
- geocodePosition(marker.getPosition());
206
- });
207
- google.maps.event.addListener(marker, 'click', function() {
208
- infowindow.setContent($("#search_map_location").val());
209
- infowindow.open(map, this)
210
- });
211
- function geocodePosition(pos) {
212
- mapLocationJSON.lat=pos.lat();
213
- mapLocationJSON.lon=pos.lng();
214
- var geocoder = new google.maps.Geocoder();
215
- geocoder.geocode
216
- ({
217
- latLng: pos
218
- },
219
- function (results, status) {
220
- if (status == google.maps.GeocoderStatus.OK) {
221
- $("#search_map_location").val(results[0].formatted_address);
222
- $("#mapErrorMsg").hide(100);
223
- mapLocationJSON.address2=results[0].formatted_address;
224
- mapLocationJSON.address1=$("#search_map_location").val();
225
- setAddress();
226
- } else {
227
- $("#mapErrorMsg").html('Cannot determine address at this location.' + status).show(100);
228
- }
229
- }
230
- );
231
- }
232
- }`
233
- return {
234
- head: head,
235
- end: end,
236
- script: script,
237
- }
238
- }
239
-
240
- //module for datepicker
241
- m.datetimepicker = function (req, res, elem) {
242
- let script = ''
243
- let head = ``
244
- let end = ``
245
- elem = elem || '.datetimepicker'
246
- head += '<link href="/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />'
247
- end += '<script type="text/javascript" src="/js/moment-with-locales.min.js" ></script>'
248
- end += '<script type="text/javascript" src="/js/bootstrap-datetimepicker.min.js" ></script>'
249
- script += `$(function () { $("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'}); });`
250
- script += `setTimeout(function () { $("body").click();},1000);`
251
- script += `$("body").on("click", function(){$("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'});});`
252
-
253
- return {
254
- head: head,
255
- end: end,
256
- script: script,
257
- }
258
- }
259
-
260
- //using ckeditor
261
- m.ckeditor = function (req, res, elem) {
262
- let script = ''
263
- let head = ``
264
- let end = ``
265
- elem = elem || '.editor'
266
- end += '<script src="/modules/ckeditor5-build-classic/ckeditor.js"></script>' + newLine
267
- end += '<script>'
268
- end += 'ClassicEditor.create( document.querySelector( "' + elem + '" ) ).catch( error => {console.error( error );} );' + newLine
269
- end += '</script>'
270
- return {
271
- head: head,
272
- end: end,
273
- script: script,
274
- }
275
- }
276
-
277
- //using tinymce
278
- m.tinymce = function (req, res, elem) {
279
- let script = ''
280
- let head = ``
281
- let end = ``
282
- elem = elem || '.tinymce'
283
- end += '<script src="https://cdn.tiny.cloud/1/b7054u42l8lw67ch5oh9qutnvbyu8exzryg4edy0gg2snhtr/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>' + newLine
284
- script += ` tinymce.init({
285
- selector: '${elem}',
286
- plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount',
287
- toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table | align lineheight | numlist bullist indent outdent | emoticons charmap | removeformat',
288
- });`
289
- return {
290
- head: head,
291
- end: end,
292
- script: script,
293
- }
294
- }
295
-
296
- //using froala
297
- m.froala = function (req, res, elem) {
298
- let script = ''
299
- let head = ``
300
- let end = ``
301
- elem = elem || '.editor'
302
-
303
- head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />'
304
- head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />'
305
- end += '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>'
306
- script += `$(function() {$("${elem}").froalaEditor({height: 200})});`
307
-
308
- return {
309
- head: head,
310
- end: end,
311
- script: script,
312
- }
313
- }
314
-
315
- m.lexical = function (req, res, elem) {
316
- let script = ''
317
- let head = ``
318
- let end = ``
319
- elem = elem || '.editor'
320
- head += `<link rel="stylesheet" href="/assets/main.143ecbc6.css">`
321
- end += `<script type="module" crossorigin src="/assets/main.3be493b7.js"></script>`
322
- return {
323
- head: head,
324
- end: end,
325
- script: script,
326
- }
327
- }
328
-
329
- //Default editor is froala
330
- m.editor = (req, res, elem = '') => {
331
- elem = elem || '.editor'
332
- //Default editor is froala
333
- //return m.froala(req, res, elem);
334
- //return m.tinymce(req, res, elem);
335
- //return m.ckeditor(req, res, elem);
336
- //return m.lexical(req,res,elem);
337
-
338
- let script = ''
339
- let head = ``
340
- let end = ``
341
-
342
- head += '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.4.2/css/all.min.css" integrity="sha512-NicFTMUg/LwBeG8C7VG+gC4YiiRtQACl98QdkmfsLy37RzXdkaUAuPyVMND0olPP4Jn8M/ctesGSB2pgUBDRIw==" crossorigin="anonymous" referrerpolicy="no-referrer" />'
343
- head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />'
344
- head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />'
345
- end += '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>'
346
- script += `$(function() {$("${elem}").froalaEditor({height: 200})});`
347
-
348
- return {
349
- head: head,
350
- end: end,
351
- script: script,
352
- }
353
- }
354
-
355
- m.switch = function (req, res, elem, array) {
356
- elem = elem || '.switch'
357
- let script = ''
358
- let head = ``
359
- let end = ``
360
-
361
- head += '<link href="/modules/bootstrap-switch/bootstrap-switch.css" rel="stylesheet" type="text/css" />' + newLine
362
- end += '<script type="text/javascript" src="/modules/bootstrap-switch/bootstrap-switch.js"></script>' + newLine
363
-
364
- let labels = ''
365
- if (Array.isArray(array)) {
366
- labels = '{offText:"' + array[0] + '", onText:"' + array[1] + '"}'
367
- }
368
- script += '$("' + elem + '").bootstrapSwitch(' + labels + ');' + newLine
369
- return {
370
- head: head,
371
- end: end,
372
- script: script,
373
- }
374
- }
375
-
376
- m.switchOld = function (req, res, elem, array) {
377
- let script = ''
378
- let head = ``
379
- let end = ``
380
- elem = elem || '.switch'
381
- head += '<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">' + newLine
382
- end += '<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>' + newLine
383
-
384
- let labels = ''
385
- if (Array.isArray(array)) {
386
- labels = '{off:"' + array[0] + '", on:"' + array[1] + '"}'
387
- }
388
- script += `$(function(){$('${elem}').bootstrapToggle(${labels});});${Util.newLine}`
389
-
390
- return {
391
- head: head,
392
- end: end,
393
- script: script,
394
- }
395
- }
396
-
397
- m.clockpicker = function (req, res, elem) {
398
- let script = ''
399
- let head = ``
400
- let end = ``
401
- elem = elem || '.clockpicker'
402
- head += '<link href="/modules/jquery-clockpicker.min.css" rel="stylesheet" type="text/css" />' + newLine
403
- end += '<script type="text/javascript" src="/modules/bootstrap-clockpicker.min.js"></script>' + newLine
404
- script += `$("body").on("click", "${elem}", function(){$(this).clockpicker({donetext: "Done"});});`
405
- //end += '$("' + elem + '").clockpicker({donetext: "Done"});' + newLine;
406
- return {
407
- head: head,
408
- end: end,
409
- script: script,
410
- }
411
- }
412
-
413
- m.number = (req, res, elem) => {
414
- let script = ''
415
- let head = ``
416
- let end = ``
417
- elem = elem || '.number'
418
-
419
- end += '<script type="text/javascript" src="/js/jquery-currency.js"></script>'
420
- script += `$(function () { $(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."}); });`
421
- script += `setTimeout(function () { $("body").click();},1000);`
422
- script += `$("body").on("click", function(){$(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."});});`
423
-
424
- return {
425
- head: head,
426
- end: end,
427
- script: script,
428
- }
429
- }
430
-
431
- m.typeahead = (req, res, table, elem) => {
432
- let script = ''
433
- let head = ``
434
- let end = ``
435
- elem = elem || '.typeahead'
436
- end += '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' + newLine
437
-
438
- let elemData = elem.replace('.', '').replace('#', '')
439
- let element = elem.replace('Typeahead', '')
440
- let key = element.replace('#', '').replace('.', '')
441
- // var script using existing cache
442
- script += `$("body").on("click", "${element}Clear", function(){
443
- $("${elem}").val("");
444
- $("${element}").val("");
445
- $("${element}").change();
446
- });${Util.newLine}`
447
- script += `$("${elem}").typeahead({highlight:true,minLength:2,source: function (query, asyncprocess) {
448
- jQuery.ajax({
449
- url : "/ztypeahead/${table}/${key}",
450
- type : 'GET',
451
- data : {
452
- "query" : query
453
- },
454
- dataType : 'json',
455
- success : function(json) {
456
- asyncprocess(json);
457
- }
458
- });
459
- }, items: 50, displayText: function (item) {
460
- return item.zname.toString();
461
- },
462
- updater:function (item) {
463
- $("${element}").val(item.id);
464
- $("${element}").change();
465
- return item;
466
- }
467
- }); ${Util.newLine}`
468
- return {
469
- head: head,
470
- end: end,
471
- script: script,
472
- }
473
- }
474
-
475
- m.typeaheadFile = (req, res, elem, data) => {
476
- let script = ''
477
- let head = ``
478
- let end = ``
479
- data = data || []
480
- elem = elem || '.typeahead'
481
- end += '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' + newLine
482
-
483
- let elemData = elem.replace('.', '')
484
- elemData = elemData.replace('#', '')
485
- let element = elem.replace('Typeahead', '')
486
- // var script using existing cache
487
- script += `$("body").on("click", "${element}Clear", function(){
488
- $("${elem}").val("");
489
- $("${element}").val("");
490
- $("${element}").change();
491
- });${Util.newLine}`
492
- script += `$("${elem}").typeahead({highlight: true,minLength:2,source:${elemData}Data, items: 50, displayText: function (item) {
493
- return item.zname.toString();
494
- },
495
- updater:function (item) {
496
- $("${element}").val(item.id);
497
- $("${element}").change();
498
- return item;
499
- }
500
- }); ${Util.newLine}`
501
- return {
502
- head: head,
503
- end: end,
504
- script: script,
505
- }
506
- }
507
-
508
- m.custom = (req, res, script, css, src) => {
509
- src = src || ''
510
- css = css || ''
511
- let head = res.locals.moduleHead
512
- let end = res.locals.moduleEnd
513
- if (script) {
514
- end += '<script>' + newLine
515
- end += script + newLine
516
- end += '</script>' + newLine
517
- }
518
- if (css) {
519
- head += css
520
- }
521
- if (src) {
522
- end += `<script src="${src}"> ${newLine}`
523
- }
524
- res.locals.moduleHead = head
525
- res.locals.moduleEnd = end
526
- }
527
-
528
- m.script = (req, res, table) => {}
529
-
530
- /*
531
- add scrip code in the body html
532
- end in the bottom html body (javascript) default
533
- top in the top html body (css)
534
-
535
- type : script / css
536
- */
537
- m.addScript = (req, res, contentScript, at = 'end', type = 'script') => {
538
- if (contentScript) {
539
- let generateId = 'app_' + Util.generate(6)
540
- let tagOpen = type == 'script' ? `<script id="${generateId}">` : '<style type="text/css">'
541
- let tagClose = type == 'script' ? '</script>' : '</style>'
542
- let content = at == 'end' ? res.locals.moduleEnd : res.locals.moduleHead
543
- content += tagOpen + newLine
544
- content += contentScript + newLine
545
- content += tagClose + newLine
546
-
547
- if (at == 'end') {
548
- res.locals.moduleEnd = content
549
- } else res.locals.moduleHead = content
550
- }
551
- }
552
-
553
- m.addModule = (req, res, content, isModuleHead = false) => {
554
- let moduleContent = isModuleHead ? res.locals.moduleHead : res.locals.moduleEnd
555
- moduleContent += content
556
- if (isModuleHead) {
557
- res.locals.moduleHead = moduleContent
558
- } else {
559
- res.locals.moduleEnd = moduleContent
560
- }
561
- }
562
-
563
- m.highchart = async (req, res, obj) => {
564
- obj = obj || {}
565
- let head = res.locals.moduleHead
566
- let end = res.locals.moduleEnd
567
- if (end.indexOf('highcharts') < 0) {
568
- end += '<script src="https://code.highcharts.com/highcharts.js"></script>' + newLine
569
- }
570
-
571
- if (!Util.isEmptyObject(obj)) {
572
- const highcharts = require('./highcharts')
573
- end += '<script>' + newLine
574
- end += await highcharts.build(obj)
575
- end += '</script>' + newLine
576
- }
577
-
578
- res.locals.moduleHead = head
579
- res.locals.moduleEnd = end
580
- }
581
-
582
- //build auto js and css based on function type
583
- m.build = (req, res, objData) => {
584
- let head = res.locals.moduleHead
585
- let end = res.locals.moduleEnd
586
-
587
- head += objData.head
588
- end += objData.end
589
- if (objData.script) {
590
- end += `<script>${objData.script}</script>`
591
- }
592
- res.locals.moduleHead = head
593
- res.locals.moduleEnd = end
594
- }
595
-
596
- m.tableForm = (req, res, name, table) => {
597
- let head = res.locals.moduleHead
598
- let end = res.locals.moduleEnd
599
- res.locals.moduleHead = head
600
- res.locals.moduleEnd = end
601
- }
602
-
603
- m.selectYear = (req, res, elem, val, startYear, endYear) => {
604
- let dt = new Date()
605
- endYear = endYear || dt.getFullYear()
606
- val = val || ''
607
- var options = ''
608
- for (var i = endYear; i >= startYear; i--) {
609
- var selected = i == val ? ' selected ' : ''
610
- options += `<option value="${i}" ${selected}>${i}</option>`
611
- }
612
- let end = res.locals.moduleEnd
613
- end += '<script>' + newLine
614
- end += `$("${elem}").html('${options}')`
615
- end += '</script>' + newLine
616
- res.locals.moduleEnd = end
617
- }
618
-
619
- //https://highlightjs.org/usage/
620
- m.highlight = (req, res, elem) => {
621
- elem = elem || '.codes'
622
- let head = res.locals.moduleHead
623
- let end = res.locals.moduleEnd
624
- if (head.indexOf('highlight') < 0) {
625
- head += '<link rel="stylesheet" href="/modules/highlight/default.min.css"> ' + newLine
626
- end += '<script src="/modules/highlight/highlight.min.js"></script>' + newLine
627
- }
628
- end += '<script>$(function(){ document.querySelectorAll("' + elem + '").forEach((block) => {hljs.highlightBlock(block);}); })</script>' + newLine
629
- res.locals.moduleHead = head
630
- res.locals.moduleEnd = end
631
- }
632
-
633
- //https://developer.snapappointments.com/bootstrap-select/
634
- m.selectpicker = function (req, res, elem) {
635
- elem = elem || '.selectpicker'
636
- let head = res.locals.moduleHead
637
- let end = res.locals.moduleEnd
638
- if (head.indexOf('bootstrap-select') < 0) {
639
- head += '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">' + newLine
640
- end += '<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>' + newLine
641
- end += `<script>$(function () {$('${elem}').selectpicker();});</script>${newLine}`
642
- }
643
- res.locals.moduleHead = head
644
- res.locals.moduleEnd = end
645
- }
646
-
647
- m.slugHTML = (req, res, content, at = 'end') => {
648
- if (content) {
649
- let head = res.locals.moduleHead
650
- let end = res.locals.moduleEnd
651
- if (at == 'end') {
652
- end += content
653
- res.locals.moduleEnd = end
654
- } else {
655
- head += content
656
- res.locals.moduleHead = head
657
- }
658
- }
659
- }
660
-
661
- module.exports = m
1
+ const Util = require('./Util')
2
+ const newLine = Util.newLine
3
+
4
+ const m = {}
5
+
6
+ //module for ide code editor
7
+ m.ideCDN = function (req, res) {
8
+ let script = ''
9
+ let head = ``
10
+ let end = ``
11
+ end += `<script src="/modules/ace.js"></script>${Util.newLine}`
12
+
13
+ return {
14
+ head: head,
15
+ end: end,
16
+ script: script,
17
+ }
18
+ }
19
+
20
+ m.ide = function (req, res, elem) {
21
+ let script = ''
22
+ let head = ``
23
+ let end = ``
24
+ elem = elem || '#ide_editor'
25
+ end += `<script> var editor_${elem} = ace.edit("${elem}");
26
+ editor_${elem}.getSession().setMode("ace/mode/ejs");
27
+ </script> ${Util.newLine}`
28
+ return {
29
+ head: head,
30
+ end: end,
31
+ script: script,
32
+ }
33
+ }
34
+
35
+ m.tags = function (req, res, elem) {
36
+ let script = ''
37
+ let head = ``
38
+ let end = ``
39
+ elem = elem || '.tags'
40
+ end += `<script type="module">import Tags from "/modules/tags.js";Tags.init("${elem}");</script>`
41
+ return {
42
+ head: head,
43
+ end: end,
44
+ script: script,
45
+ }
46
+ }
47
+ //module for datepicker
48
+ m.datepicker = function (req, res, elem) {
49
+ let script = ''
50
+ let head = ``
51
+ let end = ``
52
+ elem = elem || '.datepicker'
53
+ /* head += '<link href="/css/bootstrap-datepicker.css" rel="stylesheet">';
54
+ end += '<script src="/js/bootstrap-datepicker.min.js"></script>';*/
55
+ head += '<link href="/modules/bootstrap-datepicker/bootstrap-datepicker.min.css" rel="stylesheet">'
56
+ end += '<script src="/modules/bootstrap-datepicker/bootstrap-datepicker.min.js"></script>'
57
+ script = `$.fn.datepicker.defaults.format = "yyyy-mm-dd";$.fn.datepicker.defaults.todayHighlight = true;$("body").on("click", "${elem}", function(){$(this).datepicker();$(this).datepicker("show");});`
58
+
59
+ return {
60
+ head: head,
61
+ end: end,
62
+ script: script,
63
+ }
64
+ }
65
+
66
+ //module for selectize
67
+ //https://selectize.dev
68
+ //https://github.com/selectize/selectize.js
69
+ m.selectize = function (req, res, elem) {
70
+ let script = ''
71
+ let head = ``
72
+ let end = ``
73
+ elem = elem || '.selectize'
74
+ head += '<link href="/modules/selectizejs/css/selectize.bootstrap5.css" rel="stylesheet">'
75
+ end += '<script src="/modules/selectizejs/js/selectize.min.js"></script>'
76
+
77
+ script += `$(() => {
78
+ $('${elem}').selectize({
79
+ sortField: 'text'
80
+ });
81
+ });`
82
+
83
+ return {
84
+ head: head,
85
+ end: end,
86
+ script: script,
87
+ }
88
+ }
89
+
90
+ //module for dropzone
91
+ m.dropzone = function (req, res, elem) {
92
+ let script = ''
93
+ let head = ``
94
+ let end = ``
95
+ elem = elem || '.dropzone'
96
+ head += '<link href="/modules/dropzone/dropzone.css" rel="stylesheet">'
97
+ end += '<script src="/modules/dropzone/dropzone.min.js"></script>'
98
+
99
+ return {
100
+ head: head,
101
+ end: end,
102
+ script: script,
103
+ }
104
+ }
105
+
106
+ //module for dragdrop
107
+ m.dragdrop = function (req, res, elem) {
108
+ let script = ''
109
+ let head = ``
110
+ let end = ``
111
+ head += '<link href="/modules/drag/drag.css" rel="stylesheet">'
112
+ end += '<script src="/modules/drag/jquery-sortable.js"></script>'
113
+ script += `$(function () {
114
+ $("ol.mydragable${elem}").sortable({
115
+ group: 'mydragable${elem}',
116
+ isValidTarget: function ($item, container) {
117
+ return true;
118
+ },
119
+ onDrop: function ($item, container, _super) {
120
+ var getidname = $item.parents().attr('id') || "";
121
+ var iname = $item.find('input[type=text]').attr('data-name');
122
+ var containertype = $item.parents().data('type');
123
+ var containername = $item.parents().data('name');
124
+ var newname = getidname ? iname + "___" + getidname : iname;
125
+ $item.find('input[type=text]').attr('name', newname);
126
+ $item.find('input[type=hidden]').attr('name', containername);
127
+ $item.find('button').addClass(containertype == "left" ? "btn-primary" : "btn-danger");
128
+ $item.find('button').removeClass(containertype == "right" ? "btn-primary" : "btn-danger");
129
+ _super($item, container);
130
+ }
131
+ });
132
+ });
133
+
134
+ `
135
+ return {
136
+ head: head,
137
+ end: end,
138
+ script: script,
139
+ }
140
+ }
141
+
142
+ //module for google map
143
+ m.location = function (req, res, key) {
144
+ let script = ``
145
+ let head = ``
146
+ let end = ``
147
+ end += `<script src="https://maps.googleapis.com/maps/api/js?key=${process.env.GOOGLE_KEY}&callback=initAutocompleteZmap&libraries=places&language=ID" defer></script>`
148
+ script += `let searchAddressMap;
149
+ let autocompleteMap;
150
+ function initAutocompleteZmap() {
151
+ if(mapLocationJSON && mapLocationJSON.lat) {
152
+ $("#search_map_location").val(mapLocationJSON.address1);
153
+ initMap(mapLocationJSON.lat,mapLocationJSON.lon);
154
+ } else {
155
+ navigator.geolocation.getCurrentPosition(function(location) {
156
+ initMap(location.coords.latitude,location.coords.longitude);
157
+ $("#search_map_location").val("My Place");
158
+ });
159
+ }
160
+ searchAddressMap = document.querySelector("#search_map_location");
161
+ autocompleteMap = new google.maps.places.Autocomplete(searchAddressMap, {
162
+ componentRestrictions: {country: ["ID"]},
163
+ fields: ["address_component", "geometry"],
164
+ });
165
+ searchAddressMap.focus();
166
+ autocompleteMap.addListener("place_changed", fillInAddress);
167
+ }
168
+
169
+ function fillInAddress() {
170
+ const place = autocompleteMap.getPlace();
171
+ let lat = place.geometry.location.lat();
172
+ let lon = place.geometry.location.lng();
173
+ initMap(lat, lon);
174
+ mapLocationJSON = {
175
+ lat:lat,
176
+ lon:lon,
177
+ address1: $("#search_map_location").val(),
178
+ address2:place.address_components,
179
+ }
180
+ setAddress();
181
+ }
182
+ function setAddress() {
183
+ $("#${key}").val(JSON.stringify(mapLocationJSON));
184
+ }
185
+ function initMap(lat, lon) {
186
+ let position = {lat: lat, lng: lon}
187
+ const map = new google.maps.Map(document.getElementById("map_${key}"), {
188
+ zoom: 13,
189
+ center: position,
190
+ draggable: true
191
+ });
192
+ var marker;
193
+ placeMarker(position, map);
194
+ var infowindow = new google.maps.InfoWindow();
195
+ function placeMarker(position, map) {
196
+ marker = new google.maps.Marker({
197
+ position: position,
198
+ map: map,
199
+ draggable: true,
200
+ animation: google.maps.Animation.DROP,
201
+ });
202
+ map.panTo(position);
203
+ }
204
+ google.maps.event.addListener(marker, 'dragend', function () {
205
+ geocodePosition(marker.getPosition());
206
+ });
207
+ google.maps.event.addListener(marker, 'click', function() {
208
+ infowindow.setContent($("#search_map_location").val());
209
+ infowindow.open(map, this)
210
+ });
211
+ function geocodePosition(pos) {
212
+ mapLocationJSON.lat=pos.lat();
213
+ mapLocationJSON.lon=pos.lng();
214
+ var geocoder = new google.maps.Geocoder();
215
+ geocoder.geocode
216
+ ({
217
+ latLng: pos
218
+ },
219
+ function (results, status) {
220
+ if (status == google.maps.GeocoderStatus.OK) {
221
+ $("#search_map_location").val(results[0].formatted_address);
222
+ $("#mapErrorMsg").hide(100);
223
+ mapLocationJSON.address2=results[0].formatted_address;
224
+ mapLocationJSON.address1=$("#search_map_location").val();
225
+ setAddress();
226
+ } else {
227
+ $("#mapErrorMsg").html('Cannot determine address at this location.' + status).show(100);
228
+ }
229
+ }
230
+ );
231
+ }
232
+ }`
233
+ return {
234
+ head: head,
235
+ end: end,
236
+ script: script,
237
+ }
238
+ }
239
+
240
+ //module for datepicker
241
+ m.datetimepicker = function (req, res, elem) {
242
+ let script = ''
243
+ let head = ``
244
+ let end = ``
245
+ elem = elem || '.datetimepicker'
246
+ head += '<link href="/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />'
247
+ end += '<script type="text/javascript" src="/js/moment-with-locales.min.js" ></script>'
248
+ end += '<script type="text/javascript" src="/js/bootstrap-datetimepicker.min.js" ></script>'
249
+ script += `$(function () { $("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'}); });`
250
+ script += `setTimeout(function () { $("body").click();},1000);`
251
+ script += `$("body").on("click", function(){$("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'});});`
252
+
253
+ return {
254
+ head: head,
255
+ end: end,
256
+ script: script,
257
+ }
258
+ }
259
+
260
+ //using ckeditor
261
+ m.ckeditor = function (req, res, elem) {
262
+ let script = ''
263
+ let head = ``
264
+ let end = ``
265
+ elem = elem || '.editor'
266
+ end += '<script src="/modules/ckeditor5-build-classic/ckeditor.js"></script>' + newLine
267
+ end += '<script>'
268
+ end += 'ClassicEditor.create( document.querySelector( "' + elem + '" ) ).catch( error => {console.error( error );} );' + newLine
269
+ end += '</script>'
270
+ return {
271
+ head: head,
272
+ end: end,
273
+ script: script,
274
+ }
275
+ }
276
+
277
+ //using tinymce
278
+ m.tinymce = function (req, res, elem) {
279
+ let script = ''
280
+ let head = ``
281
+ let end = ``
282
+ elem = elem || '.tinymce'
283
+ end += '<script src="https://cdn.tiny.cloud/1/b7054u42l8lw67ch5oh9qutnvbyu8exzryg4edy0gg2snhtr/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>' + newLine
284
+ script += ` tinymce.init({
285
+ selector: '${elem}',
286
+ plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount',
287
+ toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table | align lineheight | numlist bullist indent outdent | emoticons charmap | removeformat',
288
+ });`
289
+ return {
290
+ head: head,
291
+ end: end,
292
+ script: script,
293
+ }
294
+ }
295
+
296
+ //using froala
297
+ m.froala = function (req, res, elem) {
298
+ let script = ''
299
+ let head = ``
300
+ let end = ``
301
+ elem = elem || '.editor'
302
+
303
+ head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />'
304
+ head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />'
305
+ end += '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>'
306
+ script += `$(function() {$("${elem}").froalaEditor({height: 200})});`
307
+
308
+ return {
309
+ head: head,
310
+ end: end,
311
+ script: script,
312
+ }
313
+ }
314
+
315
+ m.lexical = function (req, res, elem) {
316
+ let script = ''
317
+ let head = ``
318
+ let end = ``
319
+ elem = elem || '.editor'
320
+ head += `<link rel="stylesheet" href="/assets/main.143ecbc6.css">`
321
+ end += `<script type="module" crossorigin src="/assets/main.3be493b7.js"></script>`
322
+ return {
323
+ head: head,
324
+ end: end,
325
+ script: script,
326
+ }
327
+ }
328
+
329
+ //Default editor is froala
330
+ m.editor = (req, res, elem = '') => {
331
+ elem = elem || '.editor'
332
+ //Default editor is froala
333
+ //return m.froala(req, res, elem);
334
+ //return m.tinymce(req, res, elem);
335
+ //return m.ckeditor(req, res, elem);
336
+ //return m.lexical(req,res,elem);
337
+
338
+ let script = ''
339
+ let head = ``
340
+ let end = ``
341
+
342
+ head += '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.4.2/css/all.min.css" integrity="sha512-NicFTMUg/LwBeG8C7VG+gC4YiiRtQACl98QdkmfsLy37RzXdkaUAuPyVMND0olPP4Jn8M/ctesGSB2pgUBDRIw==" crossorigin="anonymous" referrerpolicy="no-referrer" />'
343
+ head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />'
344
+ head += '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />'
345
+ end += '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>'
346
+ script += `$(function() {$("${elem}").froalaEditor({height: 200})});`
347
+
348
+ return {
349
+ head: head,
350
+ end: end,
351
+ script: script,
352
+ }
353
+ }
354
+
355
+ m.switch = function (req, res, elem, array) {
356
+ elem = elem || '.switch'
357
+ let script = ''
358
+ let head = ``
359
+ let end = ``
360
+
361
+ head += '<link href="/modules/bootstrap-switch/bootstrap-switch.css" rel="stylesheet" type="text/css" />' + newLine
362
+ end += '<script type="text/javascript" src="/modules/bootstrap-switch/bootstrap-switch.js"></script>' + newLine
363
+
364
+ let labels = ''
365
+ if (Array.isArray(array)) {
366
+ labels = '{offText:"' + array[0] + '", onText:"' + array[1] + '"}'
367
+ }
368
+ script += '$("' + elem + '").bootstrapSwitch(' + labels + ');' + newLine
369
+ return {
370
+ head: head,
371
+ end: end,
372
+ script: script,
373
+ }
374
+ }
375
+
376
+ m.switchOld = function (req, res, elem, array) {
377
+ let script = ''
378
+ let head = ``
379
+ let end = ``
380
+ elem = elem || '.switch'
381
+ head += '<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">' + newLine
382
+ end += '<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>' + newLine
383
+
384
+ let labels = ''
385
+ if (Array.isArray(array)) {
386
+ labels = '{off:"' + array[0] + '", on:"' + array[1] + '"}'
387
+ }
388
+ script += `$(function(){$('${elem}').bootstrapToggle(${labels});});${Util.newLine}`
389
+
390
+ return {
391
+ head: head,
392
+ end: end,
393
+ script: script,
394
+ }
395
+ }
396
+
397
+ m.clockpicker = function (req, res, elem) {
398
+ let script = ''
399
+ let head = ``
400
+ let end = ``
401
+ elem = elem || '.clockpicker'
402
+ head += '<link href="/modules/jquery-clockpicker.min.css" rel="stylesheet" type="text/css" />' + newLine
403
+ end += '<script type="text/javascript" src="/modules/bootstrap-clockpicker.min.js"></script>' + newLine
404
+ script += `$("body").on("click", "${elem}", function(){$(this).clockpicker({donetext: "Done"});});`
405
+ //end += '$("' + elem + '").clockpicker({donetext: "Done"});' + newLine;
406
+ return {
407
+ head: head,
408
+ end: end,
409
+ script: script,
410
+ }
411
+ }
412
+
413
+ m.number = (req, res, elem) => {
414
+ let script = ''
415
+ let head = ``
416
+ let end = ``
417
+ elem = elem || '.number'
418
+
419
+ end += '<script type="text/javascript" src="/js/jquery-currency.js"></script>'
420
+ script += `$(function () { $(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."}); });`
421
+ script += `setTimeout(function () { $("body").click();},1000);`
422
+ script += `$("body").on("click", function(){$(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."});});`
423
+
424
+ return {
425
+ head: head,
426
+ end: end,
427
+ script: script,
428
+ }
429
+ }
430
+
431
+ m.typeahead = (req, res, table, elem) => {
432
+ let script = ''
433
+ let head = ``
434
+ let end = ``
435
+ elem = elem || '.typeahead'
436
+ end += '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' + newLine
437
+
438
+ let elemData = elem.replace('.', '').replace('#', '')
439
+ let element = elem.replace('Typeahead', '')
440
+ let key = element.replace('#', '').replace('.', '')
441
+ // var script using existing cache
442
+ script += `$("body").on("click", "${element}Clear", function(){
443
+ $("${elem}").val("");
444
+ $("${element}").val("");
445
+ $("${element}").change();
446
+ });${Util.newLine}`
447
+ script += `$("${elem}").typeahead({highlight:true,minLength:2,source: function (query, asyncprocess) {
448
+ jQuery.ajax({
449
+ url : "/ztypeahead/${table}/${key}",
450
+ type : 'GET',
451
+ data : {
452
+ "query" : query
453
+ },
454
+ dataType : 'json',
455
+ success : function(json) {
456
+ asyncprocess(json);
457
+ }
458
+ });
459
+ }, items: 50, displayText: function (item) {
460
+ return item.zname.toString();
461
+ },
462
+ updater:function (item) {
463
+ $("${element}").val(item.id);
464
+ $("${element}").change();
465
+ return item;
466
+ }
467
+ }); ${Util.newLine}`
468
+ return {
469
+ head: head,
470
+ end: end,
471
+ script: script,
472
+ }
473
+ }
474
+
475
+ m.typeaheadFile = (req, res, elem, data) => {
476
+ let script = ''
477
+ let head = ``
478
+ let end = ``
479
+ data = data || []
480
+ elem = elem || '.typeahead'
481
+ end += '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' + newLine
482
+
483
+ let elemData = elem.replace('.', '')
484
+ elemData = elemData.replace('#', '')
485
+ let element = elem.replace('Typeahead', '')
486
+ // var script using existing cache
487
+ script += `$("body").on("click", "${element}Clear", function(){
488
+ $("${elem}").val("");
489
+ $("${element}").val("");
490
+ $("${element}").change();
491
+ });${Util.newLine}`
492
+ script += `$("${elem}").typeahead({highlight: true,minLength:2,source:${elemData}Data, items: 50, displayText: function (item) {
493
+ return item.zname.toString();
494
+ },
495
+ updater:function (item) {
496
+ $("${element}").val(item.id);
497
+ $("${element}").change();
498
+ return item;
499
+ }
500
+ }); ${Util.newLine}`
501
+ return {
502
+ head: head,
503
+ end: end,
504
+ script: script,
505
+ }
506
+ }
507
+
508
+ m.custom = (req, res, script, css, src) => {
509
+ src = src || ''
510
+ css = css || ''
511
+ let head = res.locals.moduleHead
512
+ let end = res.locals.moduleEnd
513
+ if (script) {
514
+ end += '<script>' + newLine
515
+ end += script + newLine
516
+ end += '</script>' + newLine
517
+ }
518
+ if (css) {
519
+ head += css
520
+ }
521
+ if (src) {
522
+ end += `<script src="${src}"> ${newLine}`
523
+ }
524
+ res.locals.moduleHead = head
525
+ res.locals.moduleEnd = end
526
+ }
527
+
528
+ m.script = (req, res, table) => {}
529
+
530
+ /*
531
+ add scrip code in the body html
532
+ end in the bottom html body (javascript) default
533
+ top in the top html body (css)
534
+
535
+ type : script / css
536
+ */
537
+ m.addScript = (req, res, contentScript, at = 'end', type = 'script') => {
538
+ if (contentScript) {
539
+ let generateId = 'app_' + Util.generate(6)
540
+ let tagOpen = type == 'script' ? `<script id="${generateId}">` : '<style type="text/css">'
541
+ let tagClose = type == 'script' ? '</script>' : '</style>'
542
+ let content = at == 'end' ? res.locals.moduleEnd : res.locals.moduleHead
543
+ content += tagOpen + newLine
544
+ content += contentScript + newLine
545
+ content += tagClose + newLine
546
+
547
+ if (at == 'end') {
548
+ res.locals.moduleEnd = content
549
+ } else res.locals.moduleHead = content
550
+ }
551
+ }
552
+
553
+ m.addModule = (req, res, content, isModuleHead = false) => {
554
+ let moduleContent = isModuleHead ? res.locals.moduleHead : res.locals.moduleEnd
555
+ moduleContent += content
556
+ if (isModuleHead) {
557
+ res.locals.moduleHead = moduleContent
558
+ } else {
559
+ res.locals.moduleEnd = moduleContent
560
+ }
561
+ }
562
+
563
+ m.highchart = async (req, res, obj) => {
564
+ obj = obj || {}
565
+ let head = res.locals.moduleHead
566
+ let end = res.locals.moduleEnd
567
+ if (end.indexOf('highcharts') < 0) {
568
+ end += '<script src="https://code.highcharts.com/highcharts.js"></script>' + newLine
569
+ }
570
+
571
+ if (!Util.isEmptyObject(obj)) {
572
+ const highcharts = require('./highcharts')
573
+ end += '<script>' + newLine
574
+ end += await highcharts.build(obj)
575
+ end += '</script>' + newLine
576
+ }
577
+
578
+ res.locals.moduleHead = head
579
+ res.locals.moduleEnd = end
580
+ }
581
+
582
+ //build auto js and css based on function type
583
+ m.build = (req, res, objData) => {
584
+ let head = res.locals.moduleHead
585
+ let end = res.locals.moduleEnd
586
+
587
+ head += objData.head
588
+ end += objData.end
589
+ if (objData.script) {
590
+ end += `<script>${objData.script}</script>`
591
+ }
592
+ res.locals.moduleHead = head
593
+ res.locals.moduleEnd = end
594
+ }
595
+
596
+ m.tableForm = (req, res, name, table) => {
597
+ let head = res.locals.moduleHead
598
+ let end = res.locals.moduleEnd
599
+ res.locals.moduleHead = head
600
+ res.locals.moduleEnd = end
601
+ }
602
+
603
+ m.selectYear = (req, res, elem, val, startYear, endYear) => {
604
+ let dt = new Date()
605
+ endYear = endYear || dt.getFullYear()
606
+ val = val || ''
607
+ var options = ''
608
+ for (var i = endYear; i >= startYear; i--) {
609
+ var selected = i == val ? ' selected ' : ''
610
+ options += `<option value="${i}" ${selected}>${i}</option>`
611
+ }
612
+ let end = res.locals.moduleEnd
613
+ end += '<script>' + newLine
614
+ end += `$("${elem}").html('${options}')`
615
+ end += '</script>' + newLine
616
+ res.locals.moduleEnd = end
617
+ }
618
+
619
+ //https://highlightjs.org/usage/
620
+ m.highlight = (req, res, elem) => {
621
+ elem = elem || '.codes'
622
+ let head = res.locals.moduleHead
623
+ let end = res.locals.moduleEnd
624
+ if (head.indexOf('highlight') < 0) {
625
+ head += '<link rel="stylesheet" href="/modules/highlight/default.min.css"> ' + newLine
626
+ end += '<script src="/modules/highlight/highlight.min.js"></script>' + newLine
627
+ }
628
+ end += '<script>$(function(){ document.querySelectorAll("' + elem + '").forEach((block) => {hljs.highlightBlock(block);}); })</script>' + newLine
629
+ res.locals.moduleHead = head
630
+ res.locals.moduleEnd = end
631
+ }
632
+
633
+ //https://developer.snapappointments.com/bootstrap-select/
634
+ m.selectpicker = function (req, res, elem) {
635
+ elem = elem || '.selectpicker'
636
+ let head = res.locals.moduleHead
637
+ let end = res.locals.moduleEnd
638
+ if (head.indexOf('bootstrap-select') < 0) {
639
+ head += '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">' + newLine
640
+ end += '<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>' + newLine
641
+ end += `<script>$(function () {$('${elem}').selectpicker();});</script>${newLine}`
642
+ }
643
+ res.locals.moduleHead = head
644
+ res.locals.moduleEnd = end
645
+ }
646
+
647
+ m.slugHTML = (req, res, content, at = 'end') => {
648
+ if (content) {
649
+ let head = res.locals.moduleHead
650
+ let end = res.locals.moduleEnd
651
+ if (at == 'end') {
652
+ end += content
653
+ res.locals.moduleEnd = end
654
+ } else {
655
+ head += content
656
+ res.locals.moduleHead = head
657
+ }
658
+ }
659
+ }
660
+
661
+ module.exports = m