@salesforcedevs/dw-components 1.3.148-canary.14 → 1.3.148-canary.16
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/package.json
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
<dw-j2s-form
|
|
36
36
|
id={stepDatum.formData.formId}
|
|
37
37
|
countries={countries}
|
|
38
|
-
form-metadata={stepDatum.
|
|
38
|
+
form-metadata={stepDatum.formData}
|
|
39
39
|
incoming-user-info={formIncomingUserInfo}
|
|
40
40
|
onformvaliditychange={handleFormValidityChange}
|
|
41
41
|
recaptcha-token={recaptchaToken}
|
|
@@ -3,6 +3,7 @@ import StepSequence from "dx/stepSequence";
|
|
|
3
3
|
import { getListWithUuids } from "dxUtils/list";
|
|
4
4
|
import { track } from "dxUtils/analytics";
|
|
5
5
|
import { toJson } from "dxUtils/normalizers";
|
|
6
|
+
import J2sForm from "dw/j2sForm";
|
|
6
7
|
|
|
7
8
|
export type StepDatum = {
|
|
8
9
|
bodyHtml?: string;
|
|
@@ -57,30 +58,22 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
57
58
|
}
|
|
58
59
|
set stepsData(value) {
|
|
59
60
|
// normalize incoming value with uuid keys and non-required props (for cleaner HTML template), etc.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
iconSymbol
|
|
71
|
-
stepDatum.primaryAction.iconSymbol || "arrow-right"
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
if (normalizedStepDatum.formData) {
|
|
76
|
-
(normalizedStepDatum as any).formMetadata = JSON.stringify(
|
|
77
|
-
normalizedStepDatum.formData
|
|
78
|
-
);
|
|
61
|
+
const valueWithUuids = getListWithUuids<StepDatum>(toJson(value));
|
|
62
|
+
this._stepsData = valueWithUuids.map((stepDatum) => {
|
|
63
|
+
const normalizedStepDatum = {
|
|
64
|
+
...stepDatum,
|
|
65
|
+
headerData: stepDatum.headerData || {},
|
|
66
|
+
primaryAction: {
|
|
67
|
+
...stepDatum.primaryAction,
|
|
68
|
+
variant: stepDatum.primaryAction.variant || "primary",
|
|
69
|
+
iconSprite: stepDatum.primaryAction.iconSprite || "general",
|
|
70
|
+
iconSymbol:
|
|
71
|
+
stepDatum.primaryAction.iconSymbol || "arrow-right"
|
|
79
72
|
}
|
|
73
|
+
};
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
75
|
+
return normalizedStepDatum;
|
|
76
|
+
});
|
|
84
77
|
}
|
|
85
78
|
|
|
86
79
|
private countries = "[]";
|
|
@@ -229,9 +222,12 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
229
222
|
evt.preventDefault(); // don't proceed automatically to next step
|
|
230
223
|
this._isFormSubmitting = true;
|
|
231
224
|
|
|
225
|
+
const j2sFormEl = (this.template.querySelector(
|
|
226
|
+
"dw-j2s-form"
|
|
227
|
+
) as unknown) as J2sForm | null;
|
|
228
|
+
|
|
232
229
|
try {
|
|
233
|
-
const formData =
|
|
234
|
-
?.formDataForDrm;
|
|
230
|
+
const formData = j2sFormEl?.formDataForDrm;
|
|
235
231
|
// For some countries, explicit approvals will be present; for others, it is implicitly assumed
|
|
236
232
|
if (typeof formData.Opt_In__c !== "boolean") {
|
|
237
233
|
formData.Opt_In__c = true;
|
|
@@ -265,6 +261,7 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
265
261
|
}
|
|
266
262
|
}
|
|
267
263
|
} catch (ex) {
|
|
264
|
+
j2sFormEl?.notifySubmitFailure();
|
|
268
265
|
console.error(ex); // TODO
|
|
269
266
|
}
|
|
270
267
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
placeholder="Your first name"
|
|
11
11
|
required
|
|
12
12
|
validity-on-blur
|
|
13
|
-
|
|
13
|
+
onchange={handleFormFieldChange}
|
|
14
14
|
value={state.firstName}
|
|
15
15
|
></dx-input>
|
|
16
16
|
<dx-input
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
placeholder="Your last name"
|
|
22
22
|
required
|
|
23
23
|
validity-on-blur
|
|
24
|
-
|
|
24
|
+
onchange={handleFormFieldChange}
|
|
25
25
|
value={state.lastName}
|
|
26
26
|
></dx-input>
|
|
27
27
|
</div>
|
|
@@ -34,21 +34,10 @@
|
|
|
34
34
|
placeholder="Your company name"
|
|
35
35
|
required
|
|
36
36
|
validity-on-blur
|
|
37
|
-
onblur={handleRequiredFieldUpdate}
|
|
38
37
|
value={state.companyName}
|
|
38
|
+
onchange={handleFormFieldChange}
|
|
39
39
|
></dx-input>
|
|
40
40
|
<dx-select
|
|
41
|
-
if:false={isJobRoleRequired}
|
|
42
|
-
class="job-role-field"
|
|
43
|
-
label="Job Role"
|
|
44
|
-
message-when-value-missing="Select your job role"
|
|
45
|
-
name="DRM_Role__c"
|
|
46
|
-
options={jobRoles}
|
|
47
|
-
placeholder="Select Job Role"
|
|
48
|
-
value={state.jobRole}
|
|
49
|
-
></dx-select>
|
|
50
|
-
<dx-select
|
|
51
|
-
if:true={isJobRoleRequired}
|
|
52
41
|
class="job-role-field"
|
|
53
42
|
label="Job Role"
|
|
54
43
|
message-when-value-missing="Select your job role"
|
|
@@ -57,7 +46,7 @@
|
|
|
57
46
|
placeholder="Select Job Role"
|
|
58
47
|
required
|
|
59
48
|
value={state.jobRole}
|
|
60
|
-
onchange={
|
|
49
|
+
onchange={handleFormFieldChange}
|
|
61
50
|
></dx-select>
|
|
62
51
|
</div>
|
|
63
52
|
<div class="form-row">
|
|
@@ -69,8 +58,8 @@
|
|
|
69
58
|
missing-error-message="Enter your email address"
|
|
70
59
|
validity-on-blur="true"
|
|
71
60
|
required
|
|
72
|
-
onblur={handleRequiredFieldUpdate}
|
|
73
61
|
value={state.email}
|
|
62
|
+
onchange={handleFormFieldChange}
|
|
74
63
|
></dx-input>
|
|
75
64
|
<dx-select
|
|
76
65
|
label="Country/Region"
|
|
@@ -80,7 +69,7 @@
|
|
|
80
69
|
placeholder="Select Country/Region"
|
|
81
70
|
required
|
|
82
71
|
value={state.country}
|
|
83
|
-
onchange={
|
|
72
|
+
onchange={handleFormFieldChange}
|
|
84
73
|
></dx-select>
|
|
85
74
|
</div>
|
|
86
75
|
<div class="form-row" if:true={isCountryWithReferralInput}>
|
|
@@ -89,6 +78,7 @@
|
|
|
89
78
|
class="referral-email-field full-width"
|
|
90
79
|
label="If anyone has referred you, please share their Email ID below, with their consent."
|
|
91
80
|
type="email"
|
|
81
|
+
onchange={handleFormFieldChange}
|
|
92
82
|
></dx-input>
|
|
93
83
|
</div>
|
|
94
84
|
<div class="form-row" if:true={isNotParticipatingCountry}>
|
|
@@ -99,6 +89,14 @@
|
|
|
99
89
|
variant="accented"
|
|
100
90
|
></dx-alert>
|
|
101
91
|
</div>
|
|
92
|
+
<div class="form-row" if:true={showSubmitFailureAlert}>
|
|
93
|
+
<dx-alert
|
|
94
|
+
alert-info={formSubmitFailureAlertInfo}
|
|
95
|
+
class="full-width"
|
|
96
|
+
type="danger"
|
|
97
|
+
variant="accented"
|
|
98
|
+
></dx-alert>
|
|
99
|
+
</div>
|
|
102
100
|
<div class="form-terms-container">
|
|
103
101
|
<div class="form-row" if:true={state.showMarketingText}>
|
|
104
102
|
<dx-checkbox
|
|
@@ -106,7 +104,7 @@
|
|
|
106
104
|
name="Opt_In__c"
|
|
107
105
|
required
|
|
108
106
|
class="terms"
|
|
109
|
-
onchange={
|
|
107
|
+
onchange={handleFormFieldChange}
|
|
110
108
|
disabled={isNotParticipatingCountry}
|
|
111
109
|
>
|
|
112
110
|
<span lwc:dom="manual" class="marketing-terms"></span>
|
|
@@ -118,7 +116,7 @@
|
|
|
118
116
|
name="j2s_terms"
|
|
119
117
|
required
|
|
120
118
|
class="terms"
|
|
121
|
-
onchange={
|
|
119
|
+
onchange={handleFormFieldChange}
|
|
122
120
|
disabled={isNotParticipatingCountry}
|
|
123
121
|
>
|
|
124
122
|
<span lwc:dom="manual" class="j2s-terms"></span>
|
|
@@ -131,7 +129,7 @@
|
|
|
131
129
|
name="Privacy_Statement__c"
|
|
132
130
|
required
|
|
133
131
|
class="terms"
|
|
134
|
-
onchange={
|
|
132
|
+
onchange={handleFormFieldChange}
|
|
135
133
|
disabled={isNotParticipatingCountry}
|
|
136
134
|
>
|
|
137
135
|
<span lwc:dom="manual" class="legal-terms"></span>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toJson } from "dxUtils/normalizers";
|
|
2
2
|
import { api } from "lwc";
|
|
3
|
+
import debounce from "debounce";
|
|
3
4
|
import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
|
|
4
5
|
|
|
5
6
|
// Hard-coding for now because we can't get information about an endpoint for this
|
|
@@ -34,12 +35,12 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
34
35
|
private _countriesJson = "";
|
|
35
36
|
private _countriesLookup: any = {}; // TODO typings
|
|
36
37
|
private _didSetFormId = false;
|
|
37
|
-
private _formMetadata: any = {}; // TODO typings
|
|
38
38
|
private _incomingUserInfo: any = {}; // TODO typings
|
|
39
39
|
private _isInitialRender = true;
|
|
40
40
|
private _recaptchaToken = "";
|
|
41
41
|
|
|
42
42
|
@api id = "";
|
|
43
|
+
@api formMetadata: any = {};
|
|
43
44
|
@api referralText = "";
|
|
44
45
|
|
|
45
46
|
@api
|
|
@@ -66,14 +67,6 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
66
67
|
this._incomingUserInfo = toJson(value);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
@api
|
|
70
|
-
get formMetadata() {
|
|
71
|
-
return this._formMetadata;
|
|
72
|
-
}
|
|
73
|
-
set formMetadata(value: string) {
|
|
74
|
-
this._formMetadata = toJson(value);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
70
|
@api
|
|
78
71
|
get formDataForDrm() {
|
|
79
72
|
// We should be able to just get the formData from the form automatically using `new FormData(theForm)`,
|
|
@@ -98,13 +91,15 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
98
91
|
}
|
|
99
92
|
set recaptchaToken(value: string) {
|
|
100
93
|
this._recaptchaToken = value;
|
|
101
|
-
|
|
94
|
+
// Treat recaptcha checkbox as a required form field even though not technically marked as such:
|
|
95
|
+
this.handleFormFieldChange({ target: { required: true } } as any);
|
|
102
96
|
}
|
|
103
97
|
|
|
104
98
|
private participatingCountryCodes = ["US", "CA", "IN"];
|
|
105
99
|
private countriesWithReferralInput = ["IN"];
|
|
106
100
|
private countriesWithRequiredJobRole = ["CA"];
|
|
107
101
|
private requiredFormFields: HTMLElement[] = [];
|
|
102
|
+
private showSubmitFailureAlert = false;
|
|
108
103
|
|
|
109
104
|
get isNotParticipatingCountry() {
|
|
110
105
|
return !this.isParticipatingCountry(this.state.country);
|
|
@@ -114,12 +109,12 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
114
109
|
return this.countriesWithReferralInput.includes(this.state.country);
|
|
115
110
|
}
|
|
116
111
|
|
|
117
|
-
get
|
|
118
|
-
return this.
|
|
112
|
+
get notAvailableAlertInfo() {
|
|
113
|
+
return this.formMetadata.notAvailableAlertInfo;
|
|
119
114
|
}
|
|
120
115
|
|
|
121
|
-
get
|
|
122
|
-
return
|
|
116
|
+
get formSubmitFailureAlertInfo() {
|
|
117
|
+
return this.formMetadata.formSubmitFailureAlertInfo;
|
|
123
118
|
}
|
|
124
119
|
|
|
125
120
|
get jobRoles() {
|
|
@@ -151,10 +146,7 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
151
146
|
|
|
152
147
|
renderedCallback(): void {
|
|
153
148
|
if (this._isInitialRender) {
|
|
154
|
-
this.updateInnerHtml(
|
|
155
|
-
"span.j2s-terms",
|
|
156
|
-
(this.formMetadata as any).j2sTerms
|
|
157
|
-
);
|
|
149
|
+
this.updateInnerHtml("span.j2s-terms", this.formMetadata.j2sTerms);
|
|
158
150
|
}
|
|
159
151
|
|
|
160
152
|
if (
|
|
@@ -202,7 +194,47 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
202
194
|
}
|
|
203
195
|
}
|
|
204
196
|
|
|
205
|
-
|
|
197
|
+
handleLearnMore() {
|
|
198
|
+
this.template
|
|
199
|
+
.querySelector(".legal-terms-learn-more")
|
|
200
|
+
?.classList.toggle("hidden");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
handleFormFieldChange = (evt: CustomEvent) => {
|
|
204
|
+
const callbacks: Function[] = [];
|
|
205
|
+
|
|
206
|
+
// Event target information must be read prior to debouncing; otherwise, the target is gone after the debounce.
|
|
207
|
+
if ((evt.target as HTMLInputElement)?.name === "MailingCountry") {
|
|
208
|
+
const { value } = evt.detail;
|
|
209
|
+
callbacks.push(() => this.handleCountryChange(value));
|
|
210
|
+
} else if ((evt.target as HTMLInputElement)?.required) {
|
|
211
|
+
callbacks.push(() => this.handleRequiredFieldUpdate());
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
callbacks.push(() => {
|
|
215
|
+
// Remove submit failure message once any change is made to the form.
|
|
216
|
+
if (this.showSubmitFailureAlert) {
|
|
217
|
+
this.showSubmitFailureAlert = false;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Don't do unnecessary work too often if form fields are rapidly being changed
|
|
222
|
+
this.debouncedFormFieldChangeHandler(callbacks);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
@api
|
|
226
|
+
notifySubmitFailure() {
|
|
227
|
+
this.showSubmitFailureAlert = true;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private debouncedFormFieldChangeHandler = debounce(
|
|
231
|
+
(callbacks: Function[]) => {
|
|
232
|
+
callbacks.forEach((callback) => callback());
|
|
233
|
+
},
|
|
234
|
+
1000 / 15 /* 15fps seems reasonable */
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
private handleRequiredFieldUpdate() {
|
|
206
238
|
const isFormNowValid = this.checkValidity();
|
|
207
239
|
if (this.state.isFormValid !== isFormNowValid) {
|
|
208
240
|
this.setState({
|
|
@@ -211,12 +243,11 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
211
243
|
}
|
|
212
244
|
}
|
|
213
245
|
|
|
214
|
-
handleCountryChange(
|
|
215
|
-
const
|
|
216
|
-
const countryData = this._countriesLookup[value];
|
|
246
|
+
private handleCountryChange(countryCode: string) {
|
|
247
|
+
const countryData = this._countriesLookup[countryCode];
|
|
217
248
|
|
|
218
249
|
this.setState({
|
|
219
|
-
country:
|
|
250
|
+
country: countryCode,
|
|
220
251
|
learnMore: countryData.learnMore,
|
|
221
252
|
legalText: countryData.legalText,
|
|
222
253
|
marketingText: countryData.marketingText,
|
|
@@ -232,12 +263,6 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
232
263
|
);
|
|
233
264
|
}
|
|
234
265
|
|
|
235
|
-
handleLearnMore() {
|
|
236
|
-
this.template
|
|
237
|
-
.querySelector(".legal-terms-learn-more")
|
|
238
|
-
?.classList.toggle("hidden");
|
|
239
|
-
}
|
|
240
|
-
|
|
241
266
|
private updateInnerHtml(selector: string, html: string): void {
|
|
242
267
|
const element = this.template.querySelector(selector);
|
|
243
268
|
if (element) {
|