I have created an application form with a validation function that requires the user to input the correct information within the boxes before clicking away from that focused box or an error message will show. Problem is when that happens, it affects all of the boxes instead of one that’s being focused on e.g. user does not put in correct email, error message for email, first name and last name etc will show.
Here is my code for my AppForm.jsx:
import React, { useState } from 'react'
import DialingCodes from './DialingCodes'
import FileUpload from './FileUpload'
const AppForm = () => {
const [ focused, setFocused ] = React.useState(false)
const handleFocus = (e) => {
setFocused(true)
}
return (
<>
<div className='app-card'>
<img
src='../../../../logo/Logo ROASTAR-white.PNG'
width={150}
/>
<form className='app-form'>
<h3>Personal Details</h3>
<div className='form-content'>
<div className='first-name'>
<input
type='text'
name='first_name'
placeholder='First Name'
autoComplete='given-name'
pattern='^[A-Za-z]{2,16}$'
onBlur={handleFocus}
{/* This attribute is what activates the function */}
data-focused={focused.toString()}
required
>
</input>
<span>First Name must be at least 2 characters or more</span>
</div>
<div className='last-name'>
<input
type='text'
name='last_name'
placeholder='Last Name'
autoComplete='family-name'
pattern='^[A-Za-z]{2,16}$'
onBlur={handleFocus}
data-focused={focused.toString()}
required
>
</input>
<span>Last Name must be at least 2 characters or more</span>
</div>
...
</div>
...
</form>
</div>
</>
Here is my css code:
.form-content span {
display: none;
}
.form-content input:invalid[data-focused="true"] ~ span {
padding-left: 4.3vw;
text-align: left;
position: relative;
top: 2.7em;
font-size: 12px;
display: block;
color: red;
z-index: 1;
}
Any help will be very much appreciated, thank you.
2
Answers
You currently have a single bool,
focused
, shared by all inputs. That is only enough to represent whether any single field was focused, not which specific ones.You need to track in state which fields were "touched" and then use that information when deciding what value to render in
data-focus
:Just a note on this question, but implementing this kind of form logic yourself is usually "reinventing the wheel a little". Many React form libraries exist to make managing this type of thing easier, like react-hook-form. This particular "onBlur" behaviour with that library is simple, as shown in this example.
If I understand correctly what you want to do, you need to use this selector
.form-content input:invalid:focus-visible + span
.https://developer.mozilla.org/fr/docs/Web/CSS/:focus-visible