@4site/engrid-scripts 0.19.1
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/.prettierrc.js +226 -0
- package/LICENSE +24 -0
- package/dist/a11y.d.ts +6 -0
- package/dist/a11y.js +46 -0
- package/dist/add-name-to-message.d.ts +5 -0
- package/dist/add-name-to-message.js +49 -0
- package/dist/advocacy.d.ts +7 -0
- package/dist/advocacy.js +34 -0
- package/dist/amount-label.d.ts +6 -0
- package/dist/amount-label.js +29 -0
- package/dist/app.d.ts +19 -0
- package/dist/app.js +340 -0
- package/dist/apple-pay.d.ts +13 -0
- package/dist/apple-pay.js +169 -0
- package/dist/auto-country-select.d.ts +10 -0
- package/dist/auto-country-select.js +63 -0
- package/dist/auto-year.d.ts +7 -0
- package/dist/auto-year.js +35 -0
- package/dist/autocomplete.d.ts +5 -0
- package/dist/autocomplete.js +38 -0
- package/dist/autosubmit.d.ts +5 -0
- package/dist/autosubmit.js +14 -0
- package/dist/branding-html.d.ts +14 -0
- package/dist/branding-html.js +70 -0
- package/dist/capitalize-fields.d.ts +7 -0
- package/dist/capitalize-fields.js +22 -0
- package/dist/click-to-expand.d.ts +4 -0
- package/dist/click-to-expand.js +39 -0
- package/dist/cookie.d.ts +53 -0
- package/dist/cookie.js +76 -0
- package/dist/country-disable.d.ts +4 -0
- package/dist/country-disable.js +22 -0
- package/dist/country-redirect.d.ts +7 -0
- package/dist/country-redirect.js +61 -0
- package/dist/custom-currency.d.ts +9 -0
- package/dist/custom-currency.js +112 -0
- package/dist/data-attributes.d.ts +5 -0
- package/dist/data-attributes.js +122 -0
- package/dist/data-hide.d.ts +15 -0
- package/dist/data-hide.js +66 -0
- package/dist/data-layer.d.ts +23 -0
- package/dist/data-layer.js +312 -0
- package/dist/data-replace.d.ts +26 -0
- package/dist/data-replace.js +76 -0
- package/dist/debug-hidden-fields.d.ts +4 -0
- package/dist/debug-hidden-fields.js +42 -0
- package/dist/debug-panel.d.ts +27 -0
- package/dist/debug-panel.js +508 -0
- package/dist/deprecated.d.ts +5 -0
- package/dist/deprecated.js +40 -0
- package/dist/digital-wallets.d.ts +8 -0
- package/dist/digital-wallets.js +143 -0
- package/dist/ecard-to-target.d.ts +11 -0
- package/dist/ecard-to-target.js +73 -0
- package/dist/ecard.d.ts +8 -0
- package/dist/ecard.js +61 -0
- package/dist/embedded-ecard.d.ts +18 -0
- package/dist/embedded-ecard.js +267 -0
- package/dist/en-validators.d.ts +10 -0
- package/dist/en-validators.js +89 -0
- package/dist/engrid.d.ts +49 -0
- package/dist/engrid.js +547 -0
- package/dist/event-tickets.d.ts +3 -0
- package/dist/event-tickets.js +24 -0
- package/dist/events/country.d.ts +12 -0
- package/dist/events/country.js +42 -0
- package/dist/events/donation-amount.d.ts +16 -0
- package/dist/events/donation-amount.js +119 -0
- package/dist/events/donation-frequency.d.ts +17 -0
- package/dist/events/donation-frequency.js +115 -0
- package/dist/events/en-form.d.ts +20 -0
- package/dist/events/en-form.js +52 -0
- package/dist/events/index.d.ts +6 -0
- package/dist/events/index.js +6 -0
- package/dist/events/processing-fees.d.ts +20 -0
- package/dist/events/processing-fees.js +92 -0
- package/dist/events/remember-me-events.d.ts +18 -0
- package/dist/events/remember-me-events.js +36 -0
- package/dist/exit-intent-lightbox.d.ts +14 -0
- package/dist/exit-intent-lightbox.js +145 -0
- package/dist/expand-region-name.d.ts +7 -0
- package/dist/expand-region-name.js +44 -0
- package/dist/fast-form-fill.d.ts +8 -0
- package/dist/fast-form-fill.js +75 -0
- package/dist/freshaddress.d.ts +18 -0
- package/dist/freshaddress.js +204 -0
- package/dist/give-by-select.d.ts +9 -0
- package/dist/give-by-select.js +82 -0
- package/dist/iframe.d.ts +16 -0
- package/dist/iframe.js +217 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +84 -0
- package/dist/input-has-value-and-focus.d.ts +9 -0
- package/dist/input-has-value-and-focus.js +50 -0
- package/dist/input-placeholders.d.ts +7 -0
- package/dist/input-placeholders.js +82 -0
- package/dist/interfaces/ecard-to-target-options.d.ts +9 -0
- package/dist/interfaces/ecard-to-target-options.js +8 -0
- package/dist/interfaces/embedded-ecard-options.d.ts +8 -0
- package/dist/interfaces/embedded-ecard-options.js +7 -0
- package/dist/interfaces/exit-intent-options.d.ts +13 -0
- package/dist/interfaces/exit-intent-options.js +13 -0
- package/dist/interfaces/options.d.ts +147 -0
- package/dist/interfaces/options.js +50 -0
- package/dist/interfaces/translate-options.d.ts +7 -0
- package/dist/interfaces/translate-options.js +42 -0
- package/dist/interfaces/upsell-options.d.ts +24 -0
- package/dist/interfaces/upsell-options.js +33 -0
- package/dist/live-currency.d.ts +15 -0
- package/dist/live-currency.js +140 -0
- package/dist/live-frequency.d.ts +13 -0
- package/dist/live-frequency.js +109 -0
- package/dist/live-variables.d.ts +21 -0
- package/dist/live-variables.js +147 -0
- package/dist/loader.d.ts +10 -0
- package/dist/loader.js +175 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +84 -0
- package/dist/media-attribution.d.ts +4 -0
- package/dist/media-attribution.js +66 -0
- package/dist/menu.d.ts +0 -0
- package/dist/menu.js +1 -0
- package/dist/min-max-amount.d.ts +13 -0
- package/dist/min-max-amount.js +71 -0
- package/dist/mobile-cta.d.ts +9 -0
- package/dist/mobile-cta.js +71 -0
- package/dist/modal.d.ts +19 -0
- package/dist/modal.js +129 -0
- package/dist/neverbounce.d.ts +23 -0
- package/dist/neverbounce.js +244 -0
- package/dist/other-amount.d.ts +6 -0
- package/dist/other-amount.js +70 -0
- package/dist/page-background.d.ts +7 -0
- package/dist/page-background.js +55 -0
- package/dist/plaid.d.ts +6 -0
- package/dist/plaid.js +49 -0
- package/dist/postal-code-validator.d.ts +20 -0
- package/dist/postal-code-validator.js +118 -0
- package/dist/premium-gift.d.ts +10 -0
- package/dist/premium-gift.js +115 -0
- package/dist/progress-bar.d.ts +3 -0
- package/dist/progress-bar.js +40 -0
- package/dist/remember-me.d.ts +61 -0
- package/dist/remember-me.js +358 -0
- package/dist/required-if-visible.d.ts +8 -0
- package/dist/required-if-visible.js +60 -0
- package/dist/set-attr.d.ts +4 -0
- package/dist/set-attr.js +31 -0
- package/dist/set-recurr-freq.d.ts +7 -0
- package/dist/set-recurr-freq.js +70 -0
- package/dist/show-hide-radio-checkboxes.d.ts +13 -0
- package/dist/show-hide-radio-checkboxes.js +161 -0
- package/dist/show-if-amount.d.ts +15 -0
- package/dist/show-if-amount.js +117 -0
- package/dist/show-if-present.d.ts +7 -0
- package/dist/show-if-present.js +79 -0
- package/dist/skip-link.d.ts +4 -0
- package/dist/skip-link.js +36 -0
- package/dist/src-defer.d.ts +6 -0
- package/dist/src-defer.js +70 -0
- package/dist/supporter-hub.d.ts +9 -0
- package/dist/supporter-hub.js +75 -0
- package/dist/swap-amounts.d.ts +45 -0
- package/dist/swap-amounts.js +81 -0
- package/dist/thank-you-page-conditional-content.d.ts +8 -0
- package/dist/thank-you-page-conditional-content.js +46 -0
- package/dist/ticker.d.ts +11 -0
- package/dist/ticker.js +66 -0
- package/dist/tidycontact.d.ts +46 -0
- package/dist/tidycontact.js +1202 -0
- package/dist/translate-fields.d.ts +12 -0
- package/dist/translate-fields.js +548 -0
- package/dist/universal-opt-in.d.ts +7 -0
- package/dist/universal-opt-in.js +91 -0
- package/dist/upsell-lightbox.d.ts +31 -0
- package/dist/upsell-lightbox.js +363 -0
- package/dist/url-params-to-body-attrs.d.ts +5 -0
- package/dist/url-params-to-body-attrs.js +14 -0
- package/dist/url-to-form.d.ts +7 -0
- package/dist/url-to-form.js +32 -0
- package/dist/us-only-form.d.ts +4 -0
- package/dist/us-only-form.js +30 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/dist/vgs.d.ts +16 -0
- package/dist/vgs.js +250 -0
- package/dist/welcome-back.d.ts +10 -0
- package/dist/welcome-back.js +112 -0
- package/package.json +32 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Component that adds data attributes to the Body
|
|
2
|
+
import { ENGrid, Country } from ".";
|
|
3
|
+
export class DataAttributes {
|
|
4
|
+
constructor() {
|
|
5
|
+
this._country = Country.getInstance();
|
|
6
|
+
this.setDataAttributes();
|
|
7
|
+
}
|
|
8
|
+
setDataAttributes() {
|
|
9
|
+
// Add the Page Type as a Data Attribute on the Body Tag
|
|
10
|
+
if (ENGrid.checkNested(window, "pageJson", "pageType")) {
|
|
11
|
+
ENGrid.setBodyData("page-type", window.pageJson.pageType);
|
|
12
|
+
}
|
|
13
|
+
// Add the currency code as a Data Attribute on the Body Tag
|
|
14
|
+
ENGrid.setBodyData("currency-code", ENGrid.getCurrencyCode());
|
|
15
|
+
// Add a body banner data attribute if the banner contains no image or video
|
|
16
|
+
if (!document.querySelector(".body-banner img, .body-banner video")) {
|
|
17
|
+
ENGrid.setBodyData("body-banner", "empty");
|
|
18
|
+
}
|
|
19
|
+
// Add a page-alert data attribute if it is empty
|
|
20
|
+
if (!document.querySelector(".page-alert *")) {
|
|
21
|
+
ENGrid.setBodyData("no-page-alert", "");
|
|
22
|
+
}
|
|
23
|
+
// Add a content-header data attribute if it is empty
|
|
24
|
+
if (!document.querySelector(".content-header *")) {
|
|
25
|
+
ENGrid.setBodyData("no-content-header", "");
|
|
26
|
+
}
|
|
27
|
+
// Add a body-headerOutside data attribute if it is empty
|
|
28
|
+
if (!document.querySelector(".body-headerOutside *")) {
|
|
29
|
+
ENGrid.setBodyData("no-body-headerOutside", "");
|
|
30
|
+
}
|
|
31
|
+
// Add a body-header data attribute if it is empty
|
|
32
|
+
if (!document.querySelector(".body-header *")) {
|
|
33
|
+
ENGrid.setBodyData("no-body-header", "");
|
|
34
|
+
}
|
|
35
|
+
// Add a body-title data attribute if it is empty
|
|
36
|
+
if (!document.querySelector(".body-title *")) {
|
|
37
|
+
ENGrid.setBodyData("no-body-title", "");
|
|
38
|
+
}
|
|
39
|
+
// Add a body-banner data attribute if it is empty
|
|
40
|
+
if (!document.querySelector(".body-banner *")) {
|
|
41
|
+
ENGrid.setBodyData("no-body-banner", "");
|
|
42
|
+
}
|
|
43
|
+
// Add a body-bannerOverlay data attribute if it is empty
|
|
44
|
+
if (!document.querySelector(".body-bannerOverlay *")) {
|
|
45
|
+
ENGrid.setBodyData("no-body-bannerOverlay", "");
|
|
46
|
+
}
|
|
47
|
+
// Add a body-top data attribute if it is empty
|
|
48
|
+
if (!document.querySelector(".body-top *")) {
|
|
49
|
+
ENGrid.setBodyData("no-body-top", "");
|
|
50
|
+
}
|
|
51
|
+
// Add a body-main data attribute if it is empty
|
|
52
|
+
if (!document.querySelector(".body-main *")) {
|
|
53
|
+
ENGrid.setBodyData("no-body-main", "");
|
|
54
|
+
}
|
|
55
|
+
// Add a body-bottom data attribute if it is empty
|
|
56
|
+
if (!document.querySelector(".body-bottom *")) {
|
|
57
|
+
ENGrid.setBodyData("no-body-bottom", "");
|
|
58
|
+
}
|
|
59
|
+
// Add a body-footer data attribute if it is empty
|
|
60
|
+
if (!document.querySelector(".body-footer *")) {
|
|
61
|
+
ENGrid.setBodyData("no-body-footer", "");
|
|
62
|
+
}
|
|
63
|
+
// Add a body-footerOutside data attribute if it is empty
|
|
64
|
+
if (!document.querySelector(".body-footerOutside *")) {
|
|
65
|
+
ENGrid.setBodyData("no-body-footerOutside", "");
|
|
66
|
+
}
|
|
67
|
+
// Add a content-footerSpacer data attribute if it is empty
|
|
68
|
+
if (!document.querySelector(".content-footerSpacer *")) {
|
|
69
|
+
ENGrid.setBodyData("no-content-footerSpacer", "");
|
|
70
|
+
}
|
|
71
|
+
// Add a content-preFooter data attribute if it is empty
|
|
72
|
+
if (!document.querySelector(".content-preFooter *")) {
|
|
73
|
+
ENGrid.setBodyData("no-content-preFooter", "");
|
|
74
|
+
}
|
|
75
|
+
// Add a content-footer data attribute if it is empty
|
|
76
|
+
if (!document.querySelector(".content-footer *")) {
|
|
77
|
+
ENGrid.setBodyData("no-content-footer", "");
|
|
78
|
+
}
|
|
79
|
+
// Add a page-backgroundImage banner data attribute if the page background image contains no image or video
|
|
80
|
+
if (!document.querySelector(".page-backgroundImage img, .page-backgroundImage video")) {
|
|
81
|
+
ENGrid.setBodyData("no-page-backgroundImage", "");
|
|
82
|
+
}
|
|
83
|
+
// Add a page-backgroundImageOverlay data attribute if it is empty
|
|
84
|
+
if (!document.querySelector(".page-backgroundImageOverlay *")) {
|
|
85
|
+
ENGrid.setBodyData("no-page-backgroundImageOverlay", "");
|
|
86
|
+
}
|
|
87
|
+
// Add a page-customCode data attribute if it is empty
|
|
88
|
+
if (!document.querySelector(".page-customCode *")) {
|
|
89
|
+
ENGrid.setBodyData("no-page-customCode", "");
|
|
90
|
+
}
|
|
91
|
+
// Add a country data attribute
|
|
92
|
+
if (this._country.country) {
|
|
93
|
+
ENGrid.setBodyData("country", this._country.country);
|
|
94
|
+
this._country.onCountryChange.subscribe((country) => {
|
|
95
|
+
ENGrid.setBodyData("country", country);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const otherAmountDiv = document.querySelector(".en__field--donationAmt .en__field__item--other");
|
|
99
|
+
if (otherAmountDiv) {
|
|
100
|
+
otherAmountDiv.setAttribute("data-currency-symbol", ENGrid.getCurrencySymbol());
|
|
101
|
+
}
|
|
102
|
+
// Add a payment type data attribute
|
|
103
|
+
const paymentTypeSelect = ENGrid.getField("transaction.paymenttype");
|
|
104
|
+
if (paymentTypeSelect) {
|
|
105
|
+
ENGrid.setBodyData("payment-type", paymentTypeSelect.value);
|
|
106
|
+
paymentTypeSelect.addEventListener("change", () => {
|
|
107
|
+
ENGrid.setBodyData("payment-type", paymentTypeSelect.value);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Footer in Viewport Check
|
|
111
|
+
const contentFooter = document.querySelector(".content-footer");
|
|
112
|
+
if (contentFooter && ENGrid.isInViewport(contentFooter)) {
|
|
113
|
+
ENGrid.setBodyData("footer-above-fold", "");
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
ENGrid.setBodyData("footer-below-fold", "");
|
|
117
|
+
}
|
|
118
|
+
// Add demo data attribute
|
|
119
|
+
if (ENGrid.demo)
|
|
120
|
+
ENGrid.setBodyData("demo", "");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class DataHide {
|
|
2
|
+
private logger;
|
|
3
|
+
private enElements;
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Hides all the elements based on the URL arguments.
|
|
7
|
+
*/
|
|
8
|
+
hideAll(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Hides a specific element based on the item and type.
|
|
11
|
+
* @param item - The item to hide (ID or class name).
|
|
12
|
+
* @param type - The type of the item (either "id" or "class").
|
|
13
|
+
*/
|
|
14
|
+
hideItem(item: string, type: "id" | "class"): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Hides elements based on URL arguments.
|
|
2
|
+
//
|
|
3
|
+
// The DataHide class is used to hide elements based on URL arguments.
|
|
4
|
+
// It retrieves the elements to hide from the URL arguments and hides them.
|
|
5
|
+
// If no elements are found, the constructor returns early.
|
|
6
|
+
// Otherwise, it logs the found elements and hides them.
|
|
7
|
+
import { ENGrid, EngridLogger } from ".";
|
|
8
|
+
export class DataHide {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.logger = new EngridLogger("DataHide", "#333333", "#f0f0f0", "🙈");
|
|
11
|
+
this.enElements = new Array();
|
|
12
|
+
this.logger.log("Constructor");
|
|
13
|
+
this.enElements = ENGrid.getUrlParameter("engrid_hide[]");
|
|
14
|
+
if (!this.enElements || this.enElements.length === 0) {
|
|
15
|
+
this.logger.log("No Elements Found");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.logger.log("Elements Found:", this.enElements);
|
|
19
|
+
this.hideAll();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Hides all the elements based on the URL arguments.
|
|
23
|
+
*/
|
|
24
|
+
hideAll() {
|
|
25
|
+
this.enElements.forEach((element) => {
|
|
26
|
+
const item = Object.keys(element)[0];
|
|
27
|
+
const type = Object.values(element)[0];
|
|
28
|
+
this.hideItem(item, type);
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Hides a specific element based on the item and type.
|
|
34
|
+
* @param item - The item to hide (ID or class name).
|
|
35
|
+
* @param type - The type of the item (either "id" or "class").
|
|
36
|
+
*/
|
|
37
|
+
hideItem(item, type) {
|
|
38
|
+
const regEx = /engrid_hide\[([\w-]+)\]/g;
|
|
39
|
+
const itemData = [...item.matchAll(regEx)].map((match) => match[1])[0];
|
|
40
|
+
switch (type) {
|
|
41
|
+
case "id":
|
|
42
|
+
const element = document.getElementById(itemData);
|
|
43
|
+
if (element) {
|
|
44
|
+
this.logger.log("Hiding By ID", itemData, element);
|
|
45
|
+
element.setAttribute("hidden-via-url-argument", "");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.logger.error("Element Not Found By ID", itemData);
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case "class":
|
|
52
|
+
default:
|
|
53
|
+
const elements = document.getElementsByClassName(itemData);
|
|
54
|
+
if (elements.length > 0) {
|
|
55
|
+
for (let i = 0; i < elements.length; i++) {
|
|
56
|
+
this.logger.log("Hiding By Class", itemData, elements[i]);
|
|
57
|
+
elements[i].setAttribute("hidden-via-url-argument", "");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.logger.log("No Elements Found By Class", itemData);
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare class DataLayer {
|
|
2
|
+
private logger;
|
|
3
|
+
private dataLayer;
|
|
4
|
+
private _form;
|
|
5
|
+
private static instance;
|
|
6
|
+
private endOfGiftProcessStorageKey;
|
|
7
|
+
private excludedFields;
|
|
8
|
+
private hashedFields;
|
|
9
|
+
constructor();
|
|
10
|
+
static getInstance(): DataLayer;
|
|
11
|
+
private transformJSON;
|
|
12
|
+
private onLoad;
|
|
13
|
+
private onSubmit;
|
|
14
|
+
private attachEventListeners;
|
|
15
|
+
private handleFieldValueChange;
|
|
16
|
+
private hash;
|
|
17
|
+
private getFieldLabel;
|
|
18
|
+
addEndOfGiftProcessEvent(eventName: string, eventProperties?: object): void;
|
|
19
|
+
addEndOfGiftProcessVariable(variableName: string, variableValue?: any): void;
|
|
20
|
+
private storeEndOfGiftProcessData;
|
|
21
|
+
private addEndOfGiftProcessEventsToDataLayer;
|
|
22
|
+
private getEndOfGiftProcessData;
|
|
23
|
+
}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// The DataLayer class is a singleton class that is responsible for managing the data layer events.
|
|
2
|
+
// It listens to the EnForm onSubmit event and the RememberMe onLoad event.
|
|
3
|
+
// It also listens to the blur, change, and submit events of the form fields.
|
|
4
|
+
// It adds the following events to the data layer:
|
|
5
|
+
// - EN_PAGE_VIEW
|
|
6
|
+
// - EN_SUCCESSFUL_DONATION
|
|
7
|
+
// - EN_PAGEJSON_{property}
|
|
8
|
+
// - EN_SUBMISSION_SUCCESS_{pageType}
|
|
9
|
+
// - EN_URLPARAM_{key}-{value}
|
|
10
|
+
// - EN_RECURRING_FREQUENCIES
|
|
11
|
+
// - EN_FASTFORMFILL_PERSONALINFO_SUCCESS
|
|
12
|
+
// - EN_FASTFORMFILL_PERSONALINFO_PARTIALSUCCESS
|
|
13
|
+
// - EN_FASTFORMFILL_PERSONALINFO_FAILURE
|
|
14
|
+
// - EN_FASTFORMFILL_ADDRESS_SUCCESS
|
|
15
|
+
// - EN_FASTFORMFILL_ADDRESS_PARTIALSUCCESS
|
|
16
|
+
// - EN_FASTFORMFILL_ADDRESS_FAILURE
|
|
17
|
+
// - EN_FASTFORMFILL_ALL_SUCCESS
|
|
18
|
+
// - EN_FASTFORMFILL_ALL_FAILURE
|
|
19
|
+
// - EN_SUBMISSION_WITH_EMAIL_OPTIN
|
|
20
|
+
// - EN_SUBMISSION_WITHOUT_EMAIL_OPTIN
|
|
21
|
+
// - EN_FORM_VALUE_UPDATED
|
|
22
|
+
import { EngridLogger, ENGrid, EnForm, FastFormFill, RememberMeEvents, } from ".";
|
|
23
|
+
export class DataLayer {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.logger = new EngridLogger("DataLayer", "#f1e5bc", "#009cdc", "📊");
|
|
26
|
+
this.dataLayer = window.dataLayer || [];
|
|
27
|
+
this._form = EnForm.getInstance();
|
|
28
|
+
this.endOfGiftProcessStorageKey = "ENGRID_END_OF_GIFT_PROCESS_EVENTS";
|
|
29
|
+
this.excludedFields = [
|
|
30
|
+
// Credit Card
|
|
31
|
+
"transaction.ccnumber",
|
|
32
|
+
"transaction.ccexpire.delimiter",
|
|
33
|
+
"transaction.ccexpire",
|
|
34
|
+
"transaction.ccvv",
|
|
35
|
+
"supporter.creditCardHolderName",
|
|
36
|
+
// Bank Account
|
|
37
|
+
"supporter.bankAccountNumber",
|
|
38
|
+
"supporter.bankAccountType",
|
|
39
|
+
"transaction.bankname",
|
|
40
|
+
"supporter.bankRoutingNumber",
|
|
41
|
+
];
|
|
42
|
+
this.hashedFields = [
|
|
43
|
+
// Supporter Address, Phone Numbers, and Address
|
|
44
|
+
"supporter.emailAddress",
|
|
45
|
+
"supporter.phoneNumber",
|
|
46
|
+
"supporter.phoneNumber2",
|
|
47
|
+
"supporter.address1",
|
|
48
|
+
"supporter.address2",
|
|
49
|
+
"supporter.address3",
|
|
50
|
+
// In Honor/Memory Inform Email and Address
|
|
51
|
+
"transaction.infemail",
|
|
52
|
+
"transaction.infadd1",
|
|
53
|
+
"transaction.infadd2",
|
|
54
|
+
"transaction.infadd3",
|
|
55
|
+
// Billing Address
|
|
56
|
+
"supporter.billingAddress1",
|
|
57
|
+
"supporter.billingAddress2",
|
|
58
|
+
"supporter.billingAddress3",
|
|
59
|
+
];
|
|
60
|
+
if (ENGrid.getOption("RememberMe")) {
|
|
61
|
+
RememberMeEvents.getInstance().onLoad.subscribe((hasData) => {
|
|
62
|
+
this.logger.log("Remember me - onLoad", hasData);
|
|
63
|
+
this.onLoad();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.onLoad();
|
|
68
|
+
}
|
|
69
|
+
this._form.onSubmit.subscribe(() => this.onSubmit());
|
|
70
|
+
}
|
|
71
|
+
static getInstance() {
|
|
72
|
+
if (!DataLayer.instance) {
|
|
73
|
+
DataLayer.instance = new DataLayer();
|
|
74
|
+
window._dataLayer = DataLayer.instance;
|
|
75
|
+
}
|
|
76
|
+
return DataLayer.instance;
|
|
77
|
+
}
|
|
78
|
+
transformJSON(value) {
|
|
79
|
+
if (typeof value === "string") {
|
|
80
|
+
return value.toUpperCase().split(" ").join("-").replace(":-", "-");
|
|
81
|
+
}
|
|
82
|
+
else if (typeof value === "boolean") {
|
|
83
|
+
value = value ? "TRUE" : "FALSE";
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
return "";
|
|
87
|
+
}
|
|
88
|
+
onLoad() {
|
|
89
|
+
if (ENGrid.getGiftProcess()) {
|
|
90
|
+
this.logger.log("EN_SUCCESSFUL_DONATION");
|
|
91
|
+
this.dataLayer.push({
|
|
92
|
+
event: "EN_SUCCESSFUL_DONATION",
|
|
93
|
+
});
|
|
94
|
+
this.addEndOfGiftProcessEventsToDataLayer();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.logger.log("EN_PAGE_VIEW");
|
|
98
|
+
this.dataLayer.push({
|
|
99
|
+
event: "EN_PAGE_VIEW",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (window.pageJson) {
|
|
103
|
+
const pageJson = window.pageJson;
|
|
104
|
+
for (const property in pageJson) {
|
|
105
|
+
if (!Number.isNaN(pageJson[property])) {
|
|
106
|
+
this.dataLayer.push({
|
|
107
|
+
event: `EN_PAGEJSON_${property.toUpperCase()}-${pageJson[property]}`,
|
|
108
|
+
});
|
|
109
|
+
this.dataLayer.push({
|
|
110
|
+
[`'EN_PAGEJSON_${property.toUpperCase()}'`]: pageJson[property],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.dataLayer.push({
|
|
115
|
+
event: `EN_PAGEJSON_${property.toUpperCase()}-${this.transformJSON(pageJson[property])}`,
|
|
116
|
+
});
|
|
117
|
+
this.dataLayer.push({
|
|
118
|
+
[`'EN_PAGEJSON_${property.toUpperCase()}'`]: this.transformJSON(pageJson[property]),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
this.dataLayer.push({
|
|
122
|
+
event: "EN_PAGEJSON_" + property.toUpperCase(),
|
|
123
|
+
eventValue: pageJson[property],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (ENGrid.getPageCount() === ENGrid.getPageNumber()) {
|
|
127
|
+
this.dataLayer.push({
|
|
128
|
+
event: "EN_SUBMISSION_SUCCESS_" + pageJson.pageType.toUpperCase(),
|
|
129
|
+
});
|
|
130
|
+
this.dataLayer.push({
|
|
131
|
+
[`'EN_SUBMISSION_SUCCESS_${pageJson.pageType.toUpperCase()}'`]: "TRUE",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
136
|
+
urlParams.forEach((value, key) => {
|
|
137
|
+
this.dataLayer.push({
|
|
138
|
+
event: `EN_URLPARAM_${key.toUpperCase()}-${this.transformJSON(value)}`,
|
|
139
|
+
});
|
|
140
|
+
this.dataLayer.push({
|
|
141
|
+
[`'EN_URLPARAM_${key.toUpperCase()}'`]: this.transformJSON(value),
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
if (ENGrid.getPageType() === "DONATION") {
|
|
145
|
+
const recurrFreqEls = document.querySelectorAll('[name="transaction.recurrfreq"]');
|
|
146
|
+
const recurrValues = [...recurrFreqEls].map((el) => el.value);
|
|
147
|
+
this.dataLayer.push({
|
|
148
|
+
event: "EN_RECURRING_FREQUENCIES",
|
|
149
|
+
[`'EN_RECURRING_FREQEUENCIES'`]: recurrValues,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
let fastFormFill = false;
|
|
153
|
+
// Fast Form Fill - Personal Details
|
|
154
|
+
const fastPersonalDetailsFormBlock = document.querySelector(".en__component--formblock.fast-personal-details");
|
|
155
|
+
if (fastPersonalDetailsFormBlock) {
|
|
156
|
+
const allPersonalMandatoryInputsAreFilled = FastFormFill.allMandatoryInputsAreFilled(fastPersonalDetailsFormBlock);
|
|
157
|
+
const somePersonalMandatoryInputsAreFilled = FastFormFill.someMandatoryInputsAreFilled(fastPersonalDetailsFormBlock);
|
|
158
|
+
if (allPersonalMandatoryInputsAreFilled) {
|
|
159
|
+
this.dataLayer.push({
|
|
160
|
+
event: "EN_FASTFORMFILL_PERSONALINFO_SUCCESS",
|
|
161
|
+
});
|
|
162
|
+
fastFormFill = true;
|
|
163
|
+
}
|
|
164
|
+
else if (somePersonalMandatoryInputsAreFilled) {
|
|
165
|
+
this.dataLayer.push({
|
|
166
|
+
event: "EN_FASTFORMFILL_PERSONALINFO_PARTIALSUCCESS",
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.dataLayer.push({
|
|
171
|
+
event: "EN_FASTFORMFILL_PERSONALINFO_FAILURE",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Fast Form Fill - Address Details
|
|
176
|
+
const fastAddressDetailsFormBlock = document.querySelector(".en__component--formblock.fast-address-details");
|
|
177
|
+
if (fastAddressDetailsFormBlock) {
|
|
178
|
+
const allAddressMandatoryInputsAreFilled = FastFormFill.allMandatoryInputsAreFilled(fastAddressDetailsFormBlock);
|
|
179
|
+
const someAddressMandatoryInputsAreFilled = FastFormFill.someMandatoryInputsAreFilled(fastAddressDetailsFormBlock);
|
|
180
|
+
if (allAddressMandatoryInputsAreFilled) {
|
|
181
|
+
this.dataLayer.push({
|
|
182
|
+
event: "EN_FASTFORMFILL_ADDRESS_SUCCESS",
|
|
183
|
+
});
|
|
184
|
+
fastFormFill = fastFormFill ? true : false; // Only set to true if it was true before
|
|
185
|
+
}
|
|
186
|
+
else if (someAddressMandatoryInputsAreFilled) {
|
|
187
|
+
this.dataLayer.push({
|
|
188
|
+
event: "EN_FASTFORMFILL_ADDRESS_PARTIALSUCCESS",
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
this.dataLayer.push({
|
|
193
|
+
event: "EN_FASTFORMFILL_ADDRESS_FAILURE",
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (fastFormFill) {
|
|
198
|
+
this.dataLayer.push({
|
|
199
|
+
event: "EN_FASTFORMFILL_ALL_SUCCESS",
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
this.dataLayer.push({
|
|
204
|
+
event: "EN_FASTFORMFILL_ALL_FAILURE",
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
this.attachEventListeners();
|
|
208
|
+
}
|
|
209
|
+
onSubmit() {
|
|
210
|
+
const optIn = document.querySelector(".en__field__item:not(.en__field--question) input[name^='supporter.questions'][type='checkbox']:checked");
|
|
211
|
+
if (optIn) {
|
|
212
|
+
this.logger.log("EN_SUBMISSION_WITH_EMAIL_OPTIN");
|
|
213
|
+
this.dataLayer.push({
|
|
214
|
+
event: "EN_SUBMISSION_WITH_EMAIL_OPTIN",
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
this.logger.log("EN_SUBMISSION_WITHOUT_EMAIL_OPTIN");
|
|
219
|
+
this.dataLayer.push({
|
|
220
|
+
event: "EN_SUBMISSION_WITHOUT_EMAIL_OPTIN",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
attachEventListeners() {
|
|
225
|
+
const textInputs = document.querySelectorAll(".en__component--advrow input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=hidden]):not([unhidden]), .en__component--advrow textarea");
|
|
226
|
+
textInputs.forEach((el) => {
|
|
227
|
+
el.addEventListener("blur", (e) => {
|
|
228
|
+
this.handleFieldValueChange(e.target);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
const radioAndCheckboxInputs = document.querySelectorAll(".en__component--advrow input[type=checkbox], .en__component--advrow input[type=radio]");
|
|
232
|
+
radioAndCheckboxInputs.forEach((el) => {
|
|
233
|
+
el.addEventListener("change", (e) => {
|
|
234
|
+
this.handleFieldValueChange(e.target);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
const selectInputs = document.querySelectorAll(".en__component--advrow select");
|
|
238
|
+
selectInputs.forEach((el) => {
|
|
239
|
+
el.addEventListener("change", (e) => {
|
|
240
|
+
this.handleFieldValueChange(e.target);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
handleFieldValueChange(el) {
|
|
245
|
+
var _a, _b, _c;
|
|
246
|
+
if (el.value === "" || this.excludedFields.includes(el.name))
|
|
247
|
+
return;
|
|
248
|
+
const value = this.hashedFields.includes(el.name)
|
|
249
|
+
? this.hash(el.value)
|
|
250
|
+
: el.value;
|
|
251
|
+
if (["checkbox", "radio"].includes(el.type)) {
|
|
252
|
+
if (el.checked) {
|
|
253
|
+
if (el.name === "en__pg") {
|
|
254
|
+
//Premium gift handling
|
|
255
|
+
this.dataLayer.push({
|
|
256
|
+
event: "EN_FORM_VALUE_UPDATED",
|
|
257
|
+
enFieldName: el.name,
|
|
258
|
+
enFieldLabel: "Premium Gift",
|
|
259
|
+
enFieldValue: (_b = (_a = el
|
|
260
|
+
.closest(".en__pg__body")) === null || _a === void 0 ? void 0 : _a.querySelector(".en__pg__name")) === null || _b === void 0 ? void 0 : _b.textContent,
|
|
261
|
+
enProductId: (_c = document.querySelector('[name="transaction.selprodvariantid"]')) === null || _c === void 0 ? void 0 : _c.value,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
this.dataLayer.push({
|
|
266
|
+
event: "EN_FORM_VALUE_UPDATED",
|
|
267
|
+
enFieldName: el.name,
|
|
268
|
+
enFieldLabel: this.getFieldLabel(el),
|
|
269
|
+
enFieldValue: value,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.dataLayer.push({
|
|
276
|
+
event: "EN_FORM_VALUE_UPDATED",
|
|
277
|
+
enFieldName: el.name,
|
|
278
|
+
enFieldLabel: this.getFieldLabel(el),
|
|
279
|
+
enFieldValue: value,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
hash(value) {
|
|
283
|
+
return btoa(value);
|
|
284
|
+
}
|
|
285
|
+
getFieldLabel(el) {
|
|
286
|
+
var _a, _b;
|
|
287
|
+
return ((_b = (_a = el.closest(".en__field")) === null || _a === void 0 ? void 0 : _a.querySelector("label")) === null || _b === void 0 ? void 0 : _b.textContent) || "";
|
|
288
|
+
}
|
|
289
|
+
addEndOfGiftProcessEvent(eventName, eventProperties = {}) {
|
|
290
|
+
this.storeEndOfGiftProcessData(Object.assign({ event: eventName }, eventProperties));
|
|
291
|
+
}
|
|
292
|
+
addEndOfGiftProcessVariable(variableName, variableValue = "") {
|
|
293
|
+
this.storeEndOfGiftProcessData({
|
|
294
|
+
[`'${variableName.toUpperCase()}'`]: variableValue,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
storeEndOfGiftProcessData(data) {
|
|
298
|
+
const events = this.getEndOfGiftProcessData();
|
|
299
|
+
events.push(data);
|
|
300
|
+
window.sessionStorage.setItem(this.endOfGiftProcessStorageKey, JSON.stringify(events));
|
|
301
|
+
}
|
|
302
|
+
addEndOfGiftProcessEventsToDataLayer() {
|
|
303
|
+
this.getEndOfGiftProcessData().forEach((event) => {
|
|
304
|
+
this.dataLayer.push(event);
|
|
305
|
+
});
|
|
306
|
+
window.sessionStorage.removeItem(this.endOfGiftProcessStorageKey);
|
|
307
|
+
}
|
|
308
|
+
getEndOfGiftProcessData() {
|
|
309
|
+
let eventsData = window.sessionStorage.getItem(this.endOfGiftProcessStorageKey);
|
|
310
|
+
return !eventsData ? [] : JSON.parse(eventsData);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class DataReplace {
|
|
2
|
+
private logger;
|
|
3
|
+
private enElements;
|
|
4
|
+
constructor();
|
|
5
|
+
/**
|
|
6
|
+
* Searches for HTML elements containing the data to be replaced.
|
|
7
|
+
*/
|
|
8
|
+
searchElements(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if there are elements to be replaced.
|
|
11
|
+
* @returns True if there are elements to be replaced, false otherwise.
|
|
12
|
+
*/
|
|
13
|
+
shouldRun(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Replaces all occurrences of data in the HTML elements.
|
|
16
|
+
*/
|
|
17
|
+
replaceAll(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Replaces a specific data item in the given HTML element.
|
|
20
|
+
* @param where The HTML element where the replacement should occur.
|
|
21
|
+
* @param item The matched data item.
|
|
22
|
+
* @param key The key of the data item.
|
|
23
|
+
* @param defaultValue The default value to use if the data item is not found.
|
|
24
|
+
*/
|
|
25
|
+
replaceItem(where: HTMLElement, [item, key, defaultValue]: RegExpMatchArray): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// This script is used to replace merge tags in the EN Blocks of the page.
|
|
2
|
+
// It searches for HTML elements containing the data to be replaced and replaces it.
|
|
3
|
+
// The data to be replaced is passed as URL parameters, example: ?engrid_data[key]=value.
|
|
4
|
+
// The merge tag, if found, is replaced with the value from the URL parameter.
|
|
5
|
+
// If no value is found, the default value is used.
|
|
6
|
+
// The default value is the value inside the merge tag, example: {engrid_data~key~default}.
|
|
7
|
+
// If no default value is set, an empty string is used.
|
|
8
|
+
import { ENGrid, EngridLogger } from ".";
|
|
9
|
+
export class DataReplace {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.logger = new EngridLogger("DataReplace", "#333333", "#00f3ff", "⤵️");
|
|
12
|
+
this.enElements = new Array();
|
|
13
|
+
this.searchElements();
|
|
14
|
+
if (!this.shouldRun())
|
|
15
|
+
return;
|
|
16
|
+
this.logger.log("Elements Found:", this.enElements);
|
|
17
|
+
this.replaceAll();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Searches for HTML elements containing the data to be replaced.
|
|
21
|
+
*/
|
|
22
|
+
searchElements() {
|
|
23
|
+
const enElements = document.querySelectorAll(`
|
|
24
|
+
.en__component--copyblock,
|
|
25
|
+
.en__component--codeblock,
|
|
26
|
+
.en__field
|
|
27
|
+
`);
|
|
28
|
+
if (enElements.length > 0) {
|
|
29
|
+
enElements.forEach((item) => {
|
|
30
|
+
if (item instanceof HTMLElement &&
|
|
31
|
+
item.innerHTML.includes("{engrid_data~")) {
|
|
32
|
+
this.enElements.push(item);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Checks if there are elements to be replaced.
|
|
39
|
+
* @returns True if there are elements to be replaced, false otherwise.
|
|
40
|
+
*/
|
|
41
|
+
shouldRun() {
|
|
42
|
+
return this.enElements.length > 0;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Replaces all occurrences of data in the HTML elements.
|
|
46
|
+
*/
|
|
47
|
+
replaceAll() {
|
|
48
|
+
const regEx = /{engrid_data~\[([\w-]+)\]~?\[?(.+?)?\]?}/g;
|
|
49
|
+
this.enElements.forEach((item) => {
|
|
50
|
+
const array = item.innerHTML.matchAll(regEx);
|
|
51
|
+
for (const match of array) {
|
|
52
|
+
this.replaceItem(item, match);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
ENGrid.setBodyData("merge-tags-processed", "");
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Replaces a specific data item in the given HTML element.
|
|
59
|
+
* @param where The HTML element where the replacement should occur.
|
|
60
|
+
* @param item The matched data item.
|
|
61
|
+
* @param key The key of the data item.
|
|
62
|
+
* @param defaultValue The default value to use if the data item is not found.
|
|
63
|
+
*/
|
|
64
|
+
replaceItem(where, [item, key, defaultValue]) {
|
|
65
|
+
var _a;
|
|
66
|
+
let value = (_a = ENGrid.getUrlParameter(`engrid_data[${key}]`)) !== null && _a !== void 0 ? _a : defaultValue;
|
|
67
|
+
if (typeof value === "string") {
|
|
68
|
+
value = value.replace(/\r?\\n|\n|\r/g, "<br>");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
value = "";
|
|
72
|
+
}
|
|
73
|
+
this.logger.log("Replacing", key, value);
|
|
74
|
+
where.innerHTML = where.innerHTML.replace(item, value);
|
|
75
|
+
}
|
|
76
|
+
}
|