-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
139 lines (127 loc) · 4.3 KB
/
app.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
// wrap everything in a function so variables/functions are not globally available
function init() {
/* 1. Variable Declarations */
const happyForm = document.querySelector('#happyForm');
const firstNameInput = document.querySelector('#firstName');
const lastNameInput = document.querySelector('#lastName');
const commentBox = document.querySelector('#comment');
const checkbox = document.querySelector('#subscribe');
const emailInput = document.querySelector('#email');
const submitButton = document.querySelector('#submitButton');
const message = document.querySelector('#message');
/* 2. Function Declarations */
/**
* Toggle the visibility on a specified HTML element
* https://gomakethings.com/how-to-show-and-hide-elements-with-vanilla-javascript/
* @param {HTMLElement} elem The HTML element we want to toggle visibility
*/
function toggleVisibility(elem) {
elem.classList.toggle('is-visible');
}
/**
* enable submit button when the first and last name inputs have at least 1 character
* https://stackoverflow.com/a/67961881
*/
function areInputsPopulated() {
submitButton.disabled = !(
firstNameInput.value.length > 0 && lastNameInput.value.length > 0
);
}
/**
* Get data from the form
* @returns {Object} An object that contains the data from the form fields
*/
function getFormData() {
let formData = {
firstName: firstNameInput.value,
lastName: lastNameInput.value,
comment: commentBox.value,
isSubscribed: false,
};
// if subscribed is checked, update the formData
if (checkbox.checked) {
formData.isSubscribed = true;
formData.email = emailInput.value;
}
return formData;
}
/**
* run a fetch POST request
* @param {String} url the url that the POST is being sent to
* @param {Object} formObj An object that contains the form field data
* @returns {Function} Return the result from the POST fetch request
*/
async function postUser(url, formObj) {
return fetch(url, {
method: 'POST',
body: JSON.stringify(formObj),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
});
}
/**
* Clear the inputs/checkbox from the happyForm
*/
function clearFormFields() {
firstNameInput.value = '';
lastNameInput.value = '';
submitButton.disabled = true;
// only if comment textarea is populated
if (commentBox.value.length > 0) {
commentBox.value = '';
}
// only if the checkbox is checked
if (checkbox.checked) {
checkbox.checked = false;
}
// only if email input is populated
if (emailInput.value.length > 0) {
emailInput.value = '';
emailInput.classList.remove('is-visible');
}
}
/* Event Listeners/executing functions */
// https://gomakethings.com/listening-for-events-on-multiple-elements-using-javascript-event-delegation/
document.addEventListener('change', (event) => {
// if the target is not checkbox, do nothing
if (event.target !== checkbox) return;
toggleVisibility(emailInput);
});
document.addEventListener('input', (event) => {
// if the target is the firstName input or lastName input
if (event.target === firstNameInput || event.target === lastNameInput) {
areInputsPopulated();
}
// else do nothing
return;
});
document.addEventListener('submit', async (event) => {
// if the target is not the happyForm, do nothing
if (event.target !== happyForm) return;
// stop the action default of refreshing
event.preventDefault();
let formData = getFormData();
// wrap async/await in try/catch for error handling
try {
let data = await postUser('https://jsonplaceholder.typicode.com/users', formData);
let status = await data.status;
// status 200-206: success
// status 300-308: redirection
if (status >= 200 && status < 400) {
message.textContent = `Thanks for the submission ${formData.firstName}!`;
// clear the form fields
clearFormFields();
// remove message after a 2 second delay
setTimeout(() => message.textContent = '', 2000);
} else {
message.textContent = `Oops something went wrong`;
}
} catch (e) {
message.textContent = `Oops something went wrong`;
console.error(e);
}
});
}
//run the init function so the event listeners are added
init();