@saltcorn/server 0.7.4-beta.3 → 0.8.0-beta.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.
@@ -1,13 +1,13 @@
1
1
  function MenuEditor(e, t) {
2
2
  const radioValue = (e) =>
3
- $(`input:radio[name ='${$(e).attr("name")}']:checked`).val();
3
+ $(`input:radio[name=\"${$(e).attr("name")}\"]:checked`).val();
4
4
  var s = $("#" + e).data("level", "0"),
5
5
  l = {
6
6
  labelEdit: '<i class="fas fa-edit clickable"></i>',
7
7
  labelRemove: '<i class="fas fa-trash-alt clickable"></i>',
8
8
  textConfirmDelete: "This item will be deleted. Are you sure?",
9
9
  getLabelText: (e) => e.text,
10
- onUpdate: () => {},
10
+ onUpdate: () => { },
11
11
  iconPicker: { cols: 4, rows: 4, footer: !1, iconset: "fontawesome5" },
12
12
  maxLevel: -1,
13
13
  listOptions: {
@@ -113,8 +113,8 @@ function MenuEditor(e, t) {
113
113
  var o = !1;
114
114
  void 0 !== n.attr("id") && (o = n.attr("id").toString() === e),
115
115
  n.children().length ||
116
- o ||
117
- (n.prev("div").children(".sortableListsOpener").first().remove(),
116
+ o ||
117
+ (n.prev("div").children(".sortableListsOpener").first().remove(),
118
118
  n.remove()),
119
119
  MenuEditor.updateButtons(s);
120
120
  l.onUpdate();
@@ -125,10 +125,10 @@ function MenuEditor(e, t) {
125
125
  (function (e) {
126
126
  var t = e.data();
127
127
  $.each(t, function (e, t) {
128
- var el = i.find("[name=" + e + "]");
128
+ var el = i.find("[name=\"" + e + "\"]");
129
129
  if (el.prop("type") == "checkbox") el.prop("checked", !!t);
130
130
  else if (el.prop("type") == "radio") {
131
- $(`input[name=${el.prop("name")}][value="${t}"]`).prop(
131
+ $(`input[name=\"${el.prop("name")}\"][value="${t}"]`).prop(
132
132
  "checked",
133
133
  true
134
134
  );
@@ -173,7 +173,7 @@ function MenuEditor(e, t) {
173
173
  l = $(this).closest("li");
174
174
  l.closest("ul").closest("li").after(l),
175
175
  t.children().length <= 0 &&
176
- (t.prev("div").children(".sortableListsOpener").first().remove(),
176
+ (t.prev("div").children(".sortableListsOpener").first().remove(),
177
177
  t.remove()),
178
178
  MenuEditor.updateButtons(s),
179
179
  s.updateLevels();
@@ -219,8 +219,8 @@ function MenuEditor(e, t) {
219
219
  $(this).attr("type") === "radio"
220
220
  ? radioValue(this)
221
221
  : $(this).attr("type") === "checkbox"
222
- ? $(this).prop("checked")
223
- : $(this).val()
222
+ ? $(this).prop("checked")
223
+ : $(this).val()
224
224
  );
225
225
  }),
226
226
  e.children().children("i").removeClass(t).addClass(e.data("icon")),
@@ -236,8 +236,8 @@ function MenuEditor(e, t) {
236
236
  $(this).attr("type") === "radio"
237
237
  ? radioValue(this)
238
238
  : $(this).attr("type") === "checkbox"
239
- ? $(this).prop("checked")
240
- : $(this).val();
239
+ ? $(this).prop("checked")
240
+ : $(this).val();
241
241
  });
242
242
  var t = u(),
243
243
  l = $("<span>").addClass("txt").text(mqeSets.getLabelText(e)),
@@ -262,13 +262,13 @@ function MenuEditor(e, t) {
262
262
  var t = Array.isArray(e)
263
263
  ? e
264
264
  : (function (e) {
265
- try {
266
- var t = JSON.parse(e);
267
- } catch (e) {
268
- return console.log("The string is not a json valid."), null;
269
- }
270
- return t;
271
- })(e);
265
+ try {
266
+ var t = JSON.parse(e);
267
+ } catch (e) {
268
+ return console.log("The string is not a json valid."), null;
269
+ }
270
+ return t;
271
+ })(e);
272
272
  if (null !== t) {
273
273
  s.empty();
274
274
  var n = (function e(t, l) {
@@ -277,9 +277,9 @@ function MenuEditor(e, t) {
277
277
  0 === n
278
278
  ? s
279
279
  : $("<ul>")
280
- .addClass("pl-0")
281
- .css("padding-top", "10px")
282
- .data("level", n);
280
+ .addClass("pl-0")
281
+ .css("padding-top", "10px")
282
+ .data("level", n);
283
283
  return (
284
284
  $.each(t, function (t, s) {
285
285
  var l = void 0 !== s.children && $.isArray(s.children),
@@ -311,9 +311,9 @@ function MenuEditor(e, t) {
311
311
  })(t);
312
312
  o
313
313
  ? s.find("li").each(function () {
314
- var e = $(this);
315
- e.children("ul").length && f(e);
316
- })
314
+ var e = $(this);
315
+ e.children("ul").length && f(e);
316
+ })
317
317
  : (n.sortableLists(l.listOptions), (o = !0)),
318
318
  MenuEditor.updateButtons(s);
319
319
  }
@@ -409,8 +409,8 @@ function MenuEditor(e, t) {
409
409
  "class" == n.opener.as
410
410
  ? c.addClass(n.opener.close)
411
411
  : "html" == n.opener.as
412
- ? c.html(n.opener.close)
413
- : console.error("Invalid setting for opener.as");
412
+ ? c.html(n.opener.close)
413
+ : console.error("Invalid setting for opener.as");
414
414
  var d = {
415
415
  isDragged: !1,
416
416
  isRelEFP: null,
@@ -439,7 +439,7 @@ function MenuEditor(e, t) {
439
439
  var t = e(this);
440
440
  t.children(n.listSelector).length &&
441
441
  (c.clone(!0).prependTo(t.children("div").first()),
442
- t.hasClass("sortableListsOpen") ? L(t) : E(t));
442
+ t.hasClass("sortableListsOpen") ? L(t) : E(t));
443
443
  });
444
444
  }
445
445
  return this.on("mousedown touchstart", function (t) {
@@ -452,41 +452,41 @@ function MenuEditor(e, t) {
452
452
  a = e(this);
453
453
  l[0] &&
454
454
  (n.onDragStart(t, l),
455
- (function (t, s, l) {
456
- d.isDragged = !0;
457
- var a = parseInt(s.css("margin-top")),
458
- c = parseInt(s.css("margin-bottom")),
459
- f = parseInt(s.css("margin-left")),
460
- h = parseInt(s.css("margin-right")),
461
- v = s.offset(),
462
- b = s.innerHeight();
463
- (d.rootEl = {
464
- el: l,
465
- offset: l.offset(),
466
- rootElClass: l.attr("class"),
467
- }),
468
- (d.cEl = { el: s, mT: a, mL: f, mB: c, mR: h, offset: v }),
469
- (d.cEl.xyOffsetDiff = {
470
- X: t.pageX - d.cEl.offset.left,
471
- Y: t.pageY - d.cEl.offset.top,
455
+ (function (t, s, l) {
456
+ d.isDragged = !0;
457
+ var a = parseInt(s.css("margin-top")),
458
+ c = parseInt(s.css("margin-bottom")),
459
+ f = parseInt(s.css("margin-left")),
460
+ h = parseInt(s.css("margin-right")),
461
+ v = s.offset(),
462
+ b = s.innerHeight();
463
+ (d.rootEl = {
464
+ el: l,
465
+ offset: l.offset(),
466
+ rootElClass: l.attr("class"),
472
467
  }),
473
- d.cEl.el.addClass("sortableListsCurrent " + n.currElClass),
474
- s.before(i);
475
- var g = (d.placeholderNode = e("#sortableListsPlaceholder"));
476
- s
477
- .css({
478
- width: s.width(),
479
- position: "absolute",
480
- top: v.top - a,
481
- left: v.left - f,
482
- })
483
- .prependTo(o),
484
- g.css({ display: "block", height: b }),
485
- r.css("height", b),
486
- d.doc
487
- .on("mousemove touchmove", p)
488
- .on("mouseup touchend touchcancel", u);
489
- })(t, l, a));
468
+ (d.cEl = { el: s, mT: a, mL: f, mB: c, mR: h, offset: v }),
469
+ (d.cEl.xyOffsetDiff = {
470
+ X: t.pageX - d.cEl.offset.left,
471
+ Y: t.pageY - d.cEl.offset.top,
472
+ }),
473
+ d.cEl.el.addClass("sortableListsCurrent " + n.currElClass),
474
+ s.before(i);
475
+ var g = (d.placeholderNode = e("#sortableListsPlaceholder"));
476
+ s
477
+ .css({
478
+ width: s.width(),
479
+ position: "absolute",
480
+ top: v.top - a,
481
+ left: v.left - f,
482
+ })
483
+ .prependTo(o),
484
+ g.css({ display: "block", height: b }),
485
+ r.css("height", b),
486
+ d.doc
487
+ .on("mousemove touchmove", p)
488
+ .on("mouseup touchend touchcancel", u);
489
+ })(t, l, a));
490
490
  }
491
491
  });
492
492
  function p(t) {
@@ -496,12 +496,12 @@ function MenuEditor(e, t) {
496
496
  o = d.win;
497
497
  "touchmove" === t.type && v(t),
498
498
  t.pageX ||
499
- (function (e) {
500
- (e.pageY = d.pY),
501
- (e.pageX = d.pX),
502
- (e.clientY = d.cY),
503
- (e.clientX = d.cX);
504
- })(t),
499
+ (function (e) {
500
+ (e.pageY = d.pY),
501
+ (e.pageX = d.pX),
502
+ (e.clientY = d.cY),
503
+ (e.clientX = d.cX);
504
+ })(t),
505
505
  l.scrollTop() > d.rootEl.offset.top - 10 && t.clientY < 50
506
506
  ? d.upScroll
507
507
  ? ((t.pageY = t.pageY - n.scroll),
@@ -510,27 +510,27 @@ function MenuEditor(e, t) {
510
510
  }),
511
511
  f(t))
512
512
  : (function (e) {
513
- if (d.upScroll) return;
514
- d.upScroll = setInterval(function () {
515
- d.doc.trigger("mousemove");
516
- }, 50);
517
- })()
513
+ if (d.upScroll) return;
514
+ d.upScroll = setInterval(function () {
515
+ d.doc.trigger("mousemove");
516
+ }, 50);
517
+ })()
518
518
  : l.scrollTop() + o.height() <
519
- d.rootEl.offset.top + d.rootEl.el.outerHeight(!1) + 10 &&
519
+ d.rootEl.offset.top + d.rootEl.el.outerHeight(!1) + 10 &&
520
520
  o.height() - t.clientY < 50
521
- ? d.downScroll
522
- ? ((t.pageY = t.pageY + n.scroll),
523
- e("html, body").each(function (t) {
524
- e(this).scrollTop(e(this).scrollTop() + n.scroll);
525
- }),
526
- f(t))
527
- : (function (e) {
521
+ ? d.downScroll
522
+ ? ((t.pageY = t.pageY + n.scroll),
523
+ e("html, body").each(function (t) {
524
+ e(this).scrollTop(e(this).scrollTop() + n.scroll);
525
+ }),
526
+ f(t))
527
+ : (function (e) {
528
528
  if (d.downScroll) return;
529
529
  d.downScroll = setInterval(function () {
530
530
  d.doc.trigger("mousemove");
531
531
  }, 50);
532
532
  })()
533
- : h(d),
533
+ : h(d),
534
534
  (d.oElOld = d.oEl),
535
535
  (s.el[0].style.visibility = "hidden"),
536
536
  (d.oEl = oEl =
@@ -542,17 +542,17 @@ function MenuEditor(e, t) {
542
542
  (n = d.doc.scrollTop()) > 0 &&
543
543
  (l =
544
544
  null ==
545
- (o = document.elementFromPoint(
546
- 0,
547
- n + e(window).height() - 1
548
- )) || "HTML" == o.tagName.toUpperCase()),
545
+ (o = document.elementFromPoint(
546
+ 0,
547
+ n + e(window).height() - 1
548
+ )) || "HTML" == o.tagName.toUpperCase()),
549
549
  (n = d.doc.scrollLeft()) > 0 &&
550
- (l =
551
- null ==
552
- (o = document.elementFromPoint(
553
- n + e(window).width() - 1,
554
- 0
555
- )) || "HTML" == o.tagName.toUpperCase());
550
+ (l =
551
+ null ==
552
+ (o = document.elementFromPoint(
553
+ n + e(window).width() - 1,
554
+ 0
555
+ )) || "HTML" == o.tagName.toUpperCase());
556
556
  }
557
557
  l && ((t -= d.doc.scrollLeft()), (s -= d.doc.scrollTop()));
558
558
  var i = e(document.elementFromPoint(t, s));
@@ -576,8 +576,8 @@ function MenuEditor(e, t) {
576
576
  ? g(e, s, 7 > o)
577
577
  : l - 14 < o && C(e, s, l - 7 < o)
578
578
  : 5 > o
579
- ? b(e, s)
580
- : l - 5 < o && m(e, s);
579
+ ? b(e, s)
580
+ : l - 5 < o && m(e, s);
581
581
  })(t, d),
582
582
  (function (e, t) {
583
583
  var s = t.cEl;
@@ -620,12 +620,12 @@ function MenuEditor(e, t) {
620
620
  f.length && f.prev("div").prepend(c.clone(!0)),
621
621
  a
622
622
  ? d.placeholderNode.slideUp(150, function () {
623
- d.placeholderNode.remove(),
624
- y(),
625
- n.onChange(s.el),
626
- n.complete(s.el),
627
- (d.isDragged = !1);
628
- })
623
+ d.placeholderNode.remove(),
624
+ y(),
625
+ n.onChange(s.el),
626
+ n.complete(s.el),
627
+ (d.isDragged = !1);
628
+ })
629
629
  : (d.placeholderNode.remove(),
630
630
  y(),
631
631
  n.complete(s.el),
@@ -657,7 +657,7 @@ function MenuEditor(e, t) {
657
657
  function b(t, s) {
658
658
  if (
659
659
  (e("#sortableListsHintWrapper", d.rootEl.el).length && r.unwrap(),
660
- t.pageX - s.offset().left < n.insertZone)
660
+ t.pageX - s.offset().left < n.insertZone)
661
661
  ) {
662
662
  if (s.prev("#sortableListsPlaceholder").length)
663
663
  return void r.css("display", "none");
@@ -676,7 +676,7 @@ function MenuEditor(e, t) {
676
676
  function g(t, s, l) {
677
677
  if (
678
678
  (e("#sortableListsHintWrapper", d.rootEl.el).length && r.unwrap(),
679
- !l && t.pageX - s.offset().left > n.insertZone)
679
+ !l && t.pageX - s.offset().left > n.insertZone)
680
680
  ) {
681
681
  var o = s.children(),
682
682
  i = s.children(n.listSelector).first();
@@ -695,7 +695,7 @@ function MenuEditor(e, t) {
695
695
  function m(t, s) {
696
696
  if (
697
697
  (e("#sortableListsHintWrapper", d.rootEl.el).length && r.unwrap(),
698
- t.pageX - s.offset().left < n.insertZone)
698
+ t.pageX - s.offset().left < n.insertZone)
699
699
  ) {
700
700
  if (s.next("#sortableListsPlaceholder").length)
701
701
  return void r.css("display", "none");
@@ -713,7 +713,7 @@ function MenuEditor(e, t) {
713
713
  function C(t, s, l) {
714
714
  if (
715
715
  (e("#sortableListsHintWrapper", d.rootEl.el).length && r.unwrap(),
716
- !l && t.pageX - s.offset().left > n.insertZone)
716
+ !l && t.pageX - s.offset().left > n.insertZone)
717
717
  ) {
718
718
  var o = s.children(),
719
719
  i = s.children(n.listSelector).last();
@@ -735,8 +735,8 @@ function MenuEditor(e, t) {
735
735
  "html" == n.opener.as
736
736
  ? t.html(n.opener.close)
737
737
  : "class" == n.opener.as
738
- ? t.addClass(n.opener.close).removeClass(n.opener.open)
739
- : t.css("background-image", "url(" + n.opener.close + ")");
738
+ ? t.addClass(n.opener.close).removeClass(n.opener.open)
739
+ : t.css("background-image", "url(" + n.opener.close + ")");
740
740
  }
741
741
  function E(e) {
742
742
  e.removeClass("sortableListsOpen").addClass("sortableListsClosed"),
@@ -745,8 +745,8 @@ function MenuEditor(e, t) {
745
745
  "html" == n.opener.as
746
746
  ? t.html(n.opener.open)
747
747
  : "class" == n.opener.as
748
- ? t.addClass(n.opener.open).removeClass(n.opener.close)
749
- : t.css("background-image", "url(" + n.opener.open + ")");
748
+ ? t.addClass(n.opener.open).removeClass(n.opener.close)
749
+ : t.css("background-image", "url(" + n.opener.open + ")");
750
750
  }
751
751
  function y() {
752
752
  e(n.listSelector, d.rootEl.el).each(function (t) {
@@ -756,7 +756,7 @@ function MenuEditor(e, t) {
756
756
  .children(".sortableListsOpener")
757
757
  .first()
758
758
  .remove(),
759
- e(this).remove());
759
+ e(this).remove());
760
760
  });
761
761
  }
762
762
  }),
@@ -767,7 +767,7 @@ function MenuEditor(e, t) {
767
767
  "html" === e.opener.as
768
768
  ? t.html(e.opener.close)
769
769
  : "class" === e.opener.as &&
770
- t.addClass(e.opener.close).removeClass(e.opener.open);
770
+ t.addClass(e.opener.close).removeClass(e.opener.open);
771
771
  }),
772
772
  (e.fn.iconClose = function (e) {
773
773
  this.removeClass("sortableListsOpen").addClass("sortableListsClosed"),
@@ -776,7 +776,7 @@ function MenuEditor(e, t) {
776
776
  "html" === e.opener.as
777
777
  ? t.html(e.opener.open)
778
778
  : "class" === e.opener.as &&
779
- t.addClass(e.opener.open).removeClass(e.opener.close);
779
+ t.addClass(e.opener.open).removeClass(e.opener.close);
780
780
  }),
781
781
  (e.fn.sortableListsToJson = function () {
782
782
  var t = [];
@@ -808,8 +808,8 @@ function MenuEditor(e, t) {
808
808
  n = ["Down"];
809
809
  0 === s &&
810
810
  (l.push("Out"),
811
- n.push("Out"),
812
- e(this).children("li").hideButtons(["Out"])),
811
+ n.push("Out"),
812
+ e(this).children("li").hideButtons(["Out"])),
813
813
  e(this)
814
814
  .children("li")
815
815
  .each(function () {
@@ -28,13 +28,19 @@ function add_repeater(nm) {
28
28
  var newix = es.length;
29
29
  var newe = $(e).clone();
30
30
  newe.find("[name]").each(function (ix, element) {
31
+ if ($(element).hasClass("omit-repeater-clone")) $(element).remove();
31
32
  var newnm = (element.name || "").replace("_0", "_" + newix);
32
33
  var newid = (element.id || "").replace("_0", "_" + newix);
33
34
  $(element).attr("name", newnm).attr("id", newid);
34
35
  });
35
36
  newe.appendTo($("div.repeats-" + nm));
36
37
  }
37
- // "e.closest('.form-namespace').find('.coltype').val()==='Field';"
38
+
39
+ const _apply_showif_plugins = []
40
+
41
+ const add_apply_showif_plugin = p => {
42
+ _apply_showif_plugins.push(p)
43
+ }
38
44
  function apply_showif() {
39
45
  $("[data-show-if]").each(function (ix, element) {
40
46
  var e = $(element);
@@ -110,26 +116,54 @@ function apply_showif() {
110
116
  e.change(function (ec) {
111
117
  e.attr("data-selected", ec.target.value);
112
118
  });
113
- $.ajax(`/api/${dynwhere.table}?${qs}`).then((resp) => {
114
- if (resp.success) {
115
- e.empty();
116
- if (!dynwhere.required) e.append($(`<option></option>`));
117
- resp.success.forEach((r) => {
118
- e.append(
119
- $(
120
- `<option ${`${current}` === `${r[dynwhere.refname]}` ? "selected" : ""
121
- } value="${r[dynwhere.refname]}">${dynwhere.label_formula
122
- ? new Function(
123
- `{${Object.keys(r).join(",")}}`,
124
- "return " + dynwhere.label_formula
125
- )(r)
126
- : r[dynwhere.summary_field]
127
- }</option>`
128
- )
129
- );
130
- });
119
+
120
+ const currentOptionsSet = e.prop('data-fetch-options-current-set')
121
+ if (currentOptionsSet === qs) return;
122
+
123
+ const activate = (success, qs) => {
124
+ e.empty();
125
+ e.prop('data-fetch-options-current-set', qs)
126
+ if (!dynwhere.required) e.append($(`<option></option>`));
127
+ let currentDataOption = undefined;
128
+ const dataOptions = []
129
+ success.forEach((r) => {
130
+ const label = dynwhere.label_formula
131
+ ? new Function(
132
+ `{${Object.keys(r).join(",")}}`,
133
+ "return " + dynwhere.label_formula
134
+ )(r)
135
+ : r[dynwhere.summary_field]
136
+ const value = r[dynwhere.refname]
137
+ const selected = `${current}` === `${r[dynwhere.refname]}`
138
+ dataOptions.push({ text: label, value });
139
+ if (selected) currentDataOption = value;
140
+ const html = `<option ${selected ? "selected" : ""
141
+ } value="${value}">${label}</option>`
142
+ e.append(
143
+ $(html)
144
+ );
145
+ });
146
+ element.dispatchEvent(new Event('RefreshSelectOptions'))
147
+ if (e.hasClass("selectized") && $().selectize) {
148
+ e.selectize()[0].selectize.clearOptions();
149
+ e.selectize()[0].selectize.addOption(dataOptions);
150
+ if (typeof currentDataOption !== "undefined")
151
+ e.selectize()[0].selectize.setValue(currentDataOption);
152
+
131
153
  }
132
- });
154
+ }
155
+
156
+ const cache = e.prop('data-fetch-options-cache') || {}
157
+ if (cache[qs]) {
158
+ activate(cache[qs], qs)
159
+ } else
160
+ $.ajax(`/api/${dynwhere.table}?${qs}`).then((resp) => {
161
+ if (resp.success) {
162
+ activate(resp.success, qs)
163
+ const cacheNow = e.prop('data-fetch-options-cache') || {}
164
+ e.prop('data-fetch-options-cache', { ...cacheNow, [qs]: resp.success })
165
+ }
166
+ });
133
167
  });
134
168
 
135
169
  $("[data-source-url]").each(function (ix, element) {
@@ -145,17 +179,28 @@ function apply_showif() {
145
179
  },
146
180
  });
147
181
  });
182
+ _apply_showif_plugins.forEach(p => p())
183
+ }
184
+
185
+ function splitTargetMatch(elemValue, target, keySpec) {
186
+ if (!elemValue) return false;
187
+ const [fld, keySpec1] = keySpec.split("|_")
188
+ const [sep, pos] = keySpec1.split("_")
189
+ const elemValueShort = elemValue.split(sep)[pos]
190
+ return elemValueShort === target;
148
191
  }
192
+
149
193
  function get_form_record(e, select_labels) {
150
194
  const rec = {};
151
- e.closest("form")
195
+ e.closest(".form-namespace")
152
196
  .find("input[name],select[name]")
153
197
  .each(function () {
198
+ const name = $(this).attr("data-fieldname") || $(this).attr("name")
154
199
  if (select_labels && $(this).prop("tagName").toLowerCase() === "select")
155
- rec[$(this).attr("name")] = $(this).find("option:selected").text();
200
+ rec[name] = $(this).find("option:selected").text();
156
201
  else if ($(this).prop("type") === "checkbox")
157
- rec[$(this).attr("name")] = $(this).prop("checked");
158
- else rec[$(this).attr("name")] = $(this).val();
202
+ rec[name] = $(this).prop("checked");
203
+ else rec[name] = $(this).val();
159
204
  });
160
205
  return rec;
161
206
  }
@@ -507,7 +552,13 @@ function common_done(res, isWeb = true) {
507
552
  });
508
553
  else if (res.goto) {
509
554
  if (res.target === "_blank") window.open(res.goto, "_blank").focus();
510
- else window.location.href = res.goto;
555
+ else {
556
+ const prev = new URL(window.location.href)
557
+ const next = new URL(res.goto, prev.origin)
558
+ window.location.href = res.goto;
559
+ if (prev.origin === next.origin && prev.pathname === next.pathname && next.hash !== prev.hash)
560
+ location.reload()
561
+ }
511
562
  }
512
563
  if (res.popup) {
513
564
  ajax_modal(res.popup)
@@ -576,6 +627,8 @@ const columnSummary = (col) => {
576
627
  return `Field ${col.field_name} ${col.fieldview || ""}`;
577
628
  case "Link":
578
629
  return `Link ${col.link_text}`;
630
+ case "FormulaValue":
631
+ return `Formula ${col.formula}`;
579
632
  case "JoinField":
580
633
  return `Join ${col.join_field}`;
581
634
  case "ViewLink":
@@ -583,7 +636,7 @@ const columnSummary = (col) => {
583
636
  case "Action":
584
637
  return `Action ${col.action_label || col.action_name}`;
585
638
  case "Aggregation":
586
- return `${col.stat} ${col.agg_field} ${col.agg_relation}`;
639
+ return `${col.stat} ${col.agg_field.split("@")[0]} ${col.agg_relation}`;
587
640
  default:
588
641
  return "Unknown";
589
642
  }
@@ -675,6 +728,41 @@ function init_room(viewname, room_id) {
675
728
 
676
729
  function cancel_form(form) {
677
730
  if (!form) return;
731
+ $(form).trigger("reset");
732
+ $(form).trigger("change");
678
733
  $(form).append(`<input type="hidden" name="_cancel" value="on">`);
679
734
  $(form).submit();
680
735
  }
736
+
737
+ function split_paste_handler(e) {
738
+ let clipboardData = e.clipboardData || window.clipboardData || e.originalEvent.clipboardData;
739
+
740
+ const lines = clipboardData.getData('text').split(/\r\n/g)
741
+
742
+ // do normal thing if not multiline - do not interfere with ordinary copy paste
743
+ if (lines.length < 2) return;
744
+ e.preventDefault();
745
+ const form = $(e.target).closest('form')
746
+
747
+ let matched = false;
748
+
749
+ form.find('input:not(:disabled):not([readonly]):not(:hidden)').each(function (ix, element) {
750
+ if (!matched && element === e.target) matched = true;
751
+ if (matched && lines.length > 0) {
752
+ const $elem = $(element)
753
+ if (ix === 0 && $elem.attr("type") !== "number") {
754
+ //const existing = $elem.val()
755
+ //const pasted =
756
+ $elem.val(lines.shift())
757
+
758
+ } else
759
+ $elem.val(lines.shift())
760
+ }
761
+ })
762
+
763
+
764
+ }
765
+
766
+ function is_paging_param(key) {
767
+ return key.endsWith("_page") || key.endsWith("_pagesize");
768
+ }