@salesforcedevs/dw-components 1.3.148-canary.0 → 1.3.148-canary.10
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 +1 -1
- package/src/modules/dw/j2sCardSequence/j2sCardSequence.html +7 -1
- package/src/modules/dw/j2sCardSequence/j2sCardSequence.ts +145 -38
- package/src/modules/dw/j2sCardSequence/mockProps.ts +58 -43
- package/src/modules/dw/j2sForm/j2sForm.css +8 -2
- package/src/modules/dw/j2sForm/j2sForm.html +12 -10
- package/src/modules/dw/j2sForm/j2sForm.ts +58 -20
package/package.json
CHANGED
|
@@ -38,7 +38,12 @@
|
|
|
38
38
|
form-metadata={stepDatum.formMetadata}
|
|
39
39
|
incoming-user-info={formIncomingUserInfo}
|
|
40
40
|
onformvaliditychange={handleFormValidityChange}
|
|
41
|
-
|
|
41
|
+
recaptcha-token={recaptchaToken}
|
|
42
|
+
>
|
|
43
|
+
<div slot="form-captcha-slot">
|
|
44
|
+
<slot name="captcha-slot"></slot>
|
|
45
|
+
</div>
|
|
46
|
+
</dw-j2s-form>
|
|
42
47
|
</template>
|
|
43
48
|
</template>
|
|
44
49
|
</div>
|
|
@@ -52,6 +57,7 @@
|
|
|
52
57
|
<dx-button
|
|
53
58
|
class="primary-action"
|
|
54
59
|
disabled={isJ2sFormInvalid}
|
|
60
|
+
href={stepDatum.primaryAction.link}
|
|
55
61
|
icon-sprite={stepDatum.primaryAction.iconSprite}
|
|
56
62
|
icon-symbol={stepDatum.primaryAction.iconSymbol}
|
|
57
63
|
loading={isLoading}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { api, LightningElement } from "lwc";
|
|
2
2
|
import StepSequence from "dx/stepSequence";
|
|
3
3
|
import { getListWithUuids } from "dxUtils/list";
|
|
4
|
+
import { track } from "dxUtils/analytics";
|
|
4
5
|
import { toJson } from "dxUtils/normalizers";
|
|
5
|
-
import Button from "dx/button";
|
|
6
6
|
|
|
7
7
|
export type StepDatum = {
|
|
8
8
|
bodyHtml?: string;
|
|
@@ -25,23 +25,34 @@ export type StepDatum = {
|
|
|
25
25
|
textColor?: string;
|
|
26
26
|
};
|
|
27
27
|
primaryAction: {
|
|
28
|
-
text: string;
|
|
29
|
-
variant?: string;
|
|
30
28
|
iconSprite?: string;
|
|
31
29
|
iconSymbol?: string;
|
|
30
|
+
link?: string;
|
|
31
|
+
text: string;
|
|
32
|
+
variant?: string;
|
|
32
33
|
};
|
|
33
34
|
secondaryActionHtml?: string;
|
|
34
35
|
showStepNumber?: boolean;
|
|
35
36
|
stepTitle: string;
|
|
36
37
|
};
|
|
37
38
|
|
|
39
|
+
function isNoAnimationCookieSet() {
|
|
40
|
+
return document.cookie
|
|
41
|
+
.split(";")
|
|
42
|
+
.some((ck) => ck.trim() === "no_j2s_animation=true");
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
export default class J2sCardSequence extends LightningElement {
|
|
46
|
+
_didRenderStaticInnerHtml = false;
|
|
39
47
|
_isDrmLoading = false;
|
|
48
|
+
_isFormSubmitting = false;
|
|
40
49
|
_isJ2sFormInvalid = false;
|
|
41
50
|
_isTbidLoading = false;
|
|
42
51
|
_stepsData: StepDatum[] = [];
|
|
43
52
|
@api animateTransitions = false;
|
|
44
53
|
@api drmDomain: string = "https://drm.my.salesforce-sites.com";
|
|
54
|
+
@api formHandler: string =
|
|
55
|
+
"https://formhandlermule-1s9xrb.5sc6y6-4.usa-e2.cloudhub.io/form_handler";
|
|
45
56
|
@api tbidApiBaseUrl: string | undefined;
|
|
46
57
|
@api useHistory: boolean = false;
|
|
47
58
|
|
|
@@ -50,9 +61,9 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
50
61
|
return this._stepsData;
|
|
51
62
|
}
|
|
52
63
|
set stepsData(value) {
|
|
64
|
+
// normalize incoming value with uuid keys and non-required props (for cleaner HTML template), etc.
|
|
53
65
|
this._stepsData = getListWithUuids<StepDatum>(toJson(value)).map(
|
|
54
66
|
(stepDatum) => {
|
|
55
|
-
// small bit of normalization for cleaner HTML templates with non-required props, etc.
|
|
56
67
|
const normalizedStepDatum = {
|
|
57
68
|
...stepDatum,
|
|
58
69
|
headerData: stepDatum.headerData || {},
|
|
@@ -79,11 +90,14 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
79
90
|
|
|
80
91
|
private countries = "[]";
|
|
81
92
|
private currentSequenceStep = 0;
|
|
93
|
+
private recaptchaToken = "";
|
|
82
94
|
private sessionStorageId = "j2s-card-sequence";
|
|
83
95
|
private tbidUserInfo: any; // TODO typings?
|
|
84
96
|
|
|
85
97
|
private get isLoading() {
|
|
86
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
this._isDrmLoading || this._isTbidLoading || this._isFormSubmitting
|
|
100
|
+
);
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
private get isLoggedIn() {
|
|
@@ -144,12 +158,26 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
144
158
|
);
|
|
145
159
|
}
|
|
146
160
|
|
|
161
|
+
@api
|
|
162
|
+
recaptchaCallback(responseToken: string) {
|
|
163
|
+
this.recaptchaToken = responseToken;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@api
|
|
167
|
+
recaptchaExpiredCallback() {
|
|
168
|
+
this.recaptchaToken = "";
|
|
169
|
+
}
|
|
170
|
+
|
|
147
171
|
connectedCallback() {
|
|
148
172
|
this.getCountryList();
|
|
149
173
|
this.getTbidUserInfo();
|
|
150
174
|
// This has to be defined here since it depends on a variable that depends on sessionStorage.
|
|
151
175
|
this.currentSequenceStep = this.initialStepIndex;
|
|
152
176
|
this.resetCustomButtonColors();
|
|
177
|
+
if (isNoAnimationCookieSet()) {
|
|
178
|
+
/* eslint-disable-next-line @lwc/lwc/no-api-reassignments */
|
|
179
|
+
this.animateTransitions = false;
|
|
180
|
+
}
|
|
153
181
|
}
|
|
154
182
|
|
|
155
183
|
renderedCallback() {
|
|
@@ -157,24 +185,21 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
157
185
|
return;
|
|
158
186
|
}
|
|
159
187
|
|
|
160
|
-
|
|
161
|
-
this.
|
|
162
|
-
|
|
163
|
-
this.template.querySelectorAll("span.body-markup")[
|
|
164
|
-
this.currentSequenceStep
|
|
165
|
-
];
|
|
166
|
-
const secondaryActionMarkupContainer = this.template.querySelectorAll(
|
|
167
|
-
"span.secondary-action-markup"
|
|
168
|
-
)[this.currentSequenceStep];
|
|
169
|
-
if (bodyMarkupContainer) {
|
|
170
|
-
bodyMarkupContainer.innerHTML = bodyHtml || "";
|
|
171
|
-
}
|
|
172
|
-
if (secondaryActionMarkupContainer) {
|
|
173
|
-
secondaryActionMarkupContainer.innerHTML =
|
|
174
|
-
secondaryActionHtml || "";
|
|
188
|
+
if (!this._didRenderStaticInnerHtml) {
|
|
189
|
+
this.updateStaticInnerHtml();
|
|
190
|
+
this._didRenderStaticInnerHtml = true;
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
|
|
194
|
+
handleFormValidityChange({ detail }: CustomEvent) {
|
|
195
|
+
this.isJ2sFormInvalid = !detail.isValid;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
handleStepSequenceChange({ detail }: CustomEvent) {
|
|
199
|
+
this.currentSequenceStep = detail.stepIndex;
|
|
200
|
+
this.resetCustomButtonColors();
|
|
201
|
+
}
|
|
202
|
+
|
|
178
203
|
handleGetStarted(evt: Event) {
|
|
179
204
|
// If the user is not yet logged in, we need to prevent moving immediately to the next
|
|
180
205
|
// step, but set storage up so that they are on the second step when they return to the
|
|
@@ -182,32 +207,82 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
182
207
|
if (!this.isLoggedIn) {
|
|
183
208
|
evt.preventDefault();
|
|
184
209
|
this.initialStepIndex = 1;
|
|
210
|
+
this._isTbidLoading = true;
|
|
185
211
|
// @ts-ignore: call out to the tbid-controller on DSC
|
|
186
212
|
window.__startTbidLogin();
|
|
187
213
|
}
|
|
188
214
|
}
|
|
189
215
|
|
|
190
|
-
|
|
191
|
-
this.isJ2sFormInvalid
|
|
192
|
-
|
|
216
|
+
async handleFormSubmit(evt: Event) {
|
|
217
|
+
if (!this.formHandler || this.isJ2sFormInvalid || !this.isLoggedIn) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
193
220
|
|
|
194
|
-
|
|
195
|
-
this.
|
|
196
|
-
|
|
221
|
+
evt.preventDefault(); // don't proceed automatically to next step
|
|
222
|
+
this._isFormSubmitting = true;
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
const formData = (this.template.querySelector("dw-j2s-form") as any)
|
|
226
|
+
?.formDataForDrm;
|
|
227
|
+
// For some countries, explicit approvals will be present; for others, it is implicitly assumed
|
|
228
|
+
if (typeof formData.Opt_In__c !== "boolean") {
|
|
229
|
+
formData.Opt_In__c = true;
|
|
230
|
+
}
|
|
231
|
+
if (typeof formData.Privacy_Statement__c !== "boolean") {
|
|
232
|
+
formData.Privacy_Statement__c = true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const res = await fetch(this.formHandler, {
|
|
236
|
+
method: "POST",
|
|
237
|
+
headers: {
|
|
238
|
+
"Captcha-Response": this.recaptchaToken
|
|
239
|
+
},
|
|
240
|
+
body: JSON.stringify({
|
|
241
|
+
...formData,
|
|
242
|
+
handlerName: "J2S Registration Page",
|
|
243
|
+
TBID__c: this.tbidUserInfo.user_id
|
|
244
|
+
})
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (res.ok) {
|
|
248
|
+
const resData = await res.json();
|
|
249
|
+
if (resData.status === "success") {
|
|
250
|
+
this.jumpToStepIndex(2);
|
|
251
|
+
} else {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Form submission failed. (status: ${resData.status}, message: ${resData.errorMessage})`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
} catch (ex) {
|
|
258
|
+
console.error(ex); // TODO
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
this._isFormSubmitting = false;
|
|
197
262
|
}
|
|
198
263
|
|
|
199
264
|
primaryActionHandler(evt: Event) {
|
|
200
|
-
|
|
265
|
+
const target = evt.target as HTMLButtonElement;
|
|
266
|
+
|
|
267
|
+
if (!target || target.disabled) {
|
|
201
268
|
evt.preventDefault();
|
|
202
269
|
return;
|
|
203
270
|
}
|
|
204
271
|
|
|
272
|
+
track(target, "custEv_ctaButtonClick", {
|
|
273
|
+
click_text: target.textContent,
|
|
274
|
+
element_title: this.stepsData[this.currentSequenceStep].stepTitle,
|
|
275
|
+
click_url:
|
|
276
|
+
this.stepsData[this.currentSequenceStep].primaryAction.link ||
|
|
277
|
+
"",
|
|
278
|
+
element_type: "button",
|
|
279
|
+
content_category: "cta"
|
|
280
|
+
});
|
|
281
|
+
|
|
205
282
|
if (!this.currentSequenceStep) {
|
|
206
283
|
this.handleGetStarted(evt);
|
|
207
|
-
} else if (this.currentSequenceStep ===
|
|
208
|
-
|
|
209
|
-
} else if (this.currentSequenceStep === 3) {
|
|
210
|
-
// TODO: Join Slack
|
|
284
|
+
} else if (this.currentSequenceStep === 1) {
|
|
285
|
+
this.handleFormSubmit(evt);
|
|
211
286
|
}
|
|
212
287
|
}
|
|
213
288
|
|
|
@@ -237,10 +312,42 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
237
312
|
);
|
|
238
313
|
}
|
|
239
314
|
|
|
315
|
+
private jumpToStepIndex(stepIndex: number) {
|
|
316
|
+
this.initialStepIndex = stepIndex; // update sessionStorage value
|
|
317
|
+
((this.template.querySelector(
|
|
318
|
+
"dx-step-sequence"
|
|
319
|
+
) as unknown) as StepSequence)?.jumpToStep(stepIndex);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// HTML is received via config from DSC and should be static after initial render.
|
|
323
|
+
private updateStaticInnerHtml() {
|
|
324
|
+
const bodyMarkupContainers = this.template.querySelectorAll(
|
|
325
|
+
"span.body-markup"
|
|
326
|
+
);
|
|
327
|
+
const secondaryActionMarkupContainers = this.template.querySelectorAll(
|
|
328
|
+
"span.secondary-action-markup"
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
this.stepsData.forEach((step, stepIndex) => {
|
|
332
|
+
const { bodyHtml, secondaryActionHtml } = step;
|
|
333
|
+
const bodyMarkupContainer = bodyMarkupContainers[stepIndex];
|
|
334
|
+
const secondaryActionMarkupContainer =
|
|
335
|
+
secondaryActionMarkupContainers[stepIndex];
|
|
336
|
+
|
|
337
|
+
if (bodyMarkupContainer) {
|
|
338
|
+
bodyMarkupContainer.innerHTML = bodyHtml || "";
|
|
339
|
+
}
|
|
340
|
+
if (secondaryActionMarkupContainer) {
|
|
341
|
+
secondaryActionMarkupContainer.innerHTML =
|
|
342
|
+
secondaryActionHtml || "";
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
240
347
|
private async getCountryList() {
|
|
241
348
|
this._isDrmLoading = true;
|
|
242
349
|
|
|
243
|
-
const errorMsg = "Error while getting
|
|
350
|
+
const errorMsg = "Error while getting country list";
|
|
244
351
|
try {
|
|
245
352
|
const res = await fetch(
|
|
246
353
|
`${this.drmDomain}/utilities/services/apexrest/countries`
|
|
@@ -252,6 +359,11 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
252
359
|
this.countries = JSON.stringify(data);
|
|
253
360
|
} catch (error) {
|
|
254
361
|
console.error(error);
|
|
362
|
+
if (this.initialStepIndex > 0) {
|
|
363
|
+
// Page loaded on a step higher than the first, but we can't get data for the form;
|
|
364
|
+
// send user back to the start for now.
|
|
365
|
+
this.jumpToStepIndex(0);
|
|
366
|
+
}
|
|
255
367
|
}
|
|
256
368
|
|
|
257
369
|
this._isDrmLoading = false;
|
|
@@ -272,12 +384,7 @@ export default class J2sCardSequence extends LightningElement {
|
|
|
272
384
|
if (!this.tbidUserInfo && this.initialStepIndex > 0) {
|
|
273
385
|
// login failed and the user was previously beyond the start step; need to send them
|
|
274
386
|
// back to the start:
|
|
275
|
-
this.
|
|
276
|
-
(
|
|
277
|
-
this.template.querySelector(
|
|
278
|
-
"dx-step-sequence"
|
|
279
|
-
) as unknown as StepSequence
|
|
280
|
-
)?.jumpToStep(0);
|
|
387
|
+
this.jumpToStepIndex(0);
|
|
281
388
|
}
|
|
282
389
|
|
|
283
390
|
this._isTbidLoading = false;
|
|
@@ -1,46 +1,61 @@
|
|
|
1
|
-
export const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
showStepNumber: "true",
|
|
11
|
-
stepTitle: "Complete your registration.",
|
|
12
|
-
formData: {
|
|
13
|
-
countriesWithReferralInput: ["IN"],
|
|
14
|
-
countriewWithRequiredJobRole: ["CA"],
|
|
15
|
-
notAvailableAlertInfo: {
|
|
16
|
-
title: "Not Available",
|
|
17
|
-
body: 'The Journey to Salesforce program is not currently available in your country. See the <a href="https://www.google.com/">program FAQs</a> for a list of participating countries.'
|
|
1
|
+
export const stepSequenceData = {
|
|
2
|
+
animateTransitions: "true",
|
|
3
|
+
stepsData: [
|
|
4
|
+
{
|
|
5
|
+
bodyHtml:
|
|
6
|
+
'<p class="dx-text-display-7">Register for Journey to Salesforce and you\'ll be on your way to becoming a Salesforce Developer.</p><ul class="dx-text-display-8"><li>Step 1: Log in or sign up for a free Trailblazer.me account</li><li>Step 2: Confirm your program registration</li><li>Step 3: Begin your journey!</li></ul>',
|
|
7
|
+
primaryAction: {
|
|
8
|
+
text: "Get Started"
|
|
18
9
|
},
|
|
19
|
-
|
|
10
|
+
showStepNumber: "true",
|
|
11
|
+
stepTitle: "Get started now."
|
|
20
12
|
},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
13
|
+
{
|
|
14
|
+
bodyHtml:
|
|
15
|
+
'<p class="dx-text-display-7">You\'re almost done! Please review your information and agree to the Journey to Salesforce program terms and conditions.</p>',
|
|
16
|
+
formData: {
|
|
17
|
+
countriesWithReferralInput: ["IN"],
|
|
18
|
+
countriesWithRequiredJobRole: ["CA"],
|
|
19
|
+
formId: "j2s-form",
|
|
20
|
+
j2sTerms:
|
|
21
|
+
'I agree to the Journey to Salesforce Program Terms, subject to the <a href="http://www.google.com">Salesforce Program Agreement</a>.',
|
|
22
|
+
notAvailableAlertInfo: {
|
|
23
|
+
title: "Not Available",
|
|
24
|
+
body:
|
|
25
|
+
'The Journey to Salesforce program is not currently available in your country. See the <a href="https://www.google.com/">program FAQs</a> for a list of participating countries.'
|
|
26
|
+
},
|
|
27
|
+
participatingCountryCodes: ["US", "CA", "IN"]
|
|
28
|
+
},
|
|
29
|
+
primaryAction: {
|
|
30
|
+
text: "Complete Registration"
|
|
31
|
+
},
|
|
32
|
+
secondaryActionHtml:
|
|
33
|
+
'<span class="required-notice">* Required to participate in Journey to Salesforce</span>',
|
|
34
|
+
showStepNumber: "true",
|
|
35
|
+
stepTitle: "Complete your registration."
|
|
36
36
|
},
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
{
|
|
38
|
+
bodyHtml:
|
|
39
|
+
'<div class="dx-text-display-8"><p>Welcome to Journey to Salesforce! Congratulations on taking this step in your journey towards becoming a Salesforce Developer. Through this program you\'ll gain the knowledge, experience, and skills to help you excel in the Salesforce ecosystem.</p><p>To get started, click the button below to join the Journey to Salesforce community, and make sure to check your email for links to bookmark!</p></div>',
|
|
40
|
+
headerData: {
|
|
41
|
+
backgroundColor: "green-vibrant-95",
|
|
42
|
+
iconSymbol: "check-circle",
|
|
43
|
+
iconSprite: "general",
|
|
44
|
+
iconColor: "green-vibrant-65",
|
|
45
|
+
textColor: "indigo-vibrant-20"
|
|
46
|
+
},
|
|
47
|
+
primaryAction: {
|
|
48
|
+
iconSprite: "utility",
|
|
49
|
+
iconSymbol: "new_window",
|
|
50
|
+
link:
|
|
51
|
+
"https://salesforce-external.slack.com/archives/C05HJK4PGJV",
|
|
52
|
+
text: "Join Slack",
|
|
53
|
+
variant: "custom"
|
|
54
|
+
},
|
|
55
|
+
secondaryActionHtml:
|
|
56
|
+
'<span class="dx-text-display-7">Ready to jump in?</span>',
|
|
57
|
+
showStepNumber: "true",
|
|
58
|
+
stepTitle: "Your Registration is Confirmed"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
};
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
.form-row .terms {
|
|
24
|
-
--dx-c-checkbox-text-line-height:
|
|
25
|
-
--dx-c-checkbox-font-size:
|
|
24
|
+
--dx-c-checkbox-text-line-height: var(--dx-g-text-lg);
|
|
25
|
+
--dx-c-checkbox-font-size: var(--dx-g-text-sm);
|
|
26
26
|
|
|
27
27
|
font-family: var(--dx-g-font-sans);
|
|
28
28
|
font-size: var(--dx-c-checkbox-font-size);
|
|
@@ -44,3 +44,9 @@
|
|
|
44
44
|
.form-terms-container {
|
|
45
45
|
padding-top: var(--dx-g-spacing-sm);
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
.form-captcha-slot {
|
|
49
|
+
align-items: center;
|
|
50
|
+
display: flex;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!-- For the names of the form fields, see: https://salesforce.quip.com/daInAFETbPGm -->
|
|
2
3
|
<form class="j2s-form">
|
|
3
4
|
<div class="form-row">
|
|
4
5
|
<dx-input
|
|
5
6
|
class="first-name-field"
|
|
6
7
|
label="First Name"
|
|
7
8
|
missing-error-message="Enter your first name"
|
|
8
|
-
name="
|
|
9
|
+
name="FirstName"
|
|
9
10
|
placeholder="Your first name"
|
|
10
11
|
required
|
|
11
12
|
validity-on-blur
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
class="last-name-field"
|
|
17
18
|
label="Last Name"
|
|
18
19
|
missing-error-message="Enter your last name"
|
|
19
|
-
name="
|
|
20
|
+
name="LastName"
|
|
20
21
|
placeholder="Your last name"
|
|
21
22
|
required
|
|
22
23
|
validity-on-blur
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
class="company-name-field"
|
|
30
31
|
label="Company Name"
|
|
31
32
|
missing-error-message="Enter your company name"
|
|
32
|
-
name="
|
|
33
|
+
name="Company__c"
|
|
33
34
|
placeholder="Your company name"
|
|
34
35
|
required
|
|
35
36
|
validity-on-blur
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
class="job-role-field"
|
|
42
43
|
label="Job Role"
|
|
43
44
|
message-when-value-missing="Select your job role"
|
|
44
|
-
name="
|
|
45
|
+
name="DRM_Role__c"
|
|
45
46
|
options={jobRoles}
|
|
46
47
|
placeholder="Select Job Role"
|
|
47
48
|
value={state.jobRole}
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
class="job-role-field"
|
|
52
53
|
label="Job Role"
|
|
53
54
|
message-when-value-missing="Select your job role"
|
|
54
|
-
name="
|
|
55
|
+
name="DRM_Role__c"
|
|
55
56
|
options={jobRoles}
|
|
56
57
|
placeholder="Select Job Role"
|
|
57
58
|
required
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
</div>
|
|
62
63
|
<div class="form-row">
|
|
63
64
|
<dx-input
|
|
64
|
-
name="
|
|
65
|
+
name="Email"
|
|
65
66
|
type="email"
|
|
66
67
|
placeholder="Your email address"
|
|
67
68
|
label="Email"
|
|
@@ -74,7 +75,7 @@
|
|
|
74
75
|
<dx-select
|
|
75
76
|
label="Country/Region"
|
|
76
77
|
message-when-value-missing="Select your country/region"
|
|
77
|
-
name="
|
|
78
|
+
name="MailingCountry"
|
|
78
79
|
options={countries}
|
|
79
80
|
placeholder="Select Country/Region"
|
|
80
81
|
required
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
</div>
|
|
85
86
|
<div class="form-row" if:true={isCountryWithReferralInput}>
|
|
86
87
|
<dx-input
|
|
87
|
-
name="
|
|
88
|
+
name="Referral_Email__c"
|
|
88
89
|
class="referral-email-field full-width"
|
|
89
90
|
label="If anyone has referred you, please share their Email ID below, with their consent."
|
|
90
91
|
type="email"
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
<div class="form-row" if:true={state.showMarketingText}>
|
|
103
104
|
<dx-checkbox
|
|
104
105
|
value="marketing-terms"
|
|
105
|
-
name="
|
|
106
|
+
name="Opt_In__c"
|
|
106
107
|
required
|
|
107
108
|
class="terms"
|
|
108
109
|
onchange={handleRequiredFieldUpdate}
|
|
@@ -127,7 +128,7 @@
|
|
|
127
128
|
<dx-checkbox
|
|
128
129
|
if:true={state.showLegalCheckbox}
|
|
129
130
|
value="legal-terms"
|
|
130
|
-
name="
|
|
131
|
+
name="Privacy_Statement__c"
|
|
131
132
|
required
|
|
132
133
|
class="terms"
|
|
133
134
|
onchange={handleRequiredFieldUpdate}
|
|
@@ -153,6 +154,7 @@
|
|
|
153
154
|
class="legal-terms no-checkbox"
|
|
154
155
|
></span>
|
|
155
156
|
</div>
|
|
157
|
+
<slot class="form-captcha-slot" name="form-captcha-slot"></slot>
|
|
156
158
|
</div>
|
|
157
159
|
</form>
|
|
158
160
|
</template>
|
|
@@ -31,12 +31,14 @@ export type J2sFormState = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
34
|
-
private _didSetFormId = false;
|
|
35
|
-
private _isInitialRender = true;
|
|
36
|
-
private _incomingUserInfo: any = {}; // TODO typings
|
|
37
|
-
private _formMetadata: any = {}; // TODO typings
|
|
38
34
|
private _countriesJson = "";
|
|
39
35
|
private _countriesLookup: any = {}; // TODO typings
|
|
36
|
+
private _didSetFormId = false;
|
|
37
|
+
private _formMetadata: any = {}; // TODO typings
|
|
38
|
+
private _incomingUserInfo: any = {}; // TODO typings
|
|
39
|
+
private _isInitialRender = true;
|
|
40
|
+
private _recaptchaToken = "";
|
|
41
|
+
|
|
40
42
|
@api id = "";
|
|
41
43
|
@api referralText = "";
|
|
42
44
|
|
|
@@ -72,6 +74,33 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
72
74
|
this._formMetadata = toJson(value);
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
@api
|
|
78
|
+
get formDataForDrm() {
|
|
79
|
+
// We should be able to just get the formData from the form automatically using `new FormData(theForm)`,
|
|
80
|
+
// but our custom form elements don't seem to implement what it is required for that currently. See:
|
|
81
|
+
// https://web.dev/more-capable-form-controls/#defining-a-form-associated-custom-element
|
|
82
|
+
const formData: any = {};
|
|
83
|
+
this.template
|
|
84
|
+
.querySelectorAll("form [name]")
|
|
85
|
+
.forEach((namedElement) => {
|
|
86
|
+
const typedElement = namedElement as HTMLInputElement;
|
|
87
|
+
formData[typedElement.name] =
|
|
88
|
+
typeof typedElement.checked === "boolean"
|
|
89
|
+
? typedElement.checked
|
|
90
|
+
: typedElement.value;
|
|
91
|
+
});
|
|
92
|
+
return formData;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@api
|
|
96
|
+
get recaptchaToken() {
|
|
97
|
+
return this._recaptchaToken;
|
|
98
|
+
}
|
|
99
|
+
set recaptchaToken(value: string) {
|
|
100
|
+
this._recaptchaToken = value;
|
|
101
|
+
this.handleRequiredFieldUpdate();
|
|
102
|
+
}
|
|
103
|
+
|
|
75
104
|
private participatingCountryCodes = ["US", "CA", "IN"];
|
|
76
105
|
private countriesWithReferralInput = ["IN"];
|
|
77
106
|
private countriesWithRequiredJobRole = ["CA"];
|
|
@@ -141,7 +170,7 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
141
170
|
if (this.state.learnMore) {
|
|
142
171
|
this.updateInnerHtml(
|
|
143
172
|
"span.legal-terms-learn-more",
|
|
144
|
-
this.state.learnMore
|
|
173
|
+
` ${this.state.learnMore}`
|
|
145
174
|
);
|
|
146
175
|
} else {
|
|
147
176
|
this.updateInnerHtml("span.legal-terms-learn-more", "");
|
|
@@ -173,19 +202,8 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
173
202
|
}
|
|
174
203
|
}
|
|
175
204
|
|
|
176
|
-
private updateInnerHtml(selector: string, html: string): void {
|
|
177
|
-
const element = this.template.querySelector(selector);
|
|
178
|
-
if (element) {
|
|
179
|
-
element.innerHTML = html;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private isParticipatingCountry(country: string) {
|
|
184
|
-
return this.participatingCountryCodes.includes(country);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
205
|
handleRequiredFieldUpdate() {
|
|
188
|
-
const isFormNowValid = this.checkValidity(
|
|
206
|
+
const isFormNowValid = this.checkValidity();
|
|
189
207
|
if (this.state.isFormValid !== isFormNowValid) {
|
|
190
208
|
this.setState({
|
|
191
209
|
isFormValid: isFormNowValid
|
|
@@ -196,14 +214,22 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
196
214
|
handleCountryChange({ detail }: CustomEvent) {
|
|
197
215
|
const { value } = detail;
|
|
198
216
|
const countryData = this._countriesLookup[value];
|
|
217
|
+
|
|
199
218
|
this.setState({
|
|
200
219
|
country: value,
|
|
201
|
-
isFormValid: this.checkValidity(value),
|
|
202
220
|
learnMore: countryData.learnMore,
|
|
203
221
|
legalText: countryData.legalText,
|
|
204
222
|
marketingText: countryData.marketingText,
|
|
205
223
|
showLegalCheckbox: countryData.showLegalCheckbox
|
|
206
224
|
});
|
|
225
|
+
|
|
226
|
+
// Because updating the country can update the required fields, we need to re-set form
|
|
227
|
+
// validity after render
|
|
228
|
+
requestAnimationFrame(() =>
|
|
229
|
+
this.setState({
|
|
230
|
+
isFormValid: this.checkValidity()
|
|
231
|
+
})
|
|
232
|
+
);
|
|
207
233
|
}
|
|
208
234
|
|
|
209
235
|
handleLearnMore() {
|
|
@@ -212,9 +238,21 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
|
|
|
212
238
|
?.classList.toggle("hidden");
|
|
213
239
|
}
|
|
214
240
|
|
|
215
|
-
private
|
|
241
|
+
private updateInnerHtml(selector: string, html: string): void {
|
|
242
|
+
const element = this.template.querySelector(selector);
|
|
243
|
+
if (element) {
|
|
244
|
+
element.innerHTML = html;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private isParticipatingCountry(country: string) {
|
|
249
|
+
return this.participatingCountryCodes.includes(country);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private checkValidity() {
|
|
216
253
|
return (
|
|
217
|
-
this.
|
|
254
|
+
Boolean(this.recaptchaToken) &&
|
|
255
|
+
this.isParticipatingCountry(this.state.country) &&
|
|
218
256
|
this.requiredFormFields.every(
|
|
219
257
|
(requiredFormField) =>
|
|
220
258
|
// @ts-ignore
|