-
Notifications
You must be signed in to change notification settings - Fork 0
/
form-scripts.js
221 lines (187 loc) · 6.67 KB
/
form-scripts.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
window.addEventListener('DOMContentLoaded', function() {
var budget = document.getElementById('budget'),
budgetOutput = document.querySelector('#range-output');
/***************** INPUT MONTH STUFF *****************/
// This whole stuff adds better usability cross-browser: when input[type=month] is supported it provides a default value (next month), when it is not supported, it gives a placeholder (next month). This also lays out the ground for form validation afterwards where, in both cases, if the value is empty when the form is submitted, the script automatically assigns next month.
var months = {'01': 'January', '02': 'February', '03': 'March', '04': 'April', '05': 'May', '06': 'June', '07': 'July', '08': 'August', '09': 'September', '10': 'October', '11': 'November', '12': 'December'},
date = document.getElementById('date'),
year = new Date().getFullYear(),
month = new Date().getMonth() + 1;
month = month < 10 ? "0" + (month+1) : month+1;
if (month === 13) {
month = '01';
year += 1;
}
function checkInput(type) {
var input = document.createElement("input");
input.setAttribute("type", type);
return input.type === type;
}
if (checkInput("month")) {
var nextMonthValue = year + '-' + month;
date.value = nextMonthValue;
} else {
var nextMonthPlaceholder = months[month] + ' ' + year;
date.placeholder = nextMonthPlaceholder;
}
/***************** RANGE INPUT STUFF *****************/
function rangeUpdate() {
var value = (budget.value - budget.min)/(budget.max - budget.min)*100,
valueTo = value + 0.1;
budget.style.backgroundImage = [
'linear-gradient(',
'to right, ',
'#3DACDF ' + value + '%, ',
'#F2F2F2 ' + valueTo + '%',
')'
].join('');
budgetOutput.value = budget.value;
}
rangeUpdate();
budget.oninput = rangeUpdate;
/***************** FORM MAGIC *****************/
var theForm = document.getElementById('contactForm'),
formContainer = theForm.parentNode,
nameInput = theForm.name,
emailInput = theForm.email,
errorMessageEmpty = 'This field is required.',
errorMessageLength = 'This is way too long to be real.',
errorMessageInvalidEmail = 'Please, insert a valid email address',
errorMessage = '',
wait = document.getElementById('wait');
// This thing hides the menu while the textarea is focused to fix a bug where the menu could appear above the textarea itself when the text was too long
// if ( isiOS && isSafari ) {
// textarea.addEventListener('focus', function() {
// document.getElementsByTagName('header')[0].style.visibility = 'hidden';
//
// textarea.addEventListener('blur', function() {
// document.getElementsByTagName('header')[0].style.visibility = 'visible';
// });
// });
// }
theForm.setAttribute('novalidate', 'true');
function valueIsValid( input, type, maxlen ) {
// shorthand for: if undefined then
type = type || 'plain';
maxlen = maxlen || 100;
input = input.value;
if ( input === '' ) {
errorMessage = errorMessageEmpty;
return false;
} else if ( input.length > maxlen ) {
errorMessage = errorMessageLength;
return false;
} else { // input not empty and normal lenght
switch ( type ) {
case 'email': // check for email plausibility
var atpos = input.indexOf("@"),
dotpos = input.lastIndexOf(".");
if ( atpos < 1 || ( dotpos - atpos < 2 ) ) {
errorMessage = errorMessageInvalidEmail;
} else { // valid email
return true;
}
break;
default: // valid plain text
return true;
}
}
}
function errorFlash( questo ) {
if ( !questo.parentNode.classList.contains('error') ) {
questo.parentNode.classList.add('error');
}
questo.nextElementSibling.textContent = errorMessage;
}
function readyAgain( questo ) {
questo.addEventListener('focus', function() {
questo.parentNode.className = questo.parentNode.className.replace( /(?:^|\s)error(?!\S)/g , '' );
}, true);
}
nameInput.addEventListener('blur', function() {
if ( !valueIsValid( this ) ) {
errorFlash( this );
readyAgain(this);
}
}, true);
emailInput.addEventListener('focus', function() {
this.nextElementSibling.nextElementSibling.classList.add('show');
this.addEventListener('blur', function(event) {
this.nextElementSibling.nextElementSibling.classList.remove('show');
}, true);
}, true);
emailInput.addEventListener('blur', function() {
if ( !valueIsValid( this, 'email' )) {
errorFlash( this );
readyAgain(this);
}
}, true);
function validate() {
var validity = false,
validName = false,
validEmail = false;
if ( valueIsValid( nameInput ) ) {
validName = true;
} else {
errorFlash( nameInput );
readyAgain( nameInput );
}
if ( valueIsValid( emailInput, 'email' ) ) {
validEmail = true;
} else {
errorFlash( emailInput );
readyAgain( emailInput );
}
if ( validName === true && validEmail === true ) {
validity = true;
}
// Force "next month" when no date is submitted, this prevents empty data on the server side of life
if (date.value === '') {
if (checkInput('month')) {
var nextMonthValue = year + '-' + month;
date.value = nextMonthValue;
} else {
var nextMonthPlaceholder = months[month] + ' ' + year;
date.value = nextMonthPlaceholder;
}
}
return validity;
}
function sendData() {
var XHR = new XMLHttpRequest();
// We bind the FormData object and the form element
var FD = new FormData(theForm);
// We define what will happen if the data are successfully sent
XHR.addEventListener("load", function(event) {
wait.className = wait.className.replace( /(?:^|\s)showWait(?!\S)/g , '' );
window.scrollTo({top: document.getElementById('contact-page').offsetTop - 80, behavior: 'smooth'});
formContainer.innerHTML = event.target.responseText;
});
// We define what will happen in case of error
XHR.addEventListener("error", function() {
window.alert('Oups! Something goes wrong.');
});
// We setup our request
XHR.open("POST", "contact.php");
// The data sent are the one the user provide in the form
XHR.send(FD);
}
// to takeover its submit event.
theForm.addEventListener("submit", function (event) {
event.preventDefault();
if ( validate() ) {
wait.className += 'showWait';
sendData();
} else {
var submitLabel = document.querySelector('.submit-label');
var submitButton = document.getElementById('formSubmit');
submitLabel.classList.add('shake');
submitButton.classList.add('shake');
submitLabel.onanimationend = function () {
window.scrollTo({ top: document.getElementById('contact-page').offsetTop - 80, behavior: 'smooth' });
submitLabel.classList.remove('shake');
submitButton.classList.remove('shake');
}
}
});
});