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"> <article class="contact">
<h1>Contact</h1> <h1>Contact</h1>
<p>Please use the following form to contact Jesse Brault directly.</p> <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"> <div class="control">
<label for="name">Name</label> <label for="name-input">Name</label>
<input id="name" name="name" type="text" /> <input id="name-input" name="name" type="text" required />
<p id="name-message" class="message">&nbsp;</p> <p id="name-message" class="message error">&nbsp;</p>
</div> </div>
<div class="control"> <div class="control">
<label for="institution">Institution</label> <label for="institution-input">Institution</label>
<input id="institution" name="institution" type="text" /> <input id="institution-input" name="institution" type="text" />
<p id="institution-message" class="message">&nbsp;</p> <p id="institution-message" class="message error">&nbsp;</p>
</div> </div>
<div class="control"> <div class="control">
<label for="email">Email</label> <label for="email-input">Email</label>
<input id="email" name="email" type="email" /> <input id="email-input" name="email" type="email" required />
<p id="email-message" class="message">&nbsp;</p> <p id="email-message" class="message error">&nbsp;</p>
</div> </div>
<div class="control"> <div class="control">
<label for="message">Message</label> <label for="message-input">Message</label>
<textarea id="message" name="message"></textarea> <textarea id="message-input" name="message" required></textarea>
<p id="message-message" class="message">&nbsp;</p> <p id="message-message" class="message error">&nbsp;</p>
</div> </div>
<div class="control"> <div class="control">
<input type="submit" /> <input id="submit-input" type="submit" />
<p id="submit-message" class="message">&nbsp;</p> <p id="submit-message" class="message">&nbsp;</p>
</div> </div>
</form> </form>

View File

@ -1,7 +1,67 @@
window.addEventListener('load', function () { window.addEventListener('load', () => {
const contactForm = document.querySelector('form.contact') const contactForm = document.getElementById('contact-form')
contactForm.addEventListener('submit', function (submitEvent) {
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')
}
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() submitEvent.preventDefault()
validateName()
validateEmail()
validateMessage()
if (nameInput.validity.valid && emailInput.validity.valid && messageInput.validity.valid) {
const formData = new FormData(contactForm) const formData = new FormData(contactForm)
const toSend = { const toSend = {
name: formData.get('name'), name: formData.get('name'),
@ -9,29 +69,36 @@ window.addEventListener('load', function () {
institution: formData.get('institution'), institution: formData.get('institution'),
message: formData.get('message') message: formData.get('message')
} }
submitInput.disabled = true
submitMessage.innerText = 'Sending...'
fetch('https://api.jessebrault.com/contact/jessebrault', { fetch('https://api.jessebrault.com/contact/jessebrault', {
body: JSON.stringify(toSend), body: JSON.stringify(toSend),
headers: { headers: {
'Content-type': 'application/json' 'Content-type': 'application/json'
}, },
method: 'POST' // TODO: signal method: 'POST'
}) })
.then(function (response) { .then(function (response) {
if (response.status === 400) { if (response.status === 400) {
response.json().then(function (body) { response.json().then(body => {
body.errors.forEach(function ({ field, message }) { body.errors.forEach(({ field, message }) => {
const element = document.getElementById(`${field}-message`) const element = document.getElementById(`${field}-message`)
element.innerText = message element.innerText = message
}) })
}) })
} else if (response.status === 500) { } else if (response.status === 500) {
const submitMessageElement = document.getElementById('submit-message') submitMessage.classList.add('error')
submitMessageElement.innerText = 'There was internal server error. Please try again later.' submitMessage.innerText = 'There was internal server error. Please try again later.'
} else { } else {
const submitMessageElement = document.getElementById('submit-message') submitMessage.classList.remove('error')
submitMessageElement.innerText = 'Your message was successfully sent!' submitMessage.innerText = 'Your message was successfully sent!'
setTimeout(() => {
submitMessage.innerHTML = '&nbsp;'
}, 5000)
}
submitInput.disabled = false
})
.catch(error => {})
} }
}) })
.catch(function (error) {})
})
}) })

View File

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