zet-lib 3.0.7 → 3.0.9

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 CHANGED
@@ -214,6 +214,10 @@ Form.field = (obj) => {
214
214
  displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${additional_attributes} ${tabindex} ${style} type="text" class="form-control number ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
215
215
  break;
216
216
 
217
+ case "money":
218
+ displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${additional_attributes} ${tabindex} ${style} type="text" class="form-control ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
219
+ break;
220
+
217
221
  case "integer":
218
222
  displayForm = `${prepend}${inputGroupLeft}<input autocomplete="off" autofocus="" ${disabled} ${readonly} ${additional_attributes} ${tabindex} ${style} type="number" class="form-control ${obj.class}" ${id} ${name} ${placeholder} ${required} value="${value}" ${htmlOptions}>${inputGroupRight}${information}${append}`;
219
223
  break;
@@ -545,6 +549,10 @@ Form.field = (obj) => {
545
549
  displayForm = obj.html;
546
550
  break;
547
551
 
552
+ case "html":
553
+ displayForm = obj.code;
554
+ break;
555
+
548
556
  case "location":
549
557
  displayForm = `${prepend}<input type="text" class="form-control ${
550
558
  obj.class
@@ -1028,6 +1036,10 @@ Form.build = (obj) => {
1028
1036
  }
1029
1037
  }
1030
1038
  }
1039
+
1040
+ if(obj.type == "html") {
1041
+ html = obj.code;
1042
+ }
1031
1043
  return html;
1032
1044
  };
1033
1045
 
package/lib/Model.js CHANGED
@@ -84,6 +84,7 @@ Model.keys = {
84
84
  text: "Text",
85
85
  textarea: "Textarea",
86
86
  checkbox: "Checkbox",
87
+ money: "Money",
87
88
  number: "Amount",
88
89
  integer: "Integer",
89
90
  select: "Select (static) ",
@@ -119,6 +120,7 @@ Model.keys = {
119
120
  ltree: "LTree",
120
121
  virtual: "Virtual Field (readonly)",
121
122
  custom: "Custom",
123
+ html: "HTML Tags (code)",
122
124
  };
123
125
 
124
126
  Model.dropzone = {
@@ -888,6 +890,147 @@ Model.password = {
888
890
  category: "text",
889
891
  };
890
892
 
893
+ Model.money = {
894
+ properties: [
895
+ "required",
896
+ "unique",
897
+ "tabindex",
898
+ "min",
899
+ "max",
900
+ "hidden",
901
+ "defaultValue",
902
+ "inputGroupLeft",
903
+ "inputGroupRight",
904
+ "digitDecimal",
905
+ "decimalPlaces",
906
+ "thousandSeparator",
907
+ "symbol",
908
+ "information",
909
+ ],
910
+ attributes: ["min", "max"],
911
+ labels: {
912
+ required: "Required",
913
+ unique: "Unique",
914
+ tabindex: "Tab Index",
915
+ min: "Min",
916
+ max: "Max",
917
+ hidden: "Hidden",
918
+ defaultValue: "Default Value",
919
+ inputGroupLeft: "Input Group Left",
920
+ inputGroupRight: "Input Group Right",
921
+ digitDecimal:"Digit Decimal",
922
+ decimalPlaces:"Decimal Places",
923
+ thousandSeparator:"Use 1000 Separator",
924
+ symbol:"Currency Symbol",
925
+ information: "Additional Information",
926
+ },
927
+ defaultValues: {
928
+ required: false,
929
+ unique: false,
930
+ tabindex: 1,
931
+ min: 0,
932
+ max: 0,
933
+ hidden: false,
934
+ defaultValue: null,
935
+ inputGroupLeft: "",
936
+ inputGroupRight: "",
937
+ digitDecimal: 0,
938
+ decimalPlaces:",",
939
+ thousandSeparator:".",
940
+ symbol:"",
941
+ information: "",
942
+ },
943
+ typies: {
944
+ required: {
945
+ tag: "input",
946
+ type: "checkbox",
947
+ },
948
+ tabindex: {
949
+ tag: "input",
950
+ type: "number",
951
+ },
952
+ unique: {
953
+ tag: "input",
954
+ type: "checkbox",
955
+ },
956
+ min: {
957
+ tag: "input",
958
+ type: "number",
959
+ },
960
+ max: {
961
+ tag: "input",
962
+ type: "number",
963
+ },
964
+ hidden: {
965
+ tag: "input",
966
+ type: "checkbox",
967
+ },
968
+ defaultValue: {
969
+ tag: "input",
970
+ type: "number",
971
+ },
972
+ inputGroupLeft: {
973
+ tag: "input",
974
+ type: "text",
975
+ },
976
+ inputGroupRight: {
977
+ tag: "input",
978
+ type: "text",
979
+ },
980
+ digitDecimal: {
981
+ tag: "input",
982
+ type: "number",
983
+ },
984
+ decimalPlaces: {
985
+ tag: "input",
986
+ type: "text",
987
+ },
988
+ thousandSeparator: {
989
+ tag: "input",
990
+ type: "text",
991
+ },
992
+ symbol: {
993
+ tag: "input",
994
+ type: "text",
995
+ },
996
+ information: {
997
+ tag: "textarea",
998
+ type: "",
999
+ class: "",
1000
+ },
1001
+ },
1002
+ comment: (obj = {}) => {
1003
+ return `money`;
1004
+ },
1005
+ sql: (key, MYMODEL, obj = {}) => {
1006
+ const required = !obj.required ? false : true;
1007
+ const digitDecimal = obj.digitDecimal || 0;
1008
+ let defaultValue = "";
1009
+ if (!obj.defaultValue) {
1010
+ defaultValue = ``;
1011
+ } else if (obj.defaultValue == "null") {
1012
+ defaultValue = `ALTER TABLE "${MYMODEL.table}" ALTER COLUMN "${key}" SET DEFAULT NULL;`;
1013
+ } else {
1014
+ defaultValue = `ALTER TABLE "${MYMODEL.table}" ALTER COLUMN "${key}" SET DEFAULT ${obj.defaultValue};`;
1015
+ }
1016
+ const indexing = !obj.unique
1017
+ ? ""
1018
+ : ` ALTER TABLE "${MYMODEL.table}" ADD CONSTRAINT unique_${MYMODEL.table}_${key} UNIQUE (${key});`;
1019
+
1020
+ const addTable = `ALTER TABLE "${MYMODEL.table}" ADD COLUMN "${key}" NUMERIC(15, ${digitDecimal});`;
1021
+ return {
1022
+ defaultValue: defaultValue,
1023
+ column: addTable,
1024
+ index: indexing,
1025
+ foreignKey: "",
1026
+ };
1027
+ },
1028
+ columnType: (obj = {}) => {
1029
+ return `money`;
1030
+ },
1031
+ category: "money",
1032
+ };
1033
+
891
1034
  Model.number = {
892
1035
  properties: [
893
1036
  "required",
@@ -3155,6 +3298,36 @@ Model.custom = {
3155
3298
  category: "custom",
3156
3299
  };
3157
3300
 
3301
+ Model.html = {
3302
+ properties: ["code"],
3303
+ labels: {
3304
+ code: "Code",
3305
+ },
3306
+ defaultValues: {
3307
+ code: "<h1>Hello World</h1>",
3308
+ },
3309
+ typies: {
3310
+ code: {
3311
+ tag: "textarea",
3312
+ type: "",
3313
+ },
3314
+ },
3315
+ comment: (obj = {}) => {
3316
+ return ``;
3317
+ },
3318
+ sql: (key, MYMODEL, obj = {}) => {
3319
+ return {
3320
+ index: "",
3321
+ foreignKey: "",
3322
+ };
3323
+ },
3324
+ columnType: (obj = {}) => {
3325
+ return ``;
3326
+ },
3327
+ category: "custom",
3328
+ };
3329
+
3330
+
3158
3331
  Model.hardcodeGrid = `const data = await zRoute.listData(req, res, MYMODEL, zRole);
3159
3332
  ${Util.tab}res.json(data);`;
3160
3333
 
package/lib/Util.js CHANGED
@@ -660,16 +660,18 @@ Util.toNumber = function (num) {
660
660
  Util.formatNumber = function (num, thousandSeparator = ".") {
661
661
  try {
662
662
  const strValue = String(num);
663
- // Split into integer and decimal parts
664
- const parts = strValue.split(",");
663
+ // Split into integer and decimal parts (input usually has "." as decimal separator)
664
+ const parts = strValue.split(".");
665
665
  // Format integer part with thousand separators
666
666
  const integerPart = parts[0].replace(
667
667
  /\B(?=(\d{3})+(?!\d))/g,
668
668
  thousandSeparator
669
669
  );
670
+ // Determine decimal separator: if thousandSeparator is ".", use ","; otherwise use "."
671
+ let decimalSeparator = thousandSeparator === "." ? "," : ".";
670
672
  // If there's a decimal part, add it back
671
673
  if (parts.length > 1) {
672
- return `${integerPart},${parts[1]}`;
674
+ return `${integerPart}${decimalSeparator}${parts[1]}`;
673
675
  }
674
676
  return integerPart;
675
677
  } catch (e) {
@@ -370,8 +370,8 @@ function containerObject(left,right,oneColumn,tabs = []) {
370
370
  Api.modalWithContainer = async (body) => {
371
371
  try {
372
372
  //let body = req.body;
373
- /* console.log(body)
374
- console.log("Container....")*/
373
+ /* console.log(body)
374
+ console.log("Container....")*/
375
375
  let table = body.table || "";
376
376
  let html = '';
377
377
  let fields = [];
@@ -613,16 +613,16 @@ Api.modalClassic = async (body) => {
613
613
  });
614
614
  }
615
615
 
616
- /* console.log(arrName);
617
- console.log("tableft");
618
- console.log(JSON.stringify(tabLeft));
619
- console.log("tableft end");
620
- console.log("tabright");
621
- console.log(JSON.stringify(tabRight));
622
- console.log("tabright");
623
- console.log("tabonecolumn");
624
- console.log(JSON.stringify(tabOneColum));
625
- console.log("tabonecolumn end");*/
616
+ /* console.log(arrName);
617
+ console.log("tableft");
618
+ console.log(JSON.stringify(tabLeft));
619
+ console.log("tableft end");
620
+ console.log("tabright");
621
+ console.log(JSON.stringify(tabRight));
622
+ console.log("tabright");
623
+ console.log("tabonecolumn");
624
+ console.log(JSON.stringify(tabOneColum));
625
+ console.log("tabonecolumn end");*/
626
626
 
627
627
 
628
628
  if (tabLeft.length) {
@@ -673,16 +673,16 @@ Api.modalClassic = async (body) => {
673
673
  }
674
674
  }
675
675
 
676
- /* var rows = [];
677
- if (Util.isEmptyObject(datas.details)) {
678
- rows = await fieldsTable(table, rowsFields);
679
- } else {
680
- var d = datas.details;
681
- var notabs = d.hasOwnProperty('notabs') ? d.notabs : [];
682
- for (var i = 0; i < notabs.length; i++) {
683
- rows.push({name: notabs[i], label: datas.labels[notabs[i]]})
684
- }
685
- }*/
676
+ /* var rows = [];
677
+ if (Util.isEmptyObject(datas.details)) {
678
+ rows = await fieldsTable(table, rowsFields);
679
+ } else {
680
+ var d = datas.details;
681
+ var notabs = d.hasOwnProperty('notabs') ? d.notabs : [];
682
+ for (var i = 0; i < notabs.length; i++) {
683
+ rows.push({name: notabs[i], label: datas.labels[notabs[i]]})
684
+ }
685
+ }*/
686
686
 
687
687
  //caption left or right
688
688
  if (datas.left.length) {
@@ -971,10 +971,10 @@ Api.create_field = (body) => {
971
971
  }
972
972
  }
973
973
 
974
- /* console.log(JSON.stringify(left))
975
- console.log(JSON.stringify(right))
976
- console.log(JSON.stringify(oneColumn))
977
- console.log(position);*/
974
+ /* console.log(JSON.stringify(left))
975
+ console.log(JSON.stringify(right))
976
+ console.log(JSON.stringify(oneColumn))
977
+ console.log(position);*/
978
978
 
979
979
  let othersLength = Object.keys(others).length;
980
980
  if(othersLength) {
@@ -1128,7 +1128,7 @@ const createTable = (postData, isIgnore) => {
1128
1128
  let name = postData.name;
1129
1129
  name = name.trim();
1130
1130
  let forbidden = ['group','copy','command','from','select','distinct','where','year','month','day','ignore','previous','next',
1131
- 'start','end','set','setof','show','size','row','rows','return','order'];
1131
+ 'start','end','set','setof','show','size','row','rows','return','order'];
1132
1132
  if(forbidden.includes(name)) {
1133
1133
  json = Util.flashError("Module Name is Forbidden, try using other module name..", "route");
1134
1134
  return json;
@@ -449,6 +449,13 @@ me.prepare = (MYMODEL) => {
449
449
  ? 400
450
450
  : property.values.height;
451
451
  break;
452
+ case "html":
453
+ widgets[key].code = property.values.code || "";
454
+ break;
455
+
456
+ case "money":
457
+ widgets[key].symbol = property.values.symbol || "";
458
+ break;
452
459
 
453
460
  default:
454
461
  break;
@@ -560,16 +567,12 @@ me.build_sql_api = (columns, constraintList, MYMODEL) => {
560
567
  }
561
568
  }
562
569
  }
563
-
564
- //var constraintList = await connection.query(connection.constraintList(MYMODEL.table));
565
- //make a object instead of array
566
570
  const constraintObject = Util.arrayToObject(constraintList, "conname");
567
-
568
571
  const alter = [];
569
572
  const index = [];
570
573
  const defaultValue = [];
571
574
  const fk = [];
572
- const notAlters = ["virtual", "custom"];
575
+ const notAlters = ["virtual", "custom","html"];
573
576
  for (const key in properties) {
574
577
  const property = properties[key];
575
578
  if (!notAlters.includes(property.type)) {
@@ -599,6 +602,14 @@ me.build_sql_api = (columns, constraintList, MYMODEL) => {
599
602
  index.push(`DROP INDEX ${idx}; `);
600
603
  }
601
604
  }
605
+ if(property.type == "money"){
606
+ //ALTER TABLE nama_tabel
607
+ // ALTER COLUMN nama_kolom TYPE NUMERIC(15,2);
608
+ let digitDecimal = properties[key].values.digitDecimal || 0;
609
+ alter.push(
610
+ `ALTER TABLE "${MYMODEL.table}" ALTER COLUMN "${key}" TYPE NUMERIC(15,${digitDecimal});; `
611
+ );
612
+ }
602
613
  //relations foreign key
603
614
  const fkx = `fk_${MYMODEL.table}_${key}`;
604
615
  if (sqlObject.foreignKey) {
package/lib/moduleLib.js CHANGED
@@ -53,9 +53,9 @@ m.datepicker = function (req, res, elem) {
53
53
  /* head += '<link href="/css/bootstrap-datepicker.css" rel="stylesheet">';
54
54
  end += '<script src="/js/bootstrap-datepicker.min.js"></script>';*/
55
55
  head +=
56
- '<link href="/modules/bootstrap-datepicker/bootstrap-datepicker.min.css" rel="stylesheet">';
56
+ '<link href="/modules/bootstrap-datepicker/bootstrap-datepicker.min.css" rel="stylesheet">';
57
57
  end +=
58
- '<script src="/modules/bootstrap-datepicker/bootstrap-datepicker.min.js"></script>';
58
+ '<script src="/modules/bootstrap-datepicker/bootstrap-datepicker.min.js"></script>';
59
59
  script = `$.fn.datepicker.defaults.format = "yyyy-mm-dd";$.fn.datepicker.defaults.todayHighlight = true;$("body").on("click", "${elem}", function(){$(this).datepicker();$(this).datepicker("show");});`;
60
60
 
61
61
  return {
@@ -74,7 +74,7 @@ m.selectize = function (req, res, elem) {
74
74
  let end = ``;
75
75
  elem = elem || ".selectize";
76
76
  head +=
77
- '<link href="/modules/selectizejs/css/selectize.bootstrap5.css" rel="stylesheet">';
77
+ '<link href="/modules/selectizejs/css/selectize.bootstrap5.css" rel="stylesheet">';
78
78
  end += '<script src="/modules/selectizejs/js/selectize.min.js"></script>';
79
79
 
80
80
  script += `$(() => {
@@ -339,11 +339,11 @@ m.datetimepicker = function (req, res, elem) {
339
339
  let end = ``;
340
340
  elem = elem || ".datetimepicker";
341
341
  head +=
342
- '<link href="/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />';
342
+ '<link href="/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />';
343
343
  end +=
344
- '<script type="text/javascript" src="/js/moment-with-locales.min.js" ></script>';
344
+ '<script type="text/javascript" src="/js/moment-with-locales.min.js" ></script>';
345
345
  end +=
346
- '<script type="text/javascript" src="/js/bootstrap-datetimepicker.min.js" ></script>';
346
+ '<script type="text/javascript" src="/js/bootstrap-datetimepicker.min.js" ></script>';
347
347
  script += `$(function () { $("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'}); });`;
348
348
  script += `setTimeout(function () { $("body").click();},1000);`;
349
349
  script += `$("body").on("click", function(){$("${elem}").datetimepicker({format:'YYYY-MM-DD hh:mm:ss'});});`;
@@ -362,14 +362,14 @@ m.ckeditor = function (req, res, elem) {
362
362
  let end = ``;
363
363
  elem = elem || ".editor";
364
364
  end +=
365
- '<script src="/modules/ckeditor5-build-classic/ckeditor.js"></script>' +
366
- newLine;
365
+ '<script src="/modules/ckeditor5-build-classic/ckeditor.js"></script>' +
366
+ newLine;
367
367
  end += "<script>";
368
368
  end +=
369
- 'ClassicEditor.create( document.querySelector( "' +
370
- elem +
371
- '" ) ).catch( error => {console.error( error );} );' +
372
- newLine;
369
+ 'ClassicEditor.create( document.querySelector( "' +
370
+ elem +
371
+ '" ) ).catch( error => {console.error( error );} );' +
372
+ newLine;
373
373
  end += "</script>";
374
374
  return {
375
375
  head: head,
@@ -385,8 +385,8 @@ m.tinymce = function (req, res, elem) {
385
385
  let end = ``;
386
386
  elem = elem || ".tinymce";
387
387
  end +=
388
- '<script src="https://cdn.tiny.cloud/1/b7054u42l8lw67ch5oh9qutnvbyu8exzryg4edy0gg2snhtr/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>' +
389
- newLine;
388
+ '<script src="https://cdn.tiny.cloud/1/b7054u42l8lw67ch5oh9qutnvbyu8exzryg4edy0gg2snhtr/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>' +
389
+ newLine;
390
390
  script += ` tinymce.init({
391
391
  selector: '${elem}',
392
392
  plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount',
@@ -407,11 +407,11 @@ m.froala = function (req, res, elem) {
407
407
  elem = elem || ".editor";
408
408
 
409
409
  head +=
410
- '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />';
410
+ '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />';
411
411
  head +=
412
- '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />';
412
+ '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />';
413
413
  end +=
414
- '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>';
414
+ '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>';
415
415
  script += `$(function() {$("${elem}").froalaEditor({height: 200})});`;
416
416
 
417
417
  return {
@@ -449,13 +449,13 @@ m.editor = (req, res, elem = "") => {
449
449
  let end = ``;
450
450
 
451
451
  head +=
452
- '<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" />';
452
+ '<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" />';
453
453
  head +=
454
- '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />';
454
+ '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />';
455
455
  head +=
456
- '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />';
456
+ '<link href="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/css/froala_style.min.css" rel="stylesheet" type="text/css" />';
457
457
  end +=
458
- '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>';
458
+ '<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@2.9.0/js/froala_editor.pkgd.min.js"></script>';
459
459
  script += `$(function() {$("${elem}").froalaEditor({height: 200})});`;
460
460
 
461
461
  return {
@@ -472,11 +472,11 @@ m.switch = function (req, res, elem, array) {
472
472
  let end = ``;
473
473
 
474
474
  head +=
475
- '<link href="/modules/bootstrap-switch/bootstrap-switch.css" rel="stylesheet" type="text/css" />' +
476
- newLine;
475
+ '<link href="/modules/bootstrap-switch/bootstrap-switch.css" rel="stylesheet" type="text/css" />' +
476
+ newLine;
477
477
  end +=
478
- '<script type="text/javascript" src="/modules/bootstrap-switch/bootstrap-switch.js"></script>' +
479
- newLine;
478
+ '<script type="text/javascript" src="/modules/bootstrap-switch/bootstrap-switch.js"></script>' +
479
+ newLine;
480
480
 
481
481
  let labels = "";
482
482
  if (Array.isArray(array)) {
@@ -496,11 +496,11 @@ m.switchOld = function (req, res, elem, array) {
496
496
  let end = ``;
497
497
  elem = elem || ".switch";
498
498
  head +=
499
- '<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">' +
500
- newLine;
499
+ '<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">' +
500
+ newLine;
501
501
  end +=
502
- '<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>' +
503
- newLine;
502
+ '<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>' +
503
+ newLine;
504
504
 
505
505
  let labels = "";
506
506
  if (Array.isArray(array)) {
@@ -521,11 +521,11 @@ m.clockpicker = function (req, res, elem) {
521
521
  let end = ``;
522
522
  elem = elem || ".clockpicker";
523
523
  head +=
524
- '<link href="/modules/jquery-clockpicker.min.css" rel="stylesheet" type="text/css" />' +
525
- newLine;
524
+ '<link href="/modules/jquery-clockpicker.min.css" rel="stylesheet" type="text/css" />' +
525
+ newLine;
526
526
  end +=
527
- '<script type="text/javascript" src="/modules/bootstrap-clockpicker.min.js"></script>' +
528
- newLine;
527
+ '<script type="text/javascript" src="/modules/bootstrap-clockpicker.min.js"></script>' +
528
+ newLine;
529
529
  script += `$("body").on("click", "${elem}", function(){$(this).clockpicker({donetext: "Done"});});`;
530
530
  //end += '$("' + elem + '").clockpicker({donetext: "Done"});' + newLine;
531
531
  return {
@@ -542,7 +542,7 @@ m.number = (req, res, elem) => {
542
542
  elem = elem || ".number";
543
543
 
544
544
  end +=
545
- '<script type="text/javascript" src="/js/jquery-currency.js"></script>';
545
+ '<script type="text/javascript" src="/js/jquery-currency.js"></script>';
546
546
  script += `$(function () { $(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."}); });`;
547
547
  script += `setTimeout(function () { $("body").click();},1000);`;
548
548
  script += `$("body").on("click", function(){$(".number").formatCurrencyLive({symbol:"",roundToDecimalPlace :0,digitGroupSymbol :"."});});`;
@@ -560,8 +560,8 @@ m.typeahead = (req, res, table, elem) => {
560
560
  let end = ``;
561
561
  elem = elem || ".typeahead";
562
562
  end +=
563
- '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' +
564
- newLine;
563
+ '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' +
564
+ newLine;
565
565
 
566
566
  let elemData = elem.replace(".", "").replace("#", "");
567
567
  let element = elem.replace("Typeahead", "");
@@ -607,8 +607,8 @@ m.typeaheadFile = (req, res, elem, data) => {
607
607
  data = data || [];
608
608
  elem = elem || ".typeahead";
609
609
  end +=
610
- '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' +
611
- newLine;
610
+ '<script type="text/javascript" src="/modules/typeahead/typeahead.js"></script>' +
611
+ newLine;
612
612
 
613
613
  let elemData = elem.replace(".", "");
614
614
  elemData = elemData.replace("#", "");
@@ -661,7 +661,7 @@ m.dropboxview = (req, res) => {
661
661
  let head = ``;
662
662
  let end = ``;
663
663
  script +=
664
- `let dropbox_image = {}
664
+ `let dropbox_image = {}
665
665
  $(()=>{
666
666
  $(".zdropbox-view").each(function (index, item) {
667
667
  let dropboxLength = $(".zdropbox-view").length || 0;
@@ -729,9 +729,9 @@ m.addScript = (req, res, contentScript, at = "end", type = "script") => {
729
729
  if (contentScript) {
730
730
  let generateId = "app_" + Util.generate(6);
731
731
  let tagOpen =
732
- type == "script"
733
- ? `<script id="${generateId}">`
734
- : '<style type="text/css">';
732
+ type == "script"
733
+ ? `<script id="${generateId}">`
734
+ : '<style type="text/css">';
735
735
  let tagClose = type == "script" ? "</script>" : "</style>";
736
736
  let content = at == "end" ? res.locals.moduleEnd : res.locals.moduleHead;
737
737
  content += tagOpen + newLine;
@@ -746,8 +746,8 @@ m.addScript = (req, res, contentScript, at = "end", type = "script") => {
746
746
 
747
747
  m.addModule = (req, res, content, isModuleHead = false) => {
748
748
  let moduleContent = isModuleHead
749
- ? res.locals.moduleHead
750
- : res.locals.moduleEnd;
749
+ ? res.locals.moduleHead
750
+ : res.locals.moduleEnd;
751
751
  moduleContent += content;
752
752
  if (isModuleHead) {
753
753
  res.locals.moduleHead = moduleContent;
@@ -762,8 +762,8 @@ m.highchart = async (req, res, obj) => {
762
762
  let end = res.locals.moduleEnd;
763
763
  if (end.indexOf("highcharts") < 0) {
764
764
  end +=
765
- '<script src="https://code.highcharts.com/highcharts.js"></script>' +
766
- newLine;
765
+ '<script src="https://code.highcharts.com/highcharts.js"></script>' +
766
+ newLine;
767
767
  }
768
768
 
769
769
  if (!Util.isEmptyObject(obj)) {
@@ -821,16 +821,16 @@ m.highlight = (req, res, elem) => {
821
821
  let end = res.locals.moduleEnd;
822
822
  if (head.indexOf("highlight") < 0) {
823
823
  head +=
824
- '<link rel="stylesheet" href="/modules/highlight/default.min.css"> ' +
825
- newLine;
824
+ '<link rel="stylesheet" href="/modules/highlight/default.min.css"> ' +
825
+ newLine;
826
826
  end +=
827
- '<script src="/modules/highlight/highlight.min.js"></script>' + newLine;
827
+ '<script src="/modules/highlight/highlight.min.js"></script>' + newLine;
828
828
  }
829
829
  end +=
830
- '<script>$(function(){ document.querySelectorAll("' +
831
- elem +
832
- '").forEach((block) => {hljs.highlightBlock(block);}); })</script>' +
833
- newLine;
830
+ '<script>$(function(){ document.querySelectorAll("' +
831
+ elem +
832
+ '").forEach((block) => {hljs.highlightBlock(block);}); })</script>' +
833
+ newLine;
834
834
  res.locals.moduleHead = head;
835
835
  res.locals.moduleEnd = end;
836
836
  };
@@ -842,11 +842,11 @@ m.selectpicker = function (req, res, elem) {
842
842
  let end = res.locals.moduleEnd;
843
843
  if (head.indexOf("bootstrap-select") < 0) {
844
844
  head +=
845
- '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">' +
846
- newLine;
845
+ '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">' +
846
+ newLine;
847
847
  end +=
848
- '<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>' +
849
- newLine;
848
+ '<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>' +
849
+ newLine;
850
850
  end += `<script>$(function () {$('${elem}').selectpicker();});</script>${newLine}`;
851
851
  }
852
852
  res.locals.moduleHead = head;
@@ -139,8 +139,8 @@
139
139
  dropdownRelations('dropdown_multi_table', 'dropdown_multi_name', '', $('#dropdown_multi_table').data('value'), $('#dropdown_multi_name').data('value'))
140
140
  }
141
141
 
142
- $("#number_decimalPlaces").css("font-size","2rem");
143
- $("#number_thousandSeparator").css("font-size","2rem");
142
+ $("#money_decimalPlaces").css("font-size","2rem");
143
+ $("#money_thousandSeparator").css("font-size","2rem");
144
144
  }
145
145
  )
146
146
  $('#modal_setting').modal('show')
package/lib/zRoute.js CHANGED
@@ -329,6 +329,42 @@ zRoute.post = (req, res, MYMODEL, routeName, body) => {
329
329
  post[routeName][key] = val ? val : val === 0 ? 0 : null;
330
330
  break;
331
331
 
332
+ case "money":
333
+ if (typeof val == "string" && val.trim() !== "") {
334
+ // Get widget configuration
335
+ const widgetConfig = widgets[key] || {};
336
+ const symbol = widgetConfig.symbol || "";
337
+ const thousandSeparator = widgetConfig.thousandSeparator || ",";
338
+ const decimalPlaces = widgetConfig.decimalPlaces || ".";
339
+
340
+ // Remove symbol if present
341
+ let cleanedVal = val.trim();
342
+ if (symbol && cleanedVal.startsWith(symbol)) {
343
+ cleanedVal = cleanedVal.substring(symbol.length).trim();
344
+ }
345
+
346
+ // Remove thousand separators
347
+ if (thousandSeparator) {
348
+ // Escape special regex characters
349
+ const escapedThousandSep = thousandSeparator.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
350
+ cleanedVal = cleanedVal.replace(new RegExp(escapedThousandSep, 'g'), '');
351
+ }
352
+
353
+ // Replace decimal separator with standard dot
354
+ if (decimalPlaces && decimalPlaces !== ".") {
355
+ // Escape special regex characters
356
+ const escapedDecimalSep = decimalPlaces.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
357
+ cleanedVal = cleanedVal.replace(escapedDecimalSep, '.');
358
+ }
359
+
360
+ // Convert to number
361
+ const numVal = parseFloat(cleanedVal);
362
+ post[routeName][key] = isNaN(numVal) ? null : numVal;
363
+ } else {
364
+ post[routeName][key] = val ? val : val === 0 ? 0 : null;
365
+ }
366
+ break;
367
+
332
368
  case "json_array":
333
369
  myval = null;
334
370
  if (val) {
@@ -400,6 +436,9 @@ zRoute.attributeData = async (res, MYMODEL, obj) => {
400
436
  if (MYMODEL.widgets[key].name == "custom") {
401
437
  customs.push(key);
402
438
  }
439
+ if (MYMODEL.widgets[key].name == "html") {
440
+ customs.push(key);
441
+ }
403
442
  }
404
443
  if (customs.length) {
405
444
  visibles = visibles.filter((item) => !customs.includes(item));
@@ -1269,6 +1308,10 @@ zRoute.dataTableData = (
1269
1308
  myvalue = Util.formatNumber(value);
1270
1309
  break;
1271
1310
 
1311
+ case "money":
1312
+ myvalue = `${MYMODEL.widgets[key].symbol} ${Util.formatNumber(value, MYMODEL.widgets[key].thousandSeparator)}`;
1313
+ break;
1314
+
1272
1315
  case "integer":
1273
1316
  myvalue = value + "";
1274
1317
  break;
@@ -3103,6 +3146,10 @@ zRoute.forms = (
3103
3146
  case "tags":
3104
3147
  obj.type = "tags";
3105
3148
  break;
3149
+ case "html":
3150
+ obj.type = "html";
3151
+ obj.code = widgets[key].code || ""
3152
+ break;
3106
3153
  case "checkbox":
3107
3154
  obj.type = "checkbox";
3108
3155
  break;
@@ -3716,7 +3763,10 @@ zRoute.viewForm = (
3716
3763
  obj[key].value = data[key] || "";
3717
3764
  break;
3718
3765
  case "number":
3719
- obj[key].value = data[key] ? Util.formatNumber(data[key], ",") : "";
3766
+ obj[key].value = data[key] ? Util.formatNumber(data[key], ".") : "";
3767
+ break;
3768
+ case "money":
3769
+ obj[key].value = data[key] ? `${widgets[key].symbol} ${Util.formatNumber(data[key], ".")}` : "";
3720
3770
  break;
3721
3771
  case "typeahead":
3722
3772
  obj[key].type = "text";
@@ -4120,6 +4170,7 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
4120
4170
  let hasAttributes = [];
4121
4171
  let joinsFields = [];
4122
4172
  let selectize = [];
4173
+ let moneys = [];
4123
4174
  if (MYMODEL.joins) {
4124
4175
  joinsFields = MYMODEL.joins.list;
4125
4176
  }
@@ -4129,6 +4180,9 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
4129
4180
  hasDatePicker = true;
4130
4181
  } else if (widgets[key].name == "number") {
4131
4182
  hasNumber = true;
4183
+ } else if (widgets[key].name == "money") {
4184
+ hasNumber = true;
4185
+ moneys.push(key);
4132
4186
  } else if (widgets[key].name == "clockpicker") {
4133
4187
  hasClockPicker = true;
4134
4188
  } else if (widgets[key].name == "editor") {
@@ -4220,6 +4274,24 @@ zRoute.generateJS = (req, res, MYMODEL, relations, zForms = "", data = {}) => {
4220
4274
  scriptForm += numberObj.script;
4221
4275
  headObj.number = numberObj.head;
4222
4276
  endObj.number = numberObj.end;
4277
+ if(moneys.length > 0) {
4278
+ let moneyScript = ``
4279
+ moneys.map((money) => {
4280
+ moneyScript += `$('#${money}').formatCurrency({
4281
+ symbol: '${widgets[money].symbol || "" }',
4282
+ decimalSymbol: '${widgets[money].decimalPlaces || "," }',
4283
+ digitGroupSymbol: '${widgets[money].thousandSeparator || "." }',
4284
+ roundToDecimalPlace: ${widgets[money].digitDecimal || 0}
4285
+ });`
4286
+ moneyScript += `$('#${money}').formatCurrencyLive({
4287
+ symbol: '${widgets[money].symbol || "" }',
4288
+ decimalSymbol: '${widgets[money].decimalPlaces || "," }',
4289
+ digitGroupSymbol: '${widgets[money].thousandSeparator || "." }',
4290
+ roundToDecimalPlace: ${widgets[money].digitDecimal || 0}
4291
+ });`
4292
+ })
4293
+ scriptForm += ` $(function() {${moneyScript}});`;
4294
+ }
4223
4295
  }
4224
4296
  if (hasClockPicker) {
4225
4297
  let clockpickerObj = moduleLib.clockpicker(req, res);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zet-lib",
3
- "version": "3.0.7",
3
+ "version": "3.0.9",
4
4
  "description": "zet is a library that part of zet generator.",
5
5
  "engines": {
6
6
  "node": ">=18"