powerpagestoolkit 2.7.1 → 2.7.2

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,4 +1,5 @@
1
- // src/safeAjax.ts
1
+ /* @ts-self-types="./index.d.ts" */
2
+ // src/utils/safeAjax.ts
2
3
  function safeAjax(ajaxOptions) {
3
4
  const deferredAjax = $.Deferred();
4
5
  shell.getTokenDeferred().done(function(token) {
@@ -20,21 +21,21 @@ function safeAjax(ajaxOptions) {
20
21
  return deferredAjax.promise();
21
22
  }
22
23
 
23
- // src/API.ts
24
- var API = {
24
+ // src/core/API.ts
25
+ var API = class {
25
26
  /**
26
27
  * @param tableSetName The dataverse set name for the table that you are updating a record in
27
28
  * @param data The JSON of the fields and data that are to be updated on the targeted record
28
29
  * @returns a Promise resolving the successful results *[record id]* of the POST request, or rejecting the failed results *[error]* of the POST request.
29
30
  */
30
- createRecord(tableSetName, data) {
31
+ static createRecord(tableSetName, data) {
31
32
  return new Promise((resolve, reject) => {
32
33
  safeAjax({
33
34
  type: "POST",
34
35
  url: `/_api/${tableSetName}`,
35
36
  data: JSON.stringify(data),
36
37
  contentType: "application/json",
37
- success: function(response, status, xhr) {
38
+ success: function(_response, _status, xhr) {
38
39
  resolve(xhr.getResponseHeader("entityid"));
39
40
  },
40
41
  error: (error) => {
@@ -42,7 +43,7 @@ var API = {
42
43
  }
43
44
  });
44
45
  });
45
- },
46
+ }
46
47
  /**
47
48
  *
48
49
  * @param tableSetName The DataVerse SET name of the table being queried
@@ -50,7 +51,7 @@ var API = {
50
51
  * @param selectColumns *OPTIONAL* if desired, enter your own custom OData query for advanced GET results. Format = select=column1,column2,column3...
51
52
  * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request
52
53
  */
53
- getRecord(tableSetName, recordID, selectColumns) {
54
+ static getRecord(tableSetName, recordID, selectColumns) {
54
55
  return new Promise((resolve, reject) => {
55
56
  const url = `/_api/${tableSetName}(${recordID})${selectColumns ? `?$${selectColumns}` : ""}`;
56
57
  safeAjax({
@@ -60,14 +61,14 @@ var API = {
60
61
  error: reject
61
62
  });
62
63
  });
63
- },
64
+ }
64
65
  /**
65
66
  *
66
67
  * @param tableSetName The dataverse set name of the table being queried
67
68
  * @param queryParameters *OPTIONAL* the OData query parameters for refining search results: *format = $filter=filters&$select=columns*
68
69
  * @returns a Promise resolving the successful results of the GET request, or rejecting the failed results of the GET request
69
70
  */
70
- getMultiple(tableSetName, queryParameters) {
71
+ static getMultiple(tableSetName, queryParameters) {
71
72
  return new Promise((resolve, reject) => {
72
73
  const url = `/_api/${tableSetName}${queryParameters ? `?${queryParameters}` : ""}`;
73
74
  safeAjax({
@@ -79,7 +80,7 @@ var API = {
79
80
  error: reject
80
81
  });
81
82
  });
82
- },
83
+ }
83
84
  /**
84
85
  *
85
86
  * @param tableSetName The dataverse set name for the table that you are updating a record in
@@ -87,7 +88,7 @@ var API = {
87
88
  * @param data The JSON of the fields and data that are to be updated on the targeted record
88
89
  * @returns A Promise with the results of the API execution
89
90
  */
90
- updateRecord(tableSetName, recordId, data) {
91
+ static updateRecord(tableSetName, recordId, data) {
91
92
  return new Promise((resolve, reject) => {
92
93
  const url = `/_api/${tableSetName}(${recordId})`;
93
94
  safeAjax({
@@ -102,48 +103,14 @@ var API = {
102
103
  };
103
104
  var API_default = API;
104
105
 
105
- // src/DOMNodeReferenceArray.ts
106
- var DOMNodeReferenceArray = class extends Array {
107
- /**
108
- * Hides all the containers of the DOMNodeReference instances in the array.
109
- */
110
- hideAll() {
111
- this.forEach((instance) => instance.hide());
112
- return this;
113
- }
114
- /**
115
- * Shows all the containers of the DOMNodeReference instances in the array.
116
- */
117
- showAll() {
118
- this.forEach((instance) => instance.show());
119
- return this;
120
- }
121
- };
122
- function enhanceArray(array) {
123
- const enhancedArray = new DOMNodeReferenceArray(...array);
124
- return new Proxy(enhancedArray, {
125
- get(target, prop, receiver) {
126
- if (prop in target) {
127
- return Reflect.get(target, prop, receiver);
128
- }
129
- if (typeof prop === "string") {
130
- return target.find(
131
- (instance) => instance.target.toString().replace(/[#\[\]]/g, "") === prop || instance.logicalName === prop
132
- );
133
- }
134
- return void 0;
135
- }
136
- });
137
- }
138
-
139
- // src/waitFor.ts
140
- function waitFor(target, root = document, multiple = false, debounceTime) {
106
+ // src/core/waitFor.ts
107
+ function waitFor(target, root = document, multiple = false, debounceTime2) {
141
108
  return new Promise((resolve, reject) => {
142
109
  if (multiple) {
143
110
  let timeout;
144
111
  const observedElements = [];
145
112
  const observedSet = /* @__PURE__ */ new Set();
146
- if (debounceTime < 1) {
113
+ if (debounceTime2 < 1) {
147
114
  return resolve(
148
115
  Array.from(root.querySelectorAll(target))
149
116
  );
@@ -164,11 +131,11 @@ function waitFor(target, root = document, multiple = false, debounceTime) {
164
131
  } else {
165
132
  reject(
166
133
  new Error(
167
- `No elements found with target: "${target}" within ${debounceTime / 1e3} seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`
134
+ `No elements found with target: "${target}" within ${debounceTime2 / 1e3} seconds. If the element you are expecting has not loaded yet, consider raising your timeout.`
168
135
  )
169
136
  );
170
137
  }
171
- }, debounceTime);
138
+ }, debounceTime2);
172
139
  });
173
140
  observer.observe(root, {
174
141
  childList: true,
@@ -188,14 +155,10 @@ function waitFor(target, root = document, multiple = false, debounceTime) {
188
155
  observer.disconnect();
189
156
  reject(
190
157
  new Error(
191
- `Element not found by target: "${target}" within ${debounceTime / 1e3} second. If the element you are expecting has not loaded yet, consider raising your timeout.`
158
+ `Element not found by target: "${target}" within ${debounceTime2 / 1e3} second. If the element you are expecting has not loaded yet, consider raising your timeout.`
192
159
  )
193
160
  );
194
- }, debounceTime);
195
- if (target instanceof HTMLElement) {
196
- clearTimeout(timeout);
197
- return resolve(target);
198
- }
161
+ }, debounceTime2);
199
162
  const element = root.querySelector(target);
200
163
  if (element) {
201
164
  clearTimeout(timeout);
@@ -211,7 +174,7 @@ function waitFor(target, root = document, multiple = false, debounceTime) {
211
174
  });
212
175
  }
213
176
 
214
- // src/createInfoElement.ts
177
+ // src/utils/createInfoElement.ts
215
178
  function CreateInfoEl(titleString, iconStyle) {
216
179
  if (typeof titleString !== "string") {
217
180
  throw new Error(
@@ -275,7 +238,22 @@ function CreateInfoEl(titleString, iconStyle) {
275
238
  return span;
276
239
  }
277
240
 
278
- // src/errors.ts
241
+ // src/constants/symbols.ts
242
+ var init = Symbol("__I");
243
+ var destroy = Symbol("__D");
244
+ var valueSync = Symbol("__VS");
245
+ var dateSync = Symbol("__DS");
246
+ var getElementValue = Symbol("__GEV");
247
+ var attachVisibilityController = Symbol("__AVC");
248
+ var attachRadioButtons = Symbol("__ARB");
249
+ var bindMethods = Symbol("__B");
250
+ var debounceTime = Symbol("__DT");
251
+ var observers = Symbol("__O");
252
+ var boundEventListeners = Symbol("__BEV");
253
+ var isValidFormElement = Symbol("__VFE");
254
+ var registerEventListener = Symbol("__REV");
255
+
256
+ // src/errors/errors.ts
279
257
  var DOMNodeInitializationError = class extends Error {
280
258
  constructor(instance, error) {
281
259
  super(
@@ -303,29 +281,26 @@ var ValidationConfigError = class extends Error {
303
281
  }
304
282
  };
305
283
 
306
- // src/DOMNodeReference.ts
307
- var _init = Symbol("_I");
308
- var _destroy = Symbol("_D");
309
- var _valueSync = Symbol("_VS");
310
- var _dateSync = Symbol("_DS");
311
- var _getElementValue = Symbol("_GEV");
312
- var _updateRadioGroup = Symbol("_URG");
313
- var _attachVisibilityController = Symbol("_AVC");
314
- var _attachRadioButtons = Symbol("_ARB");
315
- var _bindMethods = Symbol("_B");
316
- var _debounceTime = Symbol("DT");
317
- var _observers = Symbol("O");
318
- var _boundEventListeners = Symbol("BEV");
284
+ // src/core/DOMNodeReference.ts
285
+ var EventTypes = {
286
+ CHECKBOX: "click",
287
+ RADIO: "click",
288
+ SELECT: "change",
289
+ TEXTAREA: "keyup",
290
+ DEFAULT: "input"
291
+ };
319
292
  var DOMNodeReference = class _DOMNodeReference {
320
293
  // properties initialized in the constructor
321
294
  target;
322
295
  logicalName;
323
296
  root;
324
- [_debounceTime];
297
+ [debounceTime];
325
298
  isLoaded;
326
299
  defaultDisplay;
327
- [_observers] = [];
328
- [_boundEventListeners] = [];
300
+ [observers] = [];
301
+ [boundEventListeners] = [];
302
+ isRadio = false;
303
+ radioType = null;
329
304
  /**
330
305
  * The value of the element that this node represents
331
306
  * stays in syncs with the live DOM elements?.,m via event handler
@@ -339,47 +314,51 @@ var DOMNodeReference = class _DOMNodeReference {
339
314
  */
340
315
  /******/
341
316
  /******/
342
- constructor(target, root = document.body, debounceTime) {
317
+ constructor(target, root = document.body, debounceTime2) {
343
318
  this.target = target;
344
- if (typeof target === "string") {
345
- let lName = null;
346
- const bracketMatch = target.match(/\[([^\]]+)\]/);
347
- if (bracketMatch) {
348
- lName = bracketMatch[1];
349
- const quoteMatch = lName.match(/["']([^"']+)["']/);
350
- if (quoteMatch) {
351
- lName = quoteMatch[1];
352
- }
353
- }
354
- this.logicalName = (lName || target).replace(/[#\[\]]/g, "");
355
- }
319
+ this.logicalName = this.extractLogicalName(target);
356
320
  this.root = root;
357
- this[_debounceTime] = debounceTime;
321
+ this[debounceTime] = debounceTime2;
358
322
  this.isLoaded = false;
359
323
  this.defaultDisplay = "";
360
324
  this.value = null;
361
- this[_bindMethods]();
325
+ this[bindMethods]();
362
326
  }
363
- async [_init]() {
327
+ extractLogicalName(target) {
328
+ if (typeof target !== "string") return "";
329
+ const bracketMatch = target.match(/\[([^\]]+)\]/);
330
+ if (!bracketMatch) return target.replace(/[#\[\]]/g, "");
331
+ const content = bracketMatch[1];
332
+ const quoteMatch = content.match(/["']([^"']+)["']/);
333
+ return (quoteMatch?.[1] || content).replace(/[#\[\]]/g, "");
334
+ }
335
+ async [init]() {
364
336
  try {
365
337
  if (this.target instanceof HTMLElement) {
366
338
  this.element = this.target;
367
339
  } else {
368
- this.element = await waitFor(this.target, this.root, false, this[_debounceTime]);
340
+ this.element = await waitFor(
341
+ this.target,
342
+ this.root,
343
+ false,
344
+ this[debounceTime]
345
+ );
369
346
  }
370
347
  if (!this.element) {
371
348
  throw new DOMNodeNotFoundError(this);
372
349
  }
373
- if (this.element.classList.contains("boolean-radio")) {
374
- await this[_attachRadioButtons]();
350
+ if (this.element.id && this.element.querySelectorAll(
351
+ `#${this.element.id} > input[type="radio"]`
352
+ ).length > 0) {
353
+ await this[attachRadioButtons]();
375
354
  }
376
- this[_valueSync]();
377
- this[_attachVisibilityController]();
355
+ this[valueSync]();
356
+ this[attachVisibilityController]();
378
357
  this.defaultDisplay = this.visibilityController.style.display;
379
358
  const observer = new MutationObserver((mutations) => {
380
359
  for (const mutation of mutations) {
381
360
  if (Array.from(mutation.removedNodes).includes(this.element)) {
382
- this[_destroy]();
361
+ this[destroy]();
383
362
  observer.disconnect();
384
363
  break;
385
364
  }
@@ -395,70 +374,65 @@ var DOMNodeReference = class _DOMNodeReference {
395
374
  throw new DOMNodeInitializationError(this, errorMessage);
396
375
  }
397
376
  }
398
- eventMapping = {
399
- checkbox: "click",
400
- radio: "click",
401
- select: "change",
402
- "select-multiple": "change",
403
- textarea: "keyup"
404
- // Add other input types as needed
405
- };
406
377
  /**
407
378
  * Initializes value synchronization with appropriate event listeners
408
379
  * based on element type.
409
- * @private
410
380
  */
411
- async [_valueSync]() {
412
- try {
413
- this.updateValue();
414
- let eventType;
415
- if (this.element instanceof HTMLSelectElement) {
416
- eventType = "change";
417
- } else if (this.element instanceof HTMLInputElement) {
418
- eventType = this.eventMapping[this.element.type] ?? "input";
419
- } else if (this.element instanceof HTMLTextAreaElement) {
420
- eventType = this.eventMapping[this.element.type] ?? "input";
421
- } else {
422
- eventType = "input";
423
- }
424
- this.element.addEventListener(eventType, this.updateValue);
425
- this[_boundEventListeners].push({
426
- element: this.element,
427
- handler: this.updateValue,
428
- event: eventType
429
- });
430
- if (this.element instanceof HTMLInputElement && this.element.dataset.type === "date") {
431
- await this[_dateSync](this.element);
432
- }
433
- } catch (error) {
434
- throw new DOMNodeInitializationError(
435
- this,
436
- `Failed to initialize value sync: ${error}`
437
- );
381
+ [valueSync]() {
382
+ if (!this[isValidFormElement](this.element)) return;
383
+ this.updateValue();
384
+ const eventType = this.determineEventType();
385
+ this[registerEventListener](this.element, eventType, this.updateValue);
386
+ if (this.isDateInput()) {
387
+ this[dateSync](this.element);
438
388
  }
439
389
  }
440
- async [_dateSync](element) {
390
+ determineEventType() {
391
+ if (this.element instanceof HTMLSelectElement) return "change";
392
+ if (!(this.element instanceof HTMLInputElement)) return EventTypes.DEFAULT;
393
+ return EventTypes[this.element.type.toUpperCase()] || EventTypes.DEFAULT;
394
+ }
395
+ isDateInput() {
396
+ return this.element instanceof HTMLInputElement && this.element.dataset.type === "date";
397
+ }
398
+ [isValidFormElement](element) {
399
+ return element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSpanElement || element instanceof HTMLButtonElement || element instanceof HTMLFieldSetElement;
400
+ }
401
+ [registerEventListener](element, eventType, handler) {
402
+ element.addEventListener(eventType, handler);
403
+ this[boundEventListeners].push({
404
+ element,
405
+ handler,
406
+ event: eventType
407
+ });
408
+ }
409
+ async [dateSync](element) {
441
410
  const parentElement = element.parentElement;
442
411
  if (!parentElement) {
443
412
  throw new Error("Date input must have a parent element");
444
413
  }
445
- const dateNode = await waitFor("[data-date-format]", parentElement, false, 1500);
446
- dateNode.addEventListener("select", this.updateValue);
447
- const _handler = this.updateValue;
448
- this[_boundEventListeners].push({
449
- element: dateNode,
450
- handler: _handler,
451
- event: "select"
452
- });
414
+ const dateNode = await waitFor(
415
+ "[data-date-format]",
416
+ parentElement,
417
+ false,
418
+ 1500
419
+ );
420
+ this[registerEventListener](dateNode, "select", this.updateValue);
453
421
  }
454
422
  /**
455
423
  * Gets the current value of the element based on its type
456
- * @private
424
+ * @protected
457
425
  * @returns Object containing value and optional checked state
458
426
  */
459
- [_getElementValue]() {
427
+ [getElementValue]() {
460
428
  const input = this.element;
461
429
  const select = this.element;
430
+ if (this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
431
+ return {
432
+ value: this.yesRadio.checked,
433
+ checked: this.yesRadio.checked
434
+ };
435
+ }
462
436
  switch (input.type) {
463
437
  case "checkbox":
464
438
  case "radio":
@@ -480,28 +454,18 @@ var DOMNodeReference = class _DOMNodeReference {
480
454
  return {
481
455
  value: input.value !== "" ? Number(input.value) : null
482
456
  };
483
- default:
457
+ default: {
484
458
  let cleanValue = input.value;
485
- if (this.element.classList.contains("decimal") || this.element.classList.contains("money"))
459
+ if (this.element.classList.contains("decimal") || this.element.classList.contains("money")) {
486
460
  cleanValue = input.value.replace(/[$,]/g, "");
461
+ }
487
462
  return {
488
463
  value: this.element.classList.contains("decimal") || this.element.classList.contains("money") ? parseFloat(cleanValue) : cleanValue
489
464
  };
465
+ }
490
466
  }
491
467
  }
492
- /**
493
- * Updates related radio buttons if this is part of a radio group
494
- * @private
495
- */
496
- [_updateRadioGroup]() {
497
- if (this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
498
- this.yesRadio.updateValue();
499
- this.noRadio?.updateValue();
500
- this.checked = this.yesRadio.checked;
501
- this.value = this.yesRadio.checked;
502
- }
503
- }
504
- [_attachVisibilityController]() {
468
+ [attachVisibilityController]() {
505
469
  this.visibilityController = this.element;
506
470
  if (this.element.tagName === "TABLE") {
507
471
  const fieldset = this.element.closest("fieldset");
@@ -524,11 +488,26 @@ var DOMNodeReference = class _DOMNodeReference {
524
488
  }
525
489
  }
526
490
  }
527
- async [_attachRadioButtons]() {
528
- this.yesRadio = await createDOMNodeReference(`#${this.element.id}_1`);
529
- this.noRadio = await createDOMNodeReference(`#${this.element.id}_0`);
491
+ async [attachRadioButtons]() {
492
+ if (!this.element) {
493
+ console.error(
494
+ "'this.element' not found: cannot attach radio buttons for ",
495
+ this.target
496
+ );
497
+ return;
498
+ }
499
+ this.yesRadio = await createDOMNodeReference('input[type="radio"][value="1"]', {
500
+ root: this.element
501
+ });
502
+ this.yesRadio.isRadio = true;
503
+ this.yesRadio.radioType = "truthy";
504
+ this.noRadio = await createDOMNodeReference('input[type="radio"][value="0"]', {
505
+ root: this.element
506
+ });
507
+ this.noRadio.isRadio = true;
508
+ this.noRadio.radioType = "falsy";
530
509
  }
531
- [_bindMethods]() {
510
+ [bindMethods]() {
532
511
  const prototype = Object.getPrototypeOf(this);
533
512
  for (const key of Object.getOwnPropertyNames(prototype)) {
534
513
  const value = this[key];
@@ -537,15 +516,15 @@ var DOMNodeReference = class _DOMNodeReference {
537
516
  }
538
517
  }
539
518
  }
540
- [_destroy]() {
541
- this[_boundEventListeners]?.forEach((binding) => {
519
+ [destroy]() {
520
+ this[boundEventListeners]?.forEach((binding) => {
542
521
  binding.element?.removeEventListener(binding.event, binding.handler);
543
522
  });
544
- this[_observers]?.forEach((observer) => {
523
+ this[observers]?.forEach((observer) => {
545
524
  observer.disconnect();
546
525
  });
547
- this.yesRadio?.[_destroy]();
548
- this.noRadio?.[_destroy]();
526
+ this.yesRadio?.[destroy]();
527
+ this.noRadio?.[destroy]();
549
528
  this.yesRadio = null;
550
529
  this.noRadio = null;
551
530
  this.isLoaded = false;
@@ -555,13 +534,19 @@ var DOMNodeReference = class _DOMNodeReference {
555
534
  * Updates the value and checked state based on element type
556
535
  * @public
557
536
  */
558
- updateValue() {
559
- const elementValue = this[_getElementValue]();
537
+ updateValue(e) {
538
+ if (e) {
539
+ e.stopPropagation();
540
+ }
541
+ if (this.yesRadio && this.noRadio) {
542
+ this.yesRadio.updateValue();
543
+ this.noRadio.updateValue();
544
+ }
545
+ const elementValue = this[getElementValue]();
560
546
  this.value = elementValue.value;
561
547
  if (elementValue.checked !== void 0) {
562
548
  this.checked = elementValue.checked;
563
549
  }
564
- this[_updateRadioGroup]();
565
550
  }
566
551
  /**
567
552
  * Sets up an event listener based on the specified event type, executing the specified
@@ -577,14 +562,11 @@ var DOMNodeReference = class _DOMNodeReference {
577
562
  `Argument "eventHandler" must be a Function. Received: ${typeof eventHandler}`
578
563
  );
579
564
  }
580
- this.element.addEventListener(eventType, eventHandler.bind(this));
581
- const _element = this.element;
582
- const _handler = eventHandler;
583
- this[_boundEventListeners].push({
584
- element: _element,
585
- handler: _handler,
586
- event: eventType
587
- });
565
+ this[registerEventListener](
566
+ this.element,
567
+ eventType,
568
+ eventHandler.bind(this)
569
+ );
588
570
  return this;
589
571
  }
590
572
  /**
@@ -604,7 +586,6 @@ var DOMNodeReference = class _DOMNodeReference {
604
586
  return this;
605
587
  }
606
588
  /**
607
- *
608
589
  * @param shouldShow - Either a function that returns true or false,
609
590
  * or a natural boolean to determine the visibility of this
610
591
  * @returns - Instance of this [provides option to method chain]
@@ -628,21 +609,17 @@ var DOMNodeReference = class _DOMNodeReference {
628
609
  if (value instanceof Function) {
629
610
  value = value();
630
611
  }
631
- let eventType;
632
- if (this.element instanceof HTMLSelectElement) {
633
- eventType = "change";
634
- } else if (this.element instanceof HTMLInputElement) {
635
- eventType = this.eventMapping[this.element.type] ?? "input";
636
- } else if (this.element instanceof HTMLTextAreaElement) {
637
- eventType = this.eventMapping[this.element.type] ?? "input";
638
- } else {
639
- eventType = "input";
640
- }
612
+ const eventType = this.determineEventType();
641
613
  this.element.dispatchEvent(new Event(eventType, { bubbles: false }));
642
- if (this.element.classList.contains("boolean-radio") && this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
614
+ if (this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
643
615
  this.yesRadio.element.checked = value;
644
616
  this.noRadio.element.checked = !value;
645
617
  this.value = value;
618
+ this.checked = value;
619
+ this.element.checked = value;
620
+ } else if (this.isRadio || this.element.type === "radio") {
621
+ this.checked = value;
622
+ this.element.checked = value;
646
623
  } else {
647
624
  this.element.value = value;
648
625
  }
@@ -711,7 +688,9 @@ var DOMNodeReference = class _DOMNodeReference {
711
688
  );
712
689
  if (childInputs.length > 0) {
713
690
  const promises = childInputs.map(async (input) => {
714
- const inputRef = await createDOMNodeReference(input, { multiple: false });
691
+ const inputRef = await createDOMNodeReference(
692
+ input
693
+ );
715
694
  return inputRef.clearValue();
716
695
  });
717
696
  await Promise.all(promises);
@@ -740,7 +719,7 @@ var DOMNodeReference = class _DOMNodeReference {
740
719
  enable() {
741
720
  try {
742
721
  this.element.disabled = false;
743
- } catch (e) {
722
+ } catch (_error) {
744
723
  throw new Error(
745
724
  `There was an error trying to disable the target: ${this.target}`
746
725
  );
@@ -748,7 +727,6 @@ var DOMNodeReference = class _DOMNodeReference {
748
727
  return this;
749
728
  }
750
729
  /**
751
- *
752
730
  * @param elements - The elements to prepend to the element targeted by this.
753
731
  * @returns - Instance of this [provides option to method chain]
754
732
  */
@@ -830,7 +808,6 @@ var DOMNodeReference = class _DOMNodeReference {
830
808
  return this;
831
809
  }
832
810
  /**
833
- *
834
811
  * @param options and object containing the styles you want to set : {key: value} e.g.: {'display': 'block'}
835
812
  * @returns - Instance of this [provides option to method chain]
836
813
  */
@@ -851,7 +828,7 @@ var DOMNodeReference = class _DOMNodeReference {
851
828
  * @returns - Instance of this [provides option to method chain]
852
829
  */
853
830
  uncheckRadios() {
854
- if (this.yesRadio && this.noRadio) {
831
+ if (this.yesRadio instanceof _DOMNodeReference && this.noRadio instanceof _DOMNodeReference) {
855
832
  this.yesRadio.element.checked = false;
856
833
  this.noRadio.element.checked = false;
857
834
  } else {
@@ -863,7 +840,7 @@ var DOMNodeReference = class _DOMNodeReference {
863
840
  }
864
841
  /**
865
842
  * Applies a business rule to manage visibility, required state, value, and disabled state dynamically.
866
- *
843
+ * @see {@link BusinessRule}
867
844
  * @param rule The business rule containing conditions for various actions.
868
845
  * @param dependencies For re-evaluation conditions when the state of the dependencies change
869
846
  * @returns Instance of this for method chaining.
@@ -872,11 +849,11 @@ var DOMNodeReference = class _DOMNodeReference {
872
849
  try {
873
850
  if (rule.setVisibility) {
874
851
  const [condition, clearValuesOnHide = true] = rule.setVisibility;
875
- const initialState = condition.bind(this)();
852
+ const initialState = condition.call(this);
876
853
  this.toggleVisibility(initialState);
877
854
  if (dependencies.length) {
878
855
  this._configDependencyTracking(
879
- () => this.toggleVisibility(condition.bind(this)()),
856
+ () => this.toggleVisibility(condition.call(this)),
880
857
  dependencies,
881
858
  {
882
859
  clearValuesOnHide,
@@ -891,12 +868,11 @@ var DOMNodeReference = class _DOMNodeReference {
891
868
  const [isRequired, isValid] = rule.setRequired;
892
869
  const fieldDisplayName = (() => {
893
870
  let label = this.getLabel();
894
- if (!label)
895
- return new Error(
896
- `There was an error accessing the label for this element: ${String(
897
- this.target
898
- )}`
871
+ if (!label) {
872
+ throw new Error(
873
+ `There was an error accessing the label for this element: ${this.target}`
899
874
  );
875
+ }
900
876
  label = label.innerHTML;
901
877
  if (label.length > 50) {
902
878
  label = label.substring(0, 50) + "...";
@@ -914,15 +890,15 @@ var DOMNodeReference = class _DOMNodeReference {
914
890
  controltovalidate: this.element.id,
915
891
  errormessage: `<a href='#${this.element.id}_label'>${fieldDisplayName} is a required field</a>`,
916
892
  evaluationfunction: () => {
917
- const isFieldRequired = isRequired.bind(this)();
893
+ const isFieldRequired = isRequired.call(this);
918
894
  const isFieldVisible = window.getComputedStyle(this.visibilityController).display !== "none";
919
- return !isFieldRequired || !isFieldVisible || isValid.bind(this)();
895
+ return !isFieldRequired || !isFieldVisible || isValid.call(this, isFieldRequired);
920
896
  }
921
897
  });
922
898
  Page_Validators.push(newValidator);
923
- this.setRequiredLevel(isRequired.bind(this)());
899
+ this.setRequiredLevel(isRequired.call(this));
924
900
  this._configDependencyTracking(
925
- () => this.setRequiredLevel(isRequired.bind(this)()),
901
+ () => this.setRequiredLevel(isRequired.call(this)),
926
902
  dependencies,
927
903
  { clearValuesOnHide: false }
928
904
  );
@@ -930,14 +906,14 @@ var DOMNodeReference = class _DOMNodeReference {
930
906
  if (rule.setValue) {
931
907
  let [condition, value] = rule.setValue;
932
908
  if (value instanceof Function) value = value();
933
- if (condition.bind(this)()) {
934
- this.setValue.bind(this)(value);
909
+ if (condition.call(this)) {
910
+ this.setValue.call(this, value);
935
911
  }
936
912
  if (dependencies.length) {
937
913
  this._configDependencyTracking(
938
914
  () => {
939
- if (condition.bind(this)()) {
940
- this.setValue.bind(this)(value);
915
+ if (condition.call(this)) {
916
+ this.setValue.call(this, value);
941
917
  }
942
918
  },
943
919
  dependencies,
@@ -947,11 +923,11 @@ var DOMNodeReference = class _DOMNodeReference {
947
923
  }
948
924
  if (rule.setDisabled) {
949
925
  const condition = rule.setDisabled;
950
- condition.bind(this)() ? this.disable() : this.enable();
926
+ condition.call(this) ? this.disable() : this.enable();
951
927
  if (dependencies.length) {
952
928
  this._configDependencyTracking(
953
929
  () => {
954
- condition.bind(this)() ? this.enable() : this.disable();
930
+ condition.call(this) ? this.enable() : this.disable();
955
931
  },
956
932
  dependencies,
957
933
  {
@@ -1070,7 +1046,7 @@ var DOMNodeReference = class _DOMNodeReference {
1070
1046
  }
1071
1047
  /**
1072
1048
  * Sets up tracking for dependencies using both event listeners and mutation observers.
1073
- * @private
1049
+ * @protected
1074
1050
  * @param handler The function to execute when dependencies change
1075
1051
  * @param dependencies Array of dependent DOM nodes to track
1076
1052
  * @param options Additional configuration options. clearValuesOnHide defaults to false.
@@ -1106,19 +1082,9 @@ var DOMNodeReference = class _DOMNodeReference {
1106
1082
  this.clearValue();
1107
1083
  }
1108
1084
  };
1109
- dep.on("change", handleChange);
1110
- this[_boundEventListeners].push({
1111
- element: dep.element,
1112
- event: "change",
1113
- handler: handleChange
1114
- });
1085
+ this[registerEventListener](dep.element, "change", handleChange);
1115
1086
  if (trackInputEvents) {
1116
- dep.on("input", handleChange);
1117
- this[_boundEventListeners].push({
1118
- element: dep.element,
1119
- event: "input",
1120
- handler: handleChange
1121
- });
1087
+ this[registerEventListener](dep.element, "input", handleChange);
1122
1088
  }
1123
1089
  if (observeVisibility) {
1124
1090
  const observer = new MutationObserver(() => {
@@ -1134,12 +1100,12 @@ var DOMNodeReference = class _DOMNodeReference {
1134
1100
  attributeFilter: ["style"],
1135
1101
  subtree: false
1136
1102
  });
1137
- this[_observers].push(observer);
1103
+ this[observers].push(observer);
1138
1104
  }
1139
1105
  if (trackRadioButtons && dep.yesRadio && dep.noRadio) {
1140
1106
  [dep.yesRadio, dep.noRadio].forEach((radio) => {
1141
1107
  radio.on("change", handleChange);
1142
- this[_boundEventListeners].push({
1108
+ this[boundEventListeners].push({
1143
1109
  element: radio.element,
1144
1110
  event: "change",
1145
1111
  handler: handleChange
@@ -1191,15 +1157,51 @@ var DOMNodeReference = class _DOMNodeReference {
1191
1157
  subtree: true,
1192
1158
  childList: true
1193
1159
  });
1194
- this[_observers].push(observer);
1160
+ this[observers].push(observer);
1195
1161
  }
1196
1162
  };
1197
1163
 
1198
- // src/createDOMNodeReferences.ts
1164
+ // src/core/DOMNodeReferenceArray.ts
1165
+ var DOMNodeReferenceArray = class extends Array {
1166
+ /**
1167
+ * Hides all the containers of the DOMNodeReference instances in the array.
1168
+ */
1169
+ hideAll() {
1170
+ this.forEach((instance) => instance.hide());
1171
+ return this;
1172
+ }
1173
+ /**
1174
+ * Shows all the containers of the DOMNodeReference instances in the array.
1175
+ */
1176
+ showAll() {
1177
+ this.forEach((instance) => instance.show());
1178
+ return this;
1179
+ }
1180
+ };
1181
+
1182
+ // src/utils/enhanceArray.ts
1183
+ function enhanceArray(array) {
1184
+ const enhancedArray = new DOMNodeReferenceArray(...array);
1185
+ return new Proxy(enhancedArray, {
1186
+ get(target, prop, receiver) {
1187
+ if (prop in target) {
1188
+ return Reflect.get(target, prop, receiver);
1189
+ }
1190
+ if (typeof prop === "string") {
1191
+ return target.find(
1192
+ (instance) => instance.target.toString().replace(/[#\[\]]/g, "") === prop || instance.logicalName === prop
1193
+ );
1194
+ }
1195
+ return void 0;
1196
+ }
1197
+ });
1198
+ }
1199
+
1200
+ // src/core/createDOMNodeReferences.ts
1199
1201
  async function createDOMNodeReference(target, options = {
1200
1202
  multiple: false,
1201
1203
  root: document.body,
1202
- timeout: 0
1204
+ timeoutMs: 0
1203
1205
  }) {
1204
1206
  try {
1205
1207
  if (typeof options !== "object") {
@@ -1208,7 +1210,7 @@ async function createDOMNodeReference(target, options = {
1208
1210
  );
1209
1211
  }
1210
1212
  validateOptions(options);
1211
- const { multiple = false, root = document.body, timeout = 0 } = options;
1213
+ const { multiple = false, root = document.body, timeoutMs = 0 } = options;
1212
1214
  const isMultiple = typeof multiple === "function" ? multiple() : multiple;
1213
1215
  if (isMultiple) {
1214
1216
  if (typeof target !== "string") {
@@ -1216,25 +1218,25 @@ async function createDOMNodeReference(target, options = {
1216
1218
  `'target' must be of type 'string' if 'multiple' is set to 'true'. Received type: '${typeof target}'`
1217
1219
  );
1218
1220
  }
1219
- const elements = await waitFor(target, root, true, timeout);
1221
+ const elements = await waitFor(target, root, true, timeoutMs);
1220
1222
  const initializedElements = await Promise.all(
1221
1223
  elements.map(async (element) => {
1222
- const instance2 = new DOMNodeReference(element, root, timeout);
1223
- await instance2[_init]();
1224
+ const instance2 = new DOMNodeReference(element, root, timeoutMs);
1225
+ await instance2[init]();
1224
1226
  return new Proxy(instance2, createProxyHandler());
1225
1227
  })
1226
1228
  );
1227
1229
  return enhanceArray(initializedElements);
1228
1230
  }
1229
- const instance = new DOMNodeReference(target, root, timeout);
1230
- await instance[_init]();
1231
+ const instance = new DOMNodeReference(target, root, timeoutMs);
1232
+ await instance[init]();
1231
1233
  return new Proxy(instance, createProxyHandler());
1232
1234
  } catch (e) {
1233
1235
  throw new Error(e);
1234
1236
  }
1235
1237
  }
1236
1238
  function validateOptions(options) {
1237
- const { multiple = false, root = document.body, timeout = 0 } = options;
1239
+ const { multiple = false, root = document.body, timeoutMs = 0 } = options;
1238
1240
  if (typeof multiple !== "boolean" && typeof multiple !== "function") {
1239
1241
  throw new Error(
1240
1242
  `'multiple' must be of type 'boolean' or 'function'. Received type: '${typeof multiple}'`
@@ -1253,9 +1255,9 @@ function validateOptions(options) {
1253
1255
  `'root' must be of type 'HTMLElement'. Received type: '${typeof root}'`
1254
1256
  );
1255
1257
  }
1256
- if (typeof timeout !== "number") {
1258
+ if (typeof timeoutMs !== "number") {
1257
1259
  throw new Error(
1258
- `'timeout' must be of type 'number'. Received type: '${typeof timeout}'`
1260
+ `'timeout' must be of type 'number'. Received type: '${typeof timeoutMs}'`
1259
1261
  );
1260
1262
  }
1261
1263
  return;
@@ -1276,7 +1278,7 @@ function createProxyHandler() {
1276
1278
  };
1277
1279
  }
1278
1280
 
1279
- // src/bindForm.ts
1281
+ // src/core/bindForm.ts
1280
1282
  async function bindForm(formId) {
1281
1283
  try {
1282
1284
  const form = await API_default.getRecord("systemforms", formId);
@@ -1324,8 +1326,9 @@ function getIdentifyingAttribute(tagName) {
1324
1326
  }
1325
1327
  function createReferenceString(tagName, datafieldname) {
1326
1328
  if (tagName === "control") return `#${datafieldname}`;
1327
- if (tagName === "tab" || tagName === "section")
1329
+ if (tagName === "tab" || tagName === "section") {
1328
1330
  return `[data-name="${datafieldname}"]`;
1331
+ }
1329
1332
  return null;
1330
1333
  }
1331
1334
  export {
@@ -1334,11 +1337,13 @@ export {
1334
1337
  createDOMNodeReference as createRef,
1335
1338
  waitFor
1336
1339
  };
1340
+ /*! For license information please see index.js.LEGAL.txt */
1341
+ //# sourceMappingURL=index.js.map
1337
1342
 
1338
1343
 
1339
- (function() {
1340
- const style = document.createElement('style');
1341
- style.textContent = "/* src/style.css */\n.info-icon {\n position: relative;\n display: inline-block;\n}\n.info-icon .fa-info-circle {\n cursor: pointer;\n}\n.info-icon .flyout-content {\n max-width: calc(100vw - 20px);\n display: none;\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n color: #000;\n background-color: #f9f9f9;\n padding: 10px;\n border: 1px solid #ddd;\n z-index: 1;\n min-width: 200px;\n box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);\n border-radius: 4px;\n}\n@media (max-width: 600px) {\n .info-icon .flyout-content {\n max-width: 95vw;\n padding: 12px;\n font-size: 0.9em;\n display: block;\n right: auto;\n }\n}\n.required-field::after {\n content: \" *\" !important;\n color: #f00 !important;\n}\n";
1342
- document.head.appendChild(style);
1343
- })();
1344
-
1344
+ if (typeof document !== 'undefined') {
1345
+ const style = document.createElement('style');
1346
+ style.textContent = ".info-icon {\r\n position: relative;\r\n display: inline-block;\r\n}\r\n\r\n.info-icon .fa-info-circle {\r\n cursor: pointer; /* Ensures the icon is recognized as interactive */\r\n}\r\n\r\n.info-icon .flyout-content {\r\n max-width: calc(100vw - 20px); /* 20px margin on both sides */\r\n display: none; /* Initially hidden */\r\n position: absolute;\r\n left: 50%; /* Center horizontally */\r\n transform: translateX(-50%); /* Adjust positioning */\r\n color: #000;\r\n background-color: #f9f9f9;\r\n padding: 10px;\r\n border: 1px solid #ddd;\r\n z-index: 1;\r\n min-width: 200px; /* Minimum width for better readability */\r\n box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);\r\n border-radius: 4px; /* Rounded corners */\r\n}\r\n\r\n@media (max-width: 600px) {\r\n .info-icon .flyout-content {\r\n max-width: 95vw;\r\n padding: 12px;\r\n font-size: 0.9em;\r\n display: block;\r\n right: auto;\r\n }\r\n}\r\n\r\n.required-field::after {\r\n content: \" *\" !important;\r\n color: #f00 !important;\r\n}\r\n";
1347
+ document.head.appendChild(style);
1348
+ }
1349
+