Contact validation and messages.

This commit is contained in:
JesseBrault0709 2024-06-09 14:46:57 +02:00
parent c0164c8137
commit 0aa17eef7f
3 changed files with 123 additions and 47 deletions

View File

@ -8,33 +8,33 @@ import com.jessebrault.site.StandardPage
<article class="contact">
<h1>Contact</h1>
<p>Please use the following form to contact Jesse Brault directly.</p>
<form class="contact">
<form id="contact-form" class="contact" novalidate>
<div class="control">
<label for="name">Name</label>
<input id="name" name="name" type="text" />
<p id="name-message" class="message">&nbsp;</p>
<label for="name-input">Name</label>
<input id="name-input" name="name" type="text" required />
<p id="name-message" class="message error">&nbsp;</p>
</div>
<div class="control">
<label for="institution">Institution</label>
<input id="institution" name="institution" type="text" />
<p id="institution-message" class="message">&nbsp;</p>
<label for="institution-input">Institution</label>
<input id="institution-input" name="institution" type="text" />
<p id="institution-message" class="message error">&nbsp;</p>
</div>
<div class="control">
<label for="email">Email</label>
<input id="email" name="email" type="email" />
<p id="email-message" class="message">&nbsp;</p>
<label for="email-input">Email</label>
<input id="email-input" name="email" type="email" required />
<p id="email-message" class="message error">&nbsp;</p>
</div>
<div class="control">
<label for="message">Message</label>
<textarea id="message" name="message"></textarea>
<p id="message-message" class="message">&nbsp;</p>
<label for="message-input">Message</label>
<textarea id="message-input" name="message" required></textarea>
<p id="message-message" class="message error">&nbsp;</p>
</div>
<div class="control">
<input type="submit" />
<input id="submit-input" type="submit" />
<p id="submit-message" class="message">&nbsp;</p>
</div>
</form>

View File

@ -1,37 +1,104 @@
window.addEventListener('load', function () {
const contactForm = document.querySelector('form.contact')
contactForm.addEventListener('submit', function (submitEvent) {
submitEvent.preventDefault()
const formData = new FormData(contactForm)
const toSend = {
name: formData.get('name'),
email: formData.get('email'),
institution: formData.get('institution'),
message: formData.get('message')
window.addEventListener('load', () => {
const contactForm = document.getElementById('contact-form')
const nameMessage = document.getElementById('name-message')
const emailMessage = document.getElementById('email-message')
const messageMessage = document.getElementById('message-message')
const submitMessage = document.getElementById('submit-message')
const nameInput = document.getElementById('name-input')
const emailInput = document.getElementById('email-input')
const messageInput = document.getElementById('message-input')
const submitInput = this.document.getElementById('submit-input')
const validateName = () => {
if (nameInput.validity.valid) {
nameMessage.innerHTML = '&nbsp;'
nameInput.classList.remove('invalid')
} else {
nameMessage.innerText = 'Name is required.'
nameInput.classList.add('invalid')
}
fetch('https://api.jessebrault.com/contact/jessebrault', {
body: JSON.stringify(toSend),
headers: {
'Content-type': 'application/json'
},
method: 'POST' // TODO: signal
})
.then(function (response) {
if (response.status === 400) {
response.json().then(function (body) {
body.errors.forEach(function ({ field, message }) {
const element = document.getElementById(`${field}-message`)
element.innerText = message
})
})
} else if (response.status === 500) {
const submitMessageElement = document.getElementById('submit-message')
submitMessageElement.innerText = 'There was internal server error. Please try again later.'
} else {
const submitMessageElement = document.getElementById('submit-message')
submitMessageElement.innerText = 'Your message was successfully sent!'
}
submitMessage.innerHTML = '&nbsp;'
}
nameInput.addEventListener('focusout', validateName)
nameInput.addEventListener('input', validateName)
const validateEmail = () => {
if (emailInput.validity.valid) {
emailMessage.innerHTML = '&nbsp;'
emailInput.classList.remove('invalid')
} else if (emailInput.validity.valueMissing) {
emailMessage.innerText = 'Email is required.'
emailInput.classList.add('invalid')
} else if (emailInput.validity.typeMismatch) {
emailMessage.innerText = 'Email must be a valid email.'
emailInput.classList.add('invalid')
}
submitMessage.innerHTML = '&nbsp;'
}
emailInput.addEventListener('focusout', validateEmail)
emailInput.addEventListener('input', validateEmail)
const validateMessage = () => {
if (messageInput.validity.valid) {
messageMessage.innerHTML = '&nbsp;'
messageInput.classList.remove('invalid')
} else {
messageMessage.innerText = 'Message is required.'
messageInput.classList.add('invalid')
}
submitMessage.innerHTML = '&nbsp;'
}
messageInput.addEventListener('focusout', validateMessage)
messageInput.addEventListener('input', validateMessage)
contactForm.addEventListener('submit', submitEvent => {
submitEvent.preventDefault()
validateName()
validateEmail()
validateMessage()
if (nameInput.validity.valid && emailInput.validity.valid && messageInput.validity.valid) {
const formData = new FormData(contactForm)
const toSend = {
name: formData.get('name'),
email: formData.get('email'),
institution: formData.get('institution'),
message: formData.get('message')
}
submitInput.disabled = true
submitMessage.innerText = 'Sending...'
fetch('https://api.jessebrault.com/contact/jessebrault', {
body: JSON.stringify(toSend),
headers: {
'Content-type': 'application/json'
},
method: 'POST'
})
.catch(function (error) {})
.then(function (response) {
if (response.status === 400) {
response.json().then(body => {
body.errors.forEach(({ field, message }) => {
const element = document.getElementById(`${field}-message`)
element.innerText = message
})
})
} else if (response.status === 500) {
submitMessage.classList.add('error')
submitMessage.innerText = 'There was internal server error. Please try again later.'
} else {
submitMessage.classList.remove('error')
submitMessage.innerText = 'Your message was successfully sent!'
setTimeout(() => {
submitMessage.innerHTML = '&nbsp;'
}, 5000)
}
submitInput.disabled = false
})
.catch(error => {})
}
})
})

View File

@ -416,10 +416,19 @@ form.contact {
cursor: pointer;
}
.contact .control input.invalid,
.contact .control textarea.invalid {
border: 1px solid red;
}
.contact .control .message {
margin: 0;
}
.contact .control .error {
color: red;
}
@media screen and (max-width: 767px) {
nav ul {
position: absolute;