-
Notifications
You must be signed in to change notification settings - Fork 3
/
script.js
249 lines (210 loc) · 6.31 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
const form = document.getElementById("form");
const formSteps = [...document.getElementsByClassName("step")];
const stepsOverview = [...document.getElementsByClassName("form-step")];
// set current step to start form
let currentStep = 0;
// step 1 - inputs
const userName = document.getElementById("name");
const email = document.getElementById("email");
// step 2 - inputs
const serviceCheckboxes = document.querySelectorAll(`input[type="checkbox"]`);
// step 3 - inputs
const budgetRadios = document.querySelectorAll(`input[name="budget"]`);
// step 4 - inputs (final)
const phone = document.getElementById("phone");
const company = document.getElementById("company");
// initiate radio and checkbox listeners for steps 2 and 3
addRadioListeners();
addCheckboxListeners();
// listen for click in form
// only continue if click is on a next or previous button
form.addEventListener("click", (e) => {
const next = e.target.classList.contains("next");
const previous = e.target.classList.contains("previous");
if (!next && !previous) return;
if (previous) {
currentStep -= 1;
handleCurrentStep(currentStep);
showCurrentStep();
return;
}
// no need to call last step, as that is called through the Webflow.push function on page load, found below
switch (true) {
case currentStep === 0:
validateStepOne();
break;
case currentStep === 1:
validateStepTwo();
break;
case currentStep === 2:
validateStepThree();
break;
default:
break;
}
});
// show current step in form
function showCurrentStep() {
formSteps.forEach((step, index) => {
step.classList.toggle("active", index === currentStep);
});
}
// go to next step
function goToNextStep() {
currentStep += 1;
handleCurrentStep(currentStep);
showCurrentStep();
}
// handle current step
function handleCurrentStep(liveStep) {
stepsOverview.forEach((step, index) => {
if (liveStep === index) {
step.classList.add("current-step");
} else {
step.classList.remove("current-step");
}
});
}
// set error in each step
const setError = (element, message) => {
const inputControl = element.parentElement;
const errorMessage = inputControl.querySelector(".error-message");
errorMessage.innerText = message;
errorMessage.style.display = "block";
if (
element?.childNodes[0]?.type === "radio" ||
element?.childNodes[0]?.type === "checkbox"
)
return;
// only change input if text, email, textarea, phone, or number
element.classList.add("input-error");
element.classList.remove("input-success");
};
// set success in each step and remove error message
const setSuccess = (element) => {
const inputControl = element.parentElement;
const errorMessage = inputControl.querySelector(".error-message");
errorMessage.innerText = "";
errorMessage.style.display = "none";
element.classList.remove("input-error");
if (
element?.childNodes[0]?.type === "radio" ||
element?.childNodes[0]?.type === "checkbox"
)
return;
// only change input if text, email, textarea, phone, number
element.classList.add("input-success");
};
// validation steps
function validateStepOne() {
const checkName = validateNameInput();
const checkEmail = validateEmailInput();
if (!checkName || !checkEmail) return;
goToNextStep();
}
function validateStepTwo() {
const checkboxes = [...document.querySelectorAll('input[type="checkbox"]')];
const checkAtLeastOne = checkboxes.some((input) => input.checked);
if (checkAtLeastOne) {
goToNextStep();
setSuccess(budgetRadios[0].parentElement);
} else {
setError(checkboxes[0].parentElement, "Select at least one option");
}
}
function validateStepThree() {
const isItChecked = document.querySelector('input[name="budget"]:checked');
if (isItChecked !== null) {
setSuccess(budgetRadios[0].parentElement);
goToNextStep();
return;
} else {
setError(budgetRadios[0].parentElement, "Select a budget");
}
}
// last step validation on form submit
Webflow.push(function () {
$("form").submit(function () {
const checkNumber = validatePhoneInput();
if (!checkNumber) return false;
});
});
// event listeners
function addRadioListeners() {
for (radio in budgetRadios) {
budgetRadios[radio].onclick = function () {
if (this.value) {
setSuccess(budgetRadios[0].parentElement);
}
};
}
}
function addCheckboxListeners() {
for (checkbox in serviceCheckboxes) {
serviceCheckboxes[checkbox].onclick = function () {
if (this.value) {
setSuccess(serviceCheckboxes[0].parentElement);
}
};
}
}
// validation on blur
userName.addEventListener("blur", validateNameInput);
email.addEventListener("blur", validateEmailInput);
phone.addEventListener("blur", validatePhoneInput);
// validation on keystroke only if input error class is active
userName.addEventListener(
"input",
() => inputHasError(userName) && validateNameInput()
);
phone.addEventListener(
"input",
() => inputHasError(phone) && validatePhoneInput()
);
email.addEventListener(
"input",
() => inputHasError(email) && validateEmailInput()
);
// utility functions to check if input has the input error class
function inputHasError(input) {
return input.classList.contains("input-error");
}
// validation functions
function validateNameInput() {
if (userName.value.trim() === "") {
setError(userName, "Name is required");
return false;
} else if (userName.value.trim().length < 3) {
setError(userName, "Name must be 3 characters or longer");
return false;
} else {
setSuccess(userName);
return true;
}
}
function validateEmailInput() {
const emailPattern =
/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
const isEmailValid = emailPattern.test(email.value);
if (!isEmailValid) {
setError(email, "Enter a valid email address i.e., mail@me.com");
return false;
} else {
setSuccess(email);
return true;
}
}
function validatePhoneInput() {
const phonePattern = /^[0-9]*$/;
const isPhoneValid = phonePattern.test(phone.value);
if (!isPhoneValid) {
setError(phone, "Enter numbers only");
return false;
} else if (phone.value.length < 10) {
setError(phone, "Phone number must be 10 digits");
return false;
} else {
setSuccess(phone);
return true;
}
}