@4site/engrid-scripts 0.22.15 → 0.22.17
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/dist/data-layer.js +26 -93
- package/dist/interfaces/options.d.ts +1 -0
- package/dist/interfaces/options.js +1 -0
- package/dist/min-max-amount.d.ts +3 -0
- package/dist/min-max-amount.js +56 -1
- package/dist/swap-amounts.d.ts +2 -0
- package/dist/swap-amounts.js +6 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/data-layer.js
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
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 ".";
|
|
1
|
+
// DataLayer: singleton helper for pushing structured analytics events/vars to window.dataLayer.
|
|
2
|
+
// On load it emits one aggregated event `pageJsonVariablesReady` with:
|
|
3
|
+
// EN_PAGEJSON_* (normalized pageJson), EN_URLPARAM_*, EN_RECURRING_FREQUENCIES (donation pages),
|
|
4
|
+
// and EN_SUBMISSION_SUCCESS_{PAGETYPE} when on the final page.
|
|
5
|
+
// User actions emit: EN_FORM_VALUE_UPDATED (field changes) and submission opt‑in/out events.
|
|
6
|
+
// Queued end‑of‑gift events/variables (via addEndOfGiftProcessEvent / addEndOfGiftProcessVariable)
|
|
7
|
+
// are replayed after a successful gift process load.
|
|
8
|
+
// Sensitive payment/bank fields are excluded; selected PII fields are Base64 “hashed” (btoa — not cryptographic).
|
|
9
|
+
// Replace with a real hash (e.g., SHA‑256) if required.
|
|
10
|
+
import { EngridLogger, ENGrid, EnForm, RememberMeEvents } from ".";
|
|
23
11
|
export class DataLayer {
|
|
24
12
|
constructor() {
|
|
25
13
|
this.logger = new EngridLogger("DataLayer", "#f1e5bc", "#009cdc", "📊");
|
|
@@ -77,108 +65,53 @@ export class DataLayer {
|
|
|
77
65
|
}
|
|
78
66
|
transformJSON(value) {
|
|
79
67
|
if (typeof value === "string") {
|
|
80
|
-
return value
|
|
68
|
+
return value
|
|
69
|
+
.toUpperCase()
|
|
70
|
+
.trim()
|
|
71
|
+
.replace(/\s+/g, "-")
|
|
72
|
+
.replace(/:-/g, "-");
|
|
81
73
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
if (typeof value === "boolean") {
|
|
75
|
+
return value ? "TRUE" : "FALSE";
|
|
76
|
+
}
|
|
77
|
+
if (typeof value === "number") {
|
|
78
|
+
return value; // Preserve numeric type for analytics platforms that infer number vs string
|
|
85
79
|
}
|
|
86
80
|
return "";
|
|
87
81
|
}
|
|
88
82
|
onLoad() {
|
|
89
|
-
// Collect all data layer
|
|
83
|
+
// Collect all data layer variables to push at once
|
|
90
84
|
const dataLayerData = {};
|
|
91
|
-
const dataLayerEvents = [];
|
|
92
85
|
if (ENGrid.getGiftProcess()) {
|
|
93
86
|
this.logger.log("EN_SUCCESSFUL_DONATION");
|
|
94
|
-
dataLayerEvents.push("EN_SUCCESSFUL_DONATION");
|
|
95
87
|
this.addEndOfGiftProcessEventsToDataLayer();
|
|
96
88
|
}
|
|
97
|
-
else {
|
|
98
|
-
this.logger.log("EN_PAGE_VIEW");
|
|
99
|
-
dataLayerEvents.push("EN_PAGE_VIEW");
|
|
100
|
-
}
|
|
101
89
|
if (window.pageJson) {
|
|
102
90
|
const pageJson = window.pageJson;
|
|
103
91
|
for (const property in pageJson) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
pageJson[property];
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
dataLayerEvents.push(`EN_PAGEJSON_${property.toUpperCase()}-${this.transformJSON(pageJson[property])}`);
|
|
111
|
-
dataLayerData[`EN_PAGEJSON_${property.toUpperCase()}`] =
|
|
112
|
-
this.transformJSON(pageJson[property]);
|
|
113
|
-
}
|
|
114
|
-
dataLayerEvents.push("EN_PAGEJSON_" + property.toUpperCase());
|
|
115
|
-
dataLayerData.eventValue = pageJson[property];
|
|
92
|
+
const key = `EN_PAGEJSON_${property.toUpperCase()}`;
|
|
93
|
+
const value = pageJson[property];
|
|
94
|
+
dataLayerData[key] = this.transformJSON(value);
|
|
116
95
|
}
|
|
117
96
|
if (ENGrid.getPageCount() === ENGrid.getPageNumber()) {
|
|
118
|
-
dataLayerEvents.push("EN_SUBMISSION_SUCCESS_" + pageJson.pageType.toUpperCase());
|
|
119
97
|
dataLayerData[`EN_SUBMISSION_SUCCESS_${pageJson.pageType.toUpperCase()}`] = "TRUE";
|
|
120
98
|
}
|
|
121
99
|
}
|
|
122
100
|
const urlParams = new URLSearchParams(window.location.search);
|
|
123
101
|
urlParams.forEach((value, key) => {
|
|
124
|
-
dataLayerEvents.push(`EN_URLPARAM_${key.toUpperCase()}-${this.transformJSON(value)}`);
|
|
125
102
|
dataLayerData[`EN_URLPARAM_${key.toUpperCase()}`] =
|
|
126
103
|
this.transformJSON(value);
|
|
127
104
|
});
|
|
128
105
|
if (ENGrid.getPageType() === "DONATION") {
|
|
129
106
|
const recurrFreqEls = document.querySelectorAll('[name="transaction.recurrfreq"]');
|
|
130
107
|
const recurrValues = [...recurrFreqEls].map((el) => el.value);
|
|
131
|
-
|
|
132
|
-
dataLayerData[`'EN_RECURRING_FREQEUENCIES'`] = recurrValues;
|
|
133
|
-
}
|
|
134
|
-
let fastFormFill = false;
|
|
135
|
-
// Fast Form Fill - Personal Details
|
|
136
|
-
const fastPersonalDetailsFormBlock = document.querySelector(".en__component--formblock.fast-personal-details");
|
|
137
|
-
if (fastPersonalDetailsFormBlock) {
|
|
138
|
-
const allPersonalMandatoryInputsAreFilled = FastFormFill.allMandatoryInputsAreFilled(fastPersonalDetailsFormBlock);
|
|
139
|
-
const somePersonalMandatoryInputsAreFilled = FastFormFill.someMandatoryInputsAreFilled(fastPersonalDetailsFormBlock);
|
|
140
|
-
if (allPersonalMandatoryInputsAreFilled) {
|
|
141
|
-
dataLayerEvents.push("EN_FASTFORMFILL_PERSONALINFO_SUCCESS");
|
|
142
|
-
fastFormFill = true;
|
|
143
|
-
}
|
|
144
|
-
else if (somePersonalMandatoryInputsAreFilled) {
|
|
145
|
-
dataLayerEvents.push("EN_FASTFORMFILL_PERSONALINFO_PARTIALSUCCESS");
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
dataLayerEvents.push("EN_FASTFORMFILL_PERSONALINFO_FAILURE");
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// Fast Form Fill - Address Details
|
|
152
|
-
const fastAddressDetailsFormBlock = document.querySelector(".en__component--formblock.fast-address-details");
|
|
153
|
-
if (fastAddressDetailsFormBlock) {
|
|
154
|
-
const allAddressMandatoryInputsAreFilled = FastFormFill.allMandatoryInputsAreFilled(fastAddressDetailsFormBlock);
|
|
155
|
-
const someAddressMandatoryInputsAreFilled = FastFormFill.someMandatoryInputsAreFilled(fastAddressDetailsFormBlock);
|
|
156
|
-
if (allAddressMandatoryInputsAreFilled) {
|
|
157
|
-
dataLayerEvents.push("EN_FASTFORMFILL_ADDRESS_SUCCESS");
|
|
158
|
-
fastFormFill = fastFormFill ? true : false; // Only set to true if it was true before
|
|
159
|
-
}
|
|
160
|
-
else if (someAddressMandatoryInputsAreFilled) {
|
|
161
|
-
dataLayerEvents.push("EN_FASTFORMFILL_ADDRESS_PARTIALSUCCESS");
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
dataLayerEvents.push("EN_FASTFORMFILL_ADDRESS_FAILURE");
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
if (fastFormFill) {
|
|
168
|
-
dataLayerEvents.push("EN_FASTFORMFILL_ALL_SUCCESS");
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
dataLayerEvents.push("EN_FASTFORMFILL_ALL_FAILURE");
|
|
108
|
+
dataLayerData[`EN_RECURRING_FREQUENCIES`] = recurrValues;
|
|
172
109
|
}
|
|
173
110
|
// Push all collected variables at once
|
|
174
111
|
if (Object.keys(dataLayerData).length > 0) {
|
|
175
112
|
dataLayerData.event = "pageJsonVariablesReady";
|
|
176
113
|
this.dataLayer.push(dataLayerData);
|
|
177
114
|
}
|
|
178
|
-
// Push all collected events individually (GTM requirement)
|
|
179
|
-
dataLayerEvents.forEach((event) => {
|
|
180
|
-
this.dataLayer.push({ event });
|
|
181
|
-
});
|
|
182
115
|
this.attachEventListeners();
|
|
183
116
|
}
|
|
184
117
|
onSubmit() {
|
|
@@ -266,7 +199,7 @@ export class DataLayer {
|
|
|
266
199
|
}
|
|
267
200
|
addEndOfGiftProcessVariable(variableName, variableValue = "") {
|
|
268
201
|
this.storeEndOfGiftProcessData({
|
|
269
|
-
[
|
|
202
|
+
[variableName.toUpperCase()]: variableValue,
|
|
270
203
|
});
|
|
271
204
|
}
|
|
272
205
|
storeEndOfGiftProcessData(data) {
|
|
@@ -14,6 +14,7 @@ export const OptionsDefaults = {
|
|
|
14
14
|
MaxAmount: 100000,
|
|
15
15
|
MinAmountMessage: "Amount must be at least $1",
|
|
16
16
|
MaxAmountMessage: "Amount must be less than $100,000",
|
|
17
|
+
UseAmountValidatorFromEN: false,
|
|
17
18
|
SkipToMainContentLink: true,
|
|
18
19
|
SrcDefer: true,
|
|
19
20
|
NeverBounceAPI: null,
|
package/dist/min-max-amount.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export declare class MinMaxAmount {
|
|
2
2
|
private _form;
|
|
3
3
|
private _amount;
|
|
4
|
+
private _frequency;
|
|
4
5
|
private minAmount;
|
|
5
6
|
private maxAmount;
|
|
6
7
|
private minAmountMessage;
|
|
7
8
|
private maxAmountMessage;
|
|
9
|
+
private enAmountValidator;
|
|
8
10
|
private logger;
|
|
9
11
|
constructor();
|
|
10
12
|
shouldRun(): boolean;
|
|
11
13
|
enOnValidate(): void;
|
|
12
14
|
liveValidate(): void;
|
|
15
|
+
private setValidationConfigFromEN;
|
|
13
16
|
}
|
package/dist/min-max-amount.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
// This script adds an erros message to the page if the amount is greater than the max amount or less than the min amount.
|
|
2
|
-
import { DonationAmount, EnForm, ENGrid, EngridLogger } from ".";
|
|
2
|
+
import { DonationAmount, DonationFrequency, EnForm, ENGrid, EngridLogger, } from ".";
|
|
3
3
|
export class MinMaxAmount {
|
|
4
4
|
constructor() {
|
|
5
5
|
var _a, _b;
|
|
6
6
|
this._form = EnForm.getInstance();
|
|
7
7
|
this._amount = DonationAmount.getInstance();
|
|
8
|
+
this._frequency = DonationFrequency.getInstance();
|
|
8
9
|
this.minAmount = (_a = ENGrid.getOption("MinAmount")) !== null && _a !== void 0 ? _a : 1;
|
|
9
10
|
this.maxAmount = (_b = ENGrid.getOption("MaxAmount")) !== null && _b !== void 0 ? _b : 100000;
|
|
10
11
|
this.minAmountMessage = ENGrid.getOption("MinAmountMessage");
|
|
11
12
|
this.maxAmountMessage = ENGrid.getOption("MaxAmountMessage");
|
|
13
|
+
this.enAmountValidator = null;
|
|
12
14
|
this.logger = new EngridLogger("MinMaxAmount", "white", "purple", "🔢");
|
|
13
15
|
if (!this.shouldRun()) {
|
|
14
16
|
// If we're not on a Donation Page, get out
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
19
|
+
this.setValidationConfigFromEN();
|
|
17
20
|
this._amount.onAmountChange.subscribe((s) => window.setTimeout(this.liveValidate.bind(this), 1000) // Wait 1 second for the amount to be updated
|
|
18
21
|
);
|
|
19
22
|
this._form.onValidate.subscribe(this.enOnValidate.bind(this));
|
|
@@ -68,4 +71,56 @@ export class MinMaxAmount {
|
|
|
68
71
|
ENGrid.removeError(".en__field--withOther");
|
|
69
72
|
}
|
|
70
73
|
}
|
|
74
|
+
setValidationConfigFromEN() {
|
|
75
|
+
if (!ENGrid.getOption("UseAmountValidatorFromEN") ||
|
|
76
|
+
!window.EngagingNetworks.validators) {
|
|
77
|
+
this.logger.log("Not setting validation config from EN.");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Find the amount validator for the donation amount field
|
|
81
|
+
// It should be of type "AMNT" or "FAMNT" and have
|
|
82
|
+
// a componentId that matches the donation amount field.
|
|
83
|
+
this.enAmountValidator = window.EngagingNetworks.validators.find((validator) => {
|
|
84
|
+
var _a;
|
|
85
|
+
return ((validator.type === "FAMNT" || validator.type === "AMNT") &&
|
|
86
|
+
((_a = document
|
|
87
|
+
.querySelector(".en__field--" + validator.componentId)) === null || _a === void 0 ? void 0 : _a.classList.contains("en__field--donationAmt")));
|
|
88
|
+
});
|
|
89
|
+
if (!this.enAmountValidator || !this.enAmountValidator.format) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.logger.log(`Detected an amount validator for donation amount on the page:`, this.enAmountValidator);
|
|
93
|
+
// Static amount validator
|
|
94
|
+
if (this.enAmountValidator.type === "AMNT") {
|
|
95
|
+
this.minAmount = Number(this.enAmountValidator.format.split("~")[0]);
|
|
96
|
+
this.maxAmount = Number(this.enAmountValidator.format.split("~")[1]);
|
|
97
|
+
this.minAmountMessage = this.enAmountValidator.errorMessage;
|
|
98
|
+
this.maxAmountMessage = this.enAmountValidator.errorMessage;
|
|
99
|
+
this.logger.log(`Setting new values - Min Amount: ${this.minAmount}, Max Amount: ${this.maxAmount}, Error Message: ${this.minAmountMessage}`);
|
|
100
|
+
}
|
|
101
|
+
// Frequency-based amount validator
|
|
102
|
+
if (this.enAmountValidator.type === "FAMNT") {
|
|
103
|
+
this._frequency.onFrequencyChange.subscribe((freq) => {
|
|
104
|
+
if (!this.enAmountValidator || !this.enAmountValidator.format)
|
|
105
|
+
return;
|
|
106
|
+
// In the validator, "onetime" is written as "SINGLE"
|
|
107
|
+
// Validator format for FAMNT is like SINGLE:10~100000|MONTHLY:5~100000|QUARTERLY:25~100000|ANNUAL:25~100000
|
|
108
|
+
const frequency = freq === "onetime" ? "SINGLE" : freq.toUpperCase();
|
|
109
|
+
const validationRange = this.enAmountValidator.format
|
|
110
|
+
.split("|")
|
|
111
|
+
.find((range) => range.startsWith(frequency));
|
|
112
|
+
if (!validationRange) {
|
|
113
|
+
this.logger.log(`No validation range found for frequency: ${frequency}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const amounts = validationRange.split(":")[1].split("~");
|
|
117
|
+
this.minAmount = Number(amounts[0]);
|
|
118
|
+
this.maxAmount = Number(amounts[1]);
|
|
119
|
+
this.minAmountMessage = this.enAmountValidator.errorMessage;
|
|
120
|
+
this.maxAmountMessage = this.enAmountValidator.errorMessage;
|
|
121
|
+
this.logger.log(`Frequency changed to ${frequency}, updating min and max amounts`, validationRange);
|
|
122
|
+
this.logger.log(`Setting new values - Min Amount: ${this.minAmount}, Max Amount: ${this.maxAmount}, Error Message: ${this.minAmountMessage}`);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
71
126
|
}
|
package/dist/swap-amounts.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* "Other": "other",
|
|
11
11
|
* },
|
|
12
12
|
* default: 30,
|
|
13
|
+
* stickyDefault: false, // Optional. When true, every swap forces the default amount to be (re)selected
|
|
13
14
|
* },
|
|
14
15
|
* "monthly": {
|
|
15
16
|
* amounts: {
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
* "Other": "other",
|
|
21
22
|
* },
|
|
22
23
|
* default: 15,
|
|
24
|
+
* stickyDefault: true, // Example forcing default on each frequency swap
|
|
23
25
|
* },
|
|
24
26
|
* };
|
|
25
27
|
*/
|
package/dist/swap-amounts.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* "Other": "other",
|
|
16
16
|
* },
|
|
17
17
|
* default: 30,
|
|
18
|
+
* stickyDefault: false, // Optional. When true, every swap forces the default amount to be (re)selected
|
|
18
19
|
* },
|
|
19
20
|
* "monthly": {
|
|
20
21
|
* amounts: {
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
* "Other": "other",
|
|
26
27
|
* },
|
|
27
28
|
* default: 15,
|
|
29
|
+
* stickyDefault: true, // Example forcing default on each frequency swap
|
|
28
30
|
* },
|
|
29
31
|
* };
|
|
30
32
|
*/
|
|
@@ -80,6 +82,7 @@ export class SwapAmounts {
|
|
|
80
82
|
const config = {
|
|
81
83
|
amounts: amountsObj,
|
|
82
84
|
default: defaultAmount,
|
|
85
|
+
// stickyDefault omitted so it defaults to false behavior
|
|
83
86
|
};
|
|
84
87
|
window.EngridAmounts = {
|
|
85
88
|
onetime: config,
|
|
@@ -95,7 +98,9 @@ export class SwapAmounts {
|
|
|
95
98
|
const config = configs[freq];
|
|
96
99
|
if (!config)
|
|
97
100
|
return;
|
|
98
|
-
const
|
|
101
|
+
const stickyDefault = !!config.stickyDefault;
|
|
102
|
+
// If stickyDefault, always ignore current value so selected flag in list enforces default
|
|
103
|
+
const ignoreCurrentValue = stickyDefault ? true : this.ignoreCurrentValue();
|
|
99
104
|
window.EngagingNetworks.require._defined.enjs.swapList("donationAmt", this.toEnAmountList(config), { ignoreCurrentValue });
|
|
100
105
|
this._amount.load();
|
|
101
106
|
this.logger.log("Amounts Swapped To", config, { ignoreCurrentValue });
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AppVersion = "0.22.
|
|
1
|
+
export declare const AppVersion = "0.22.17";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AppVersion = "0.22.
|
|
1
|
+
export const AppVersion = "0.22.17";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4site/engrid-scripts",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.17",
|
|
4
4
|
"description": "Scripts for the ENGRID Project",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"strongly-typed-events": "^2.0.9"
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/4site-interactive-studios/engrid#readme",
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "e5c02e6aa5b48df75e149d7fbf4a0a864beb16cb",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"nodemon": "^2.0.20"
|
|
31
31
|
}
|