@4site/engrid-scripts 0.19.9 → 0.19.11
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/app.js +3 -1
- package/dist/iframe.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/upsell-options.d.ts +5 -0
- package/dist/interfaces/upsell-options.js +1 -0
- package/dist/upsell-checkbox.d.ts +28 -0
- package/dist/upsell-checkbox.js +220 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DonationAmount, DonationFrequency, EnForm, ProcessingFees, Country, } from "./events";
|
|
2
|
-
import { AmountLabel, Loader, ProgressBar, UpsellLightbox, ENGrid, OptionsDefaults, setRecurrFreq, PageBackground, MediaAttribution, ApplePay, A11y, CapitalizeFields, Ecard, ClickToExpand, Advocacy, DataAttributes, LiveVariables, iFrame, InputPlaceholders, InputHasValueAndFocus, ShowHideRadioCheckboxes, AutoCountrySelect, SkipToMainContentLink, SrcDefer, NeverBounce, AutoYear, Autocomplete, RememberMe, TranslateFields, ShowIfAmount, EngridLogger, OtherAmount, MinMaxAmount, Ticker, DataReplace, DataHide, AddNameToMessage, ExpandRegionName, AppVersion, UrlToForm, RequiredIfVisible, TidyContact, DataLayer, LiveCurrency, Autosubmit, EventTickets, SwapAmounts, DebugPanel, DebugHiddenFields, FreshAddress, BrandingHtml, CountryDisable, PremiumGift, DigitalWallets, MobileCTA, LiveFrequency, UniversalOptIn, Plaid, GiveBySelect, UrlParamsToBodyAttrs, ExitIntentLightbox, SupporterHub, FastFormFill, SetAttr, ShowIfPresent, ENValidators, CustomCurrency, VGS, PostalCodeValidator, CountryRedirect, WelcomeBack, EcardToTarget, UsOnlyForm, ThankYouPageConditionalContent, EmbeddedEcard, CheckboxLabel, } from ".";
|
|
2
|
+
import { AmountLabel, Loader, ProgressBar, UpsellLightbox, ENGrid, OptionsDefaults, setRecurrFreq, PageBackground, MediaAttribution, ApplePay, A11y, CapitalizeFields, Ecard, ClickToExpand, Advocacy, DataAttributes, LiveVariables, iFrame, InputPlaceholders, InputHasValueAndFocus, ShowHideRadioCheckboxes, AutoCountrySelect, SkipToMainContentLink, SrcDefer, NeverBounce, AutoYear, Autocomplete, RememberMe, TranslateFields, ShowIfAmount, EngridLogger, OtherAmount, MinMaxAmount, Ticker, DataReplace, DataHide, AddNameToMessage, ExpandRegionName, AppVersion, UrlToForm, RequiredIfVisible, TidyContact, DataLayer, LiveCurrency, Autosubmit, EventTickets, SwapAmounts, DebugPanel, DebugHiddenFields, FreshAddress, BrandingHtml, CountryDisable, PremiumGift, DigitalWallets, MobileCTA, LiveFrequency, UniversalOptIn, Plaid, GiveBySelect, UrlParamsToBodyAttrs, ExitIntentLightbox, SupporterHub, FastFormFill, SetAttr, ShowIfPresent, ENValidators, CustomCurrency, VGS, PostalCodeValidator, CountryRedirect, WelcomeBack, EcardToTarget, UsOnlyForm, ThankYouPageConditionalContent, EmbeddedEcard, CheckboxLabel, UpsellCheckbox, } from ".";
|
|
3
3
|
export class App extends ENGrid {
|
|
4
4
|
constructor(options) {
|
|
5
5
|
super();
|
|
@@ -143,6 +143,8 @@ export class App extends ENGrid {
|
|
|
143
143
|
new LiveVariables(this.options);
|
|
144
144
|
// Dynamically set Recurrency Frequency
|
|
145
145
|
new setRecurrFreq();
|
|
146
|
+
// Upsell Checkbox
|
|
147
|
+
new UpsellCheckbox();
|
|
146
148
|
// Upsell Lightbox
|
|
147
149
|
new UpsellLightbox();
|
|
148
150
|
// Amount Labels
|
package/dist/iframe.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./input-placeholders";
|
|
|
22
22
|
export * from "./media-attribution";
|
|
23
23
|
export * from "./live-variables";
|
|
24
24
|
export * from "./upsell-lightbox";
|
|
25
|
+
export * from "./upsell-checkbox";
|
|
25
26
|
export * from "./show-hide-radio-checkboxes";
|
|
26
27
|
export * from "./translate-fields";
|
|
27
28
|
export * from "./auto-country-select";
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./input-placeholders";
|
|
|
22
22
|
export * from "./media-attribution";
|
|
23
23
|
export * from "./live-variables";
|
|
24
24
|
export * from "./upsell-lightbox";
|
|
25
|
+
export * from "./upsell-checkbox";
|
|
25
26
|
export * from "./show-hide-radio-checkboxes";
|
|
26
27
|
export * from "./translate-fields";
|
|
27
28
|
export * from "./auto-country-select";
|
|
@@ -20,5 +20,10 @@ export interface UpsellOptions {
|
|
|
20
20
|
disablePaymentMethods: Array<string>;
|
|
21
21
|
skipUpsell: boolean;
|
|
22
22
|
conversionField: string;
|
|
23
|
+
upsellCheckbox: false | {
|
|
24
|
+
label: string;
|
|
25
|
+
location: string;
|
|
26
|
+
cssClass: string;
|
|
27
|
+
};
|
|
23
28
|
}
|
|
24
29
|
export declare const UpsellOptionsDefaults: UpsellOptions;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ProcessingFees } from ".";
|
|
2
|
+
import { DonationAmount } from "./events";
|
|
3
|
+
export declare class UpsellCheckbox {
|
|
4
|
+
private options;
|
|
5
|
+
private checkboxOptions;
|
|
6
|
+
private checkboxOptionsDefaults;
|
|
7
|
+
_amount: DonationAmount;
|
|
8
|
+
_fees: ProcessingFees;
|
|
9
|
+
private _frequency;
|
|
10
|
+
private _dataLayer;
|
|
11
|
+
private checkboxContainer;
|
|
12
|
+
private oldAmount;
|
|
13
|
+
private oldFrequency;
|
|
14
|
+
private logger;
|
|
15
|
+
constructor();
|
|
16
|
+
private updateLiveData;
|
|
17
|
+
private renderCheckbox;
|
|
18
|
+
private shouldRun;
|
|
19
|
+
private showCheckbox;
|
|
20
|
+
private hideCheckbox;
|
|
21
|
+
private liveAmounts;
|
|
22
|
+
private liveFrequency;
|
|
23
|
+
private getUpsellAmount;
|
|
24
|
+
private toggleCheck;
|
|
25
|
+
private getAmountTxt;
|
|
26
|
+
private getFrequencyTxt;
|
|
27
|
+
private renderConversionField;
|
|
28
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// This component will add a checkbox to the donation form that will allow the user to upgrade their donation to a monthly donation.
|
|
2
|
+
import { ENGrid, EngridLogger, ProcessingFees, UpsellOptionsDefaults, DataLayer, } from ".";
|
|
3
|
+
import { DonationAmount, DonationFrequency } from "./events";
|
|
4
|
+
export class UpsellCheckbox {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.checkboxOptions = false;
|
|
7
|
+
this.checkboxOptionsDefaults = {
|
|
8
|
+
label: "Make my gift a monthly gift of <strong>{new-amount}/mo</strong>",
|
|
9
|
+
location: "before .en__component .en__submit",
|
|
10
|
+
cssClass: "",
|
|
11
|
+
};
|
|
12
|
+
this._amount = DonationAmount.getInstance();
|
|
13
|
+
this._fees = ProcessingFees.getInstance();
|
|
14
|
+
this._frequency = DonationFrequency.getInstance();
|
|
15
|
+
this._dataLayer = DataLayer.getInstance();
|
|
16
|
+
this.checkboxContainer = null;
|
|
17
|
+
this.oldAmount = 0;
|
|
18
|
+
this.oldFrequency = "one-time";
|
|
19
|
+
this.logger = new EngridLogger("UpsellCheckbox", "black", "LemonChiffon", "✅");
|
|
20
|
+
let options = "EngridUpsell" in window ? window.EngridUpsell : {};
|
|
21
|
+
this.options = Object.assign(Object.assign({}, UpsellOptionsDefaults), options);
|
|
22
|
+
if (this.options.upsellCheckbox === false) {
|
|
23
|
+
this.logger.log("Skipped");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// If window.EngridUpsell has only the upsellCheckbox property, set window.EngridUpsell.skipUpsell to true
|
|
27
|
+
if (Object.keys(options).length === 1 && "upsellCheckbox" in options) {
|
|
28
|
+
window.EngridUpsell.skipUpsell = true; // Skip the upsell lightbox
|
|
29
|
+
}
|
|
30
|
+
this.checkboxOptions = Object.assign(Object.assign({}, this.checkboxOptionsDefaults), this.options.upsellCheckbox);
|
|
31
|
+
if (!this.shouldRun()) {
|
|
32
|
+
this.logger.log("should NOT run");
|
|
33
|
+
// If we're not on a Donation Page, get out
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.renderCheckbox();
|
|
37
|
+
this.updateLiveData();
|
|
38
|
+
this._frequency.onFrequencyChange.subscribe(() => this.updateLiveData());
|
|
39
|
+
this._amount.onAmountChange.subscribe(() => this.updateLiveData());
|
|
40
|
+
this._fees.onFeeChange.subscribe(() => this.updateLiveData());
|
|
41
|
+
}
|
|
42
|
+
updateLiveData() {
|
|
43
|
+
this.liveAmounts();
|
|
44
|
+
this.liveFrequency();
|
|
45
|
+
}
|
|
46
|
+
renderCheckbox() {
|
|
47
|
+
if (this.checkboxOptions === false)
|
|
48
|
+
return;
|
|
49
|
+
const label = this.checkboxOptions.label
|
|
50
|
+
.replace("{new-amount}", " <span class='upsell_suggestion'></span>")
|
|
51
|
+
.replace("{old-amount}", " <span class='upsell_amount'></span>")
|
|
52
|
+
.replace("{old-frequency}", " <span class='upsell_frequency'></span>");
|
|
53
|
+
const formBlock = document.createElement("div");
|
|
54
|
+
formBlock.classList.add("en__component", "en__component--formblock", "recurring-frequency-y-hide", "engrid-upsell-checkbox");
|
|
55
|
+
if (this.checkboxOptions.cssClass)
|
|
56
|
+
formBlock.classList.add(this.checkboxOptions.cssClass);
|
|
57
|
+
formBlock.innerHTML = `
|
|
58
|
+
<div class="en__field en__field--checkbox">
|
|
59
|
+
<div class="en__field__element en__field__element--checkbox">
|
|
60
|
+
<div class="en__field__item">
|
|
61
|
+
<input type="checkbox" class="en__field__input en__field__input--checkbox" name="upsellCheckbox" id="upsellCheckbox" value="Y">
|
|
62
|
+
<label class="en__field__label en__field__label--item" for="upsellCheckbox" style="gap: 0.5ch">${label}</label>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>`;
|
|
66
|
+
const checkbox = formBlock.querySelector("#upsellCheckbox");
|
|
67
|
+
if (checkbox)
|
|
68
|
+
checkbox.addEventListener("change", this.toggleCheck.bind(this));
|
|
69
|
+
const position = this.checkboxOptions.location.split(" ")[0];
|
|
70
|
+
// Location is everything after the first space
|
|
71
|
+
const location = this.checkboxOptions.location
|
|
72
|
+
.split(" ")
|
|
73
|
+
.slice(1)
|
|
74
|
+
.join(" ")
|
|
75
|
+
.trim();
|
|
76
|
+
const target = document.querySelector(location);
|
|
77
|
+
this.checkboxContainer = formBlock;
|
|
78
|
+
if (target) {
|
|
79
|
+
if (position === "before") {
|
|
80
|
+
this.logger.log("rendered before");
|
|
81
|
+
target.before(formBlock);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this.logger.log("rendered after");
|
|
85
|
+
target.after(formBlock);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.logger.error("could not render - target not found");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Should we run the script?
|
|
93
|
+
shouldRun() {
|
|
94
|
+
// if it's a first page of a Donation page
|
|
95
|
+
return ENGrid.getPageNumber() === 1 && ENGrid.getPageType() === "DONATION";
|
|
96
|
+
}
|
|
97
|
+
showCheckbox() {
|
|
98
|
+
if (this.checkboxContainer)
|
|
99
|
+
this.checkboxContainer.classList.remove("hide");
|
|
100
|
+
}
|
|
101
|
+
hideCheckbox() {
|
|
102
|
+
if (this.checkboxContainer)
|
|
103
|
+
this.checkboxContainer.classList.add("hide");
|
|
104
|
+
}
|
|
105
|
+
liveAmounts() {
|
|
106
|
+
// Only update live data if the current frequency is one-time
|
|
107
|
+
if (this._frequency.frequency !== "onetime")
|
|
108
|
+
return;
|
|
109
|
+
const live_upsell_amount = document.querySelectorAll(".upsell_suggestion");
|
|
110
|
+
const live_amount = document.querySelectorAll(".upsell_amount");
|
|
111
|
+
const upsellAmount = this.getUpsellAmount();
|
|
112
|
+
const suggestedAmount = upsellAmount + this._fees.calculateFees(upsellAmount);
|
|
113
|
+
if (suggestedAmount > 0) {
|
|
114
|
+
this.showCheckbox();
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.hideCheckbox();
|
|
118
|
+
}
|
|
119
|
+
live_upsell_amount.forEach((elem) => (elem.innerHTML = this.getAmountTxt(suggestedAmount)));
|
|
120
|
+
live_amount.forEach((elem) => (elem.innerHTML = this.getAmountTxt(this._amount.amount + this._fees.fee)));
|
|
121
|
+
}
|
|
122
|
+
liveFrequency() {
|
|
123
|
+
const live_upsell_frequency = document.querySelectorAll(".upsell_frequency");
|
|
124
|
+
live_upsell_frequency.forEach((elem) => (elem.innerHTML = this.getFrequencyTxt()));
|
|
125
|
+
}
|
|
126
|
+
// Return the Suggested Upsell Amount
|
|
127
|
+
getUpsellAmount() {
|
|
128
|
+
const amount = this._amount.amount;
|
|
129
|
+
let upsellAmount = 0;
|
|
130
|
+
for (let i = 0; i < this.options.amountRange.length; i++) {
|
|
131
|
+
let val = this.options.amountRange[i];
|
|
132
|
+
if (upsellAmount == 0 && amount <= val.max) {
|
|
133
|
+
upsellAmount = val.suggestion;
|
|
134
|
+
if (upsellAmount === 0)
|
|
135
|
+
return 0;
|
|
136
|
+
if (typeof upsellAmount !== "number") {
|
|
137
|
+
const suggestionMath = upsellAmount.replace("amount", amount.toFixed(2));
|
|
138
|
+
upsellAmount = parseFloat(Function('"use strict";return (' + suggestionMath + ")")());
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return upsellAmount > this.options.minAmount
|
|
144
|
+
? upsellAmount
|
|
145
|
+
: this.options.minAmount;
|
|
146
|
+
}
|
|
147
|
+
// Proceed to the next page (upsold or not)
|
|
148
|
+
toggleCheck(e) {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
if (e.target.checked) {
|
|
152
|
+
this.logger.success("Upsold");
|
|
153
|
+
const upsoldAmount = this.getUpsellAmount();
|
|
154
|
+
const originalAmount = this._amount.amount;
|
|
155
|
+
this.oldAmount = originalAmount;
|
|
156
|
+
this.oldFrequency = this._frequency.frequency;
|
|
157
|
+
// If we're checking the upsell checkbox, remove the class that hides it on different frequencies
|
|
158
|
+
(_a = this.checkboxContainer) === null || _a === void 0 ? void 0 : _a.classList.remove("recurring-frequency-y-hide");
|
|
159
|
+
this._frequency.setFrequency("monthly");
|
|
160
|
+
this._amount.setAmount(upsoldAmount);
|
|
161
|
+
this._dataLayer.addEndOfGiftProcessEvent("ENGRID_UPSELL_CHECKBOX", {
|
|
162
|
+
eventValue: true,
|
|
163
|
+
originalAmount: originalAmount,
|
|
164
|
+
upsoldAmount: upsoldAmount,
|
|
165
|
+
frequency: "monthly",
|
|
166
|
+
});
|
|
167
|
+
this._dataLayer.addEndOfGiftProcessVariable("ENGRID_UPSELL_CHECKBOX", true);
|
|
168
|
+
this._dataLayer.addEndOfGiftProcessVariable("ENGRID_UPSELL_ORIGINAL_AMOUNT", originalAmount);
|
|
169
|
+
this._dataLayer.addEndOfGiftProcessVariable("ENGRID_UPSELL_DONATION_FREQUENCY", "MONTHLY");
|
|
170
|
+
this.renderConversionField("upsellSuccess", "onetime", originalAmount, "monthly", upsoldAmount, "monthly", upsoldAmount);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
this.logger.success("Not Upsold");
|
|
174
|
+
this._amount.setAmount(this.oldAmount);
|
|
175
|
+
this._frequency.setFrequency(this.oldFrequency);
|
|
176
|
+
(_b = this.checkboxContainer) === null || _b === void 0 ? void 0 : _b.classList.add("recurring-frequency-y-hide");
|
|
177
|
+
this._dataLayer.addEndOfGiftProcessVariable("ENGRID_UPSELL_CHECKBOX", false);
|
|
178
|
+
this._dataLayer.addEndOfGiftProcessVariable("ENGRID_UPSELL_DONATION_FREQUENCY", "ONE-TIME");
|
|
179
|
+
this.renderConversionField("upsellFail", this._frequency.frequency, this._amount.amount, "monthly", this._amount.amount, this._frequency.frequency, this._amount.amount);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
getAmountTxt(amount = 0) {
|
|
183
|
+
var _a, _b, _c, _d;
|
|
184
|
+
const symbol = (_a = ENGrid.getCurrencySymbol()) !== null && _a !== void 0 ? _a : "$";
|
|
185
|
+
const dec_separator = (_b = ENGrid.getOption("DecimalSeparator")) !== null && _b !== void 0 ? _b : ".";
|
|
186
|
+
const thousands_separator = (_c = ENGrid.getOption("ThousandsSeparator")) !== null && _c !== void 0 ? _c : "";
|
|
187
|
+
const dec_places = amount % 1 == 0 ? 0 : (_d = ENGrid.getOption("DecimalPlaces")) !== null && _d !== void 0 ? _d : 2;
|
|
188
|
+
const amountTxt = ENGrid.formatNumber(amount, dec_places, dec_separator, thousands_separator);
|
|
189
|
+
return amount > 0 ? symbol + amountTxt : "";
|
|
190
|
+
}
|
|
191
|
+
getFrequencyTxt() {
|
|
192
|
+
const freqTxt = {
|
|
193
|
+
onetime: "one-time",
|
|
194
|
+
monthly: "monthly",
|
|
195
|
+
annual: "annual",
|
|
196
|
+
};
|
|
197
|
+
const frequency = this._frequency.frequency;
|
|
198
|
+
return frequency in freqTxt ? freqTxt[frequency] : frequency;
|
|
199
|
+
}
|
|
200
|
+
renderConversionField(event, // The event that triggered the conversion
|
|
201
|
+
freq, // The frequency of the donation (onetime, monthly, annual)
|
|
202
|
+
amt, // The original amount of the donation (before the upsell)
|
|
203
|
+
sugFreq, // The suggested frequency of the upsell (monthly)
|
|
204
|
+
sugAmt, // The suggested amount of the upsell
|
|
205
|
+
subFreq, // The submitted frequency of the upsell (onetime, monthly, annual)
|
|
206
|
+
subAmt // The submitted amount of the upsell
|
|
207
|
+
) {
|
|
208
|
+
if (this.options.conversionField === "")
|
|
209
|
+
return;
|
|
210
|
+
const conversionField = document.querySelector("input[name='" + this.options.conversionField + "']") ||
|
|
211
|
+
ENGrid.createHiddenInput(this.options.conversionField);
|
|
212
|
+
if (!conversionField) {
|
|
213
|
+
this.logger.error("Could not find or create the conversion field");
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const conversionValue = `event:${event},freq:${freq},amt:${amt},sugFreq:${sugFreq},sugAmt:${sugAmt},subFreq:${subFreq},subAmt:${subAmt}`;
|
|
217
|
+
conversionField.value = conversionValue;
|
|
218
|
+
this.logger.log(`Conversion Field ${event}`, conversionValue);
|
|
219
|
+
}
|
|
220
|
+
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AppVersion = "0.19.
|
|
1
|
+
export declare const AppVersion = "0.19.11";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AppVersion = "0.19.
|
|
1
|
+
export const AppVersion = "0.19.11";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4site/engrid-scripts",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.11",
|
|
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": "253c4fc83741ff28c179c03c9b6833a15ce6e14d",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"nodemon": "^2.0.20"
|
|
31
31
|
}
|