Greetings! I have come across this contact form code:
/* Custom Contact Form Styling */
input[type=text],
[type=email],
select,
textarea {
width: 100%;
padding: 12px;
border: 1px solid #555;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
}
input[type=submit] {
background-color: #0563bb;
color: white;
padding: 12px 20px;
border: none;
cursor: pointer;
}
input[type=submit]:hover {
opacity: 0.9;
}
.contactform {
position: relative;
border-radius: 50px;
background-color: #f2f2f2;
padding: 5px;
z-index: 2;
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
margin-top: 1%;
width: 100%;
animation-name: gradient;
animation-duration: 3s;
animation-iteration-count: infinite;
}
.contactform:hover {
animation-name: gradientTwo;
animation-duration: 15s;
animation-iteration-count: infinite;
}
.column {
float: center;
width: 50%;
margin-top: 6px;
padding: 20px;
display: block;
margin-left: auto;
margin-right: auto;
}
.row:after {
content: "";
display: table;
clear: both;
}
@media screen and (max-width: 600px) {
.column,
input[type=submit] {
width: auto;
margin-top: 0;
}
}
@keyframes customAnimation {
10%,
90% {
transform: translateX(-1px);
}
20%,
80% {
transform: translateX(2px);
}
30%,
50%,
70% {
transform: translateX(-4px);
}
40%,
60% {
transform: translateX(4px);
}
}
<section id="contact">
<div class="container" data-aos="fade-up">
<div class="contactform">
<div style="text-align:center">
<div class="section-title">
<h2><br/>Connect With Us</h2>
</div>
<p>Feel free to fill out our contact form!</p>
</div>
<div class="row">
<div class="column">
<form name="myform" action="thankyou.html" method="POST" novalidate>
<label for="firstname">First Name</label>
<input type="text" id="first name" name="firstname" placeholder="Your First Name.." required>
<label for="lastname">Last Name</label>
<input type="text" id="lastname" name="lastname" placeholder="Your Last Name.." required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="Your Email.." required>
<label for="subject">Subject</label>
<textarea id="subject" name="subject" placeholder="Write your message here..." style="height:170px" required></textarea>
<input type="submit" value="Submit">
</form>
</div>
</div>
</div>
</div>
</section>
I am looking to enhance this form by adding animations specifically on the input fields. The goal is to display the input field label above the respective field when clicked, similar to the demonstration in this video.
Desired Outcome
You can view the desired outcome through this video link: Video Link
If you have any recommendations on how I can achieve this effect within the form, please share your thoughts and suggestions.
Below is the code snippet of the contact form showcased in the video:
ContactForm.jsx
:
/ dependencies
import React from 'react'
import { Grid, Typography, TextField, Button, Divider, useMediaQuery } from '@material-ui/core'
import emailjs from 'emailjs-com'
// icons
import { FaGithub, FaLinkedin, FaPhone } from 'react-icons/fa'
import { MdEmail } from 'react-icons/md'
// file imports
import { db } from "../../firebaseConfig";
import ContactStyles from './ContactStyles'
import{ init } from 'emailjs-com';
init(process.env.REACT_APP_USER_ID);
const ContactForm = () => {
// classes and queries
const classes = ContactStyles();
const md = useMediaQuery('(max-width: 960px)');
const lg = useMediaQuery('(min-width: 960px)');
// state declaration
const [name, setName] = React.useState("");
const [email, setEmail] = React.useState("");
const [message, setMessage] = React.useState("");
const [errorName, setErrorName] = React.useState(false);
const [errorEmail, setErrorEmail] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState(false);
// event handler
const submitHandler = (e) => {
e.preventDefault(); // prevent page refresh
// regex pattern for validating email address
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
setErrorName(false);
setErrorEmail(false);
setErrorMessage(false);
// check if any field is invalid to prevent submission
if (name === "" || !emailRegex.test(email) || message === "") {
if (name === "") {
setErrorName(true);
}
if (!emailRegex.test(email)) {
setErrorEmail(true);
}
if (message === "") {
setErrorMessage(true);
}
} else {
const firebaseData = { // data to save to Firebase and send via email
name: name,
email: email,
message: message
}
// save to Firestore
db.collection('contacts').add(firebaseData)
.then(() => {
console.log('Message submitted to Firebase');
})
.catch((err) => {
console.log(err.message);
});
// send via email
emailjs.send(
process.env.REACT_APP_SERVICE_ID,
process.env.REACT_APP_TEMPLATE_ID,
{
name: name,
email: email,
to_name: "",
from_name: "",
message: message,
}
)
.then((response) => {
alert('Message successfully sent!');
console.log(response);
})
.catch((err) => {
console.error(err);
});
setName('');
setEmail('');
setMessage('');
setErrorName(false);
setErrorEmail(false);
setErrorMessage(false);
}
}
return (
<Grid container className={classes.root} id="contact">
{/* Title */}
<Grid className={classes.title} item xs={12}>
<br />
<Typography variant="h2">Contact Me</Typography>
<Typography variant="h4">Let's Connect!</Typography>
</Grid>
{/* Contact Info */}
{lg && <>
<Grid item xs={1}></Grid>
<Grid item xs={10} md={5}>
<br /><br />
<Typography variant="h5"><b>Get in Touch!</b></Typography>
<Divider></Divider>
<br />
<MdEmail />
<Typography display="inline"><b> Email:</b></Typography>
<a rel="noreferrer" target="_blank" className={classes.contact} href="mailto:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a4abafa4a9aca2b1a485aab0b1a9aaaaaeeba6aaa8">[email protected]</a>">
<Typography display="inline"> <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7f1e11151e1316180b1e3f100a0b13101014511c1012">[email protected]</a></Typography>
</a>
<div /><br />
<FaPhone />
<Typography display="inline"><b> Phone:</b></Typography>
<a rel="noreferrer" target="_blank" className={classes.contact} href="647-544-0781">
<Typography className={classes.contact} display="inline"> 647-544-0781</Typography>
</a>
<div /><br />
<FaGithub />
<Typography display="inline"><b> Github:</b></Typography>
<a rel="noreferrer" target="_blank" className={classes.contact} href="https://github.com/anjalig21">
<Typography display="inline"> github.com/AnjaliGupta</Typography>
</a>
<div /><br />
<FaLinkedin />
<Typography display="inline"><b> LinkedIn:</b></Typography>
<a rel="noreferrer" target="_blank" className={classes.contact} href="https://www.linkedin.com/in/anjali-gupta21/">
<Typography display="inline"> linkedin.com/in/AnjaliGupta</Typography>
</a>
<br /><br /><br />
</Grid>
<Grid item xs={1}></Grid>
</>}
{/* Contact Form */}
{md && <Grid item xs={1}></Grid>}
<Grid item xs={10} md={4}>
<div className={classes.formContainer}>
<form onSubmit={submitHandler} className={classes.form}>
<TextField
className={classes.input}
value={name}
onChange={(e) => setName(e.target.value)}
label="Full Name"
variant="outlined"
error={errorName}
helperText={errorName ? "Please provide your full name." : ""}
/>
<br /><br />
<TextField
className={classes.input}
value={email}
onChange={(e) => setEmail(e.target.value)}
label="Email Address"
variant="outlined"
error={errorEmail}
helperText={errorEmail ? "Please enter a valid email." : ""}
/>
<br /><br />
<TextField
className={classes.input}
value={message}
onChange={(e) => setMessage(e.target.value)}
label="Your Message"
multiline
rows={10}
variant="outlined"
error={errorMessage}
helperText={errorMessage ? "Please write a message." : ""}
/>
<br /><br />
<div className={classes.center}>
<Button type="submit" variant="contained" size="large" className={classes.button}>
Send
</Button>
</div>
</form>
</div>
</Grid>
<Grid item xs={1}></Grid>
</Grid>
)
}
export default ContactForm;
ContactStyles.jsx
:
import { makeStyles } from '@material-ui/styles';
const ContactStyles = makeStyles((theme) => ({
root: {
background: theme.palette.primary.dark
},
title: {
textAlign: "center",
color: theme.palette.secondary.dark
},
formContainer: {
height: "78vh",
position: "relative"
},
form: {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-100%, -50%)"
},
input: {
width: "200%",
fontWeight: "600",
'& label.Mui-focused': {
color: theme.palette.secondary.dark,
},
'& .MuiInput-underline:after': {
borderBottomColor: theme.palette.secondary.dark,
},
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: '#0644A3',
},
'&:hover fieldset': {
borderColor: theme.palette.secondary.dark,
},
'&.Mui-focused fieldset': {
borderColor: theme.palette.secondary.dark,
},
},
},
center: {
display: "flex",
justifyContent: "center",
width: "200%"
},
button: {
backgroundColor: "#0644A3",
color: "#FFFFFF",
borderRadius: 20,
marginRight: "2%",
textTransform: "none",
'&:hover': {
transition: "0.3s",
color: "#0644A3",
backgroundColor: "#FFFFFF",
border: "1px solid #0644A3",
}
},
contact: {
textDecoration: "none",
color: "#000000",
'&:hover': {
transition: "0.3s",
color: "#b5befa"
}
},
spacing: {
display: "flex",
alignItems: "center"
}
}))
export default ContactStyles;