Reputation: 2896
I have an input that's styled with styled components
. It has a min
and max
number, and it's passed down as props to give a red border:
export const StyledInput = styled.input`
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
display: block;
outline: none;
font-size: 16px;
font-weight: 500;
-webkit-appearance: none;
border: 1px solid #e6e6e6;
border-radius: 5px;
background-color: #fff;
border: ${(props) => (props.option === true ? '0px' : '')};
line-height: 30px;
/* vertical-align: middle; */
z-index: 1;
height: 33px;
width: ${(props) => (props.numberInputWidth)};
padding: 0 8px;
margin-left: 5px;
margin-top: 20px;
transition: border-color 0.3s ease-in-out;
&:focus {
border-color: ${COLORS.LIGHTGREEN};
transition: border-color 0.3s ease-in-out;
${({ error }) => error && `
border-color: ${COLORS.ERROR};
`}
}
`
And my component's state:
this.state = {
inputTouched: false,
inputValue: 0,
}
and the error handling prop:
error={!!(inputValue > max || inputValue < min)}
So let's say min = 1
and max = 100
. It's working as intended:
So, when this.state.inputValue
is over the min/max, it'll produce a red border indicating an error. However, upon rendering the page, the input is set at 0
, and clicking into it will give a red border.
I want it to be green initially, and then let the error logic handle it.
I want it to look like this:
but only on initial click
Is there anyway to do so?
Upvotes: 2
Views: 3045
Reputation: 545
Effectively, you only want to apply your error-checking / css styles AFTER the form has been focused by the user.
The cases you want to handle are:
I don't think the UX is very good if the input is initially green, while showing 0. I would personally leave it white, and only show it being green AFTER a valid value has been put in, but that is up to you.
In your state:
this.state = {
inputTouched: false,
inputValue: 0,
inputWasFocused: false
}
Your error handling should be updated to check for errors only AFTER the input has been focused by the user.
if(inputWasFocused) {
error={!!(inputValue > max || inputValue < min)}
}
Alternative logic can be implemented to simply allow your default value of 0 to be an acceptable input, until the input has been focused - however I think the above is fairly clear as well.
Then, the only thing you have to do is set the state of inputWasFocused to be true, after the user un-focuses the input.
Add a handler to the class which has your input field/input component:
seatInputBlurHandler = () => {
this.setState({inputWasFocused: true})
}
And pass the handler to your input field, to be executed onBlur To do so, add the following event to your input field JSX:
<input type="text" onBlur={() => this.seatInputBlurHandler()}>
So after all of that: When the page is loaded, inputWasFocused is false, and the error checking does not apply. When the user selects the input, nothing happens until they leave - and when they do, onBlur is triggered, and the seatInputBlurHandler is executed, resulting in inputWasFocused being set to true, and thus the error checking logic will run, and the field should be styled appropriately after.
If you need help with the JSX syntax, please post the JSX code where you render the input field.
Upvotes: 1