Why setCustomValidity()
doesn't work in React? Am I missing something? With vanillia HTML and JS works fine. Or there is other way to easily make something similiar to setCustomValidity
?
React code:
class Form extends React.Component {
formVal(e) {
e.target.setCustomValidity("Test_1");
}
formVal2() {
let inpt = document.getElementById("input");
inpt.target.setCustomValidity("TEST_2");
}
render() {
return (
<div>
<form>
<input
id="input"
type="datetime-local"
onBlur={this.formVal}
/>
</form>
<button onClick={this.formVal2}>Click </button>
</div>
);
}
}
CodePen - React
With no React:
<form>
<input type="email" id="mail" name="mail">
<button onclick="test()">Submit</button>
</form>
// JS
var input = document.getElementById("mail");
function test() {
input.setCustomValidity("test")
}
CodePen - no React
setCustomValidity
doesn't immediately trigger validation, you have to have a form submit event to trigger it or call checkValidity
. I've updated your CodePen to show how you can achieve this in React, and it is also included below.
class Form extends React.Component {
onChange(e) {
let date = new Date(Date.parse(e.target.value));
if (date > new Date()) {
e.target.setCustomValidity("Please select a date in the past.");
} else {
e.target.setCustomValidity("");
}
}
render() {
return (
<div>
<form>
<input
id="input"
type="datetime-local"
onChange={this.onChange}
/>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
ReactDOM.render(<Form />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Hello here is how you need to do it.
import * as React from "react";
export default function Form () {
const nameInput = React.useRef<HTMLInputElement>(null);
const [nameVal,setNameVal] = React.useState("");
const onSubmitHandler = (e: React.FormEvent<HTMLFormElement>) => {
// handle yow submition
}
const onNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!nameInput.current) return;
setNameVal(e.currentTarget.value);
const {validity} = nameInput.current;
if (validity.badInput) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.customError) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.patternMismatch) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.rangeOverflow) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.rangeUnderflow) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.stepMismatch) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.tooLong) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.tooShort) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.typeMismatch) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.valid) {
nameInput.current.setCustomValidity("Set the message to show");
}
if (validity.valueMissing) {
nameInput.current.setCustomValidity("Set the message to show");
}
}
return (
<form onSubmit={onSubmitHandler}>
<label htmlFor="id-name">Name</label>
<input
id="id-name"
ref={nameInput}
type="text"
required
min={5}
max={15}
value={nameVal}
onChange={onNameChange}
/>
<button type="submit">submit</button>
</form>
)
}
I mean you dont have to add all of them, just the ones you care about
In case you want to show validation for required fields that are left empty you should set setCustomValidity on onInvalid like this:
<input onInvalid={e => e.target.setCustomValidity('Your custom message')} />
And if you are using typescript like this:
<input onInvalid={e => (e.target as HTMLInputElement).setCustomValidity('Enter User Name Here')} />
In case you are want to handle validation for values you can add it like here: https://stackoverflow.com/a/45695707/6912349
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With