@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 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
@@ -194,6 +194,7 @@ export class iFrame {
194
194
  const excludeClasses = [
195
195
  "giveBySelect-Card",
196
196
  "en__field--ccnumber",
197
+ "en__field--survey",
197
198
  "give-by-select",
198
199
  "give-by-select-header",
199
200
  "en__submit",
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;
@@ -30,4 +30,5 @@ export const UpsellOptionsDefaults = {
30
30
  disablePaymentMethods: [],
31
31
  skipUpsell: false,
32
32
  conversionField: "",
33
+ upsellCheckbox: false,
33
34
  };
@@ -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.9";
1
+ export declare const AppVersion = "0.19.11";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const AppVersion = "0.19.9";
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.9",
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": "9361c560694896d53c7ea69258ed7b736d0d1771",
28
+ "gitHead": "253c4fc83741ff28c179c03c9b6833a15ce6e14d",
29
29
  "devDependencies": {
30
30
  "nodemon": "^2.0.20"
31
31
  }