I have a form where I want to know if the input values are empty when onSubmit, they are not sent. I have tried to do it through the if of handleInputChange but this isn't working:
const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
if ((e.target as HTMLInputElement).value) {
setNewPost({
...newPost,
[(e.target as HTMLInputElement).name]: (e.target as HTMLInputElement).value
})
}
e.preventDefault();
};
All the code:
const New: React.FC = () => {
// const [newPost, setNewPost] = useState("");
const [newPost, setNewPost] = useState({
title: '',
author: '',
content: ''
})
const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
if ((e.target as HTMLInputElement).value) {
setNewPost({
...newPost,
[(e.target as HTMLInputElement).name]: (e.target as HTMLInputElement).value
})
}
e.preventDefault();
};
const createPost = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); //Detiene el formulario para que no actualize la página
setPost(newPost)
}
return (
<div className="containerHomepage">
<form className="formulari" onSubmit={createPost}>
<div className="containerBreadCrumb">
<ul className="breadCrumb">
<li>Posts</li>
</ul>
</div>
<div className="containerTitleButton">
<input
className=""
type="text"
placeholder='Post title'
name="title"
onChange={handleInputChange}
></input>
<button
className="button"
type="submit"
>Save</button>
</div>
<div className="containerEdit">
<input
className=""
type="text"
placeholder='Author'
name="author"
onChange={handleInputChange}
></input>
<input
className=""
type="text"
placeholder='Content'
name="content"
onChange={handleInputChange}
></input>
</div>
</form>
</div>
);
};
// ========================================
export default New;
CodePudding user response:
Your current handleInputChange
makes it so that the user cannot change any input to an empty string. There's a major usability flaw here. Once the user types the first character, they cannot delete it! You should allow the inputs to be empty, but disallow submitting the form unless all fields are filled out.
You can use e.currentTarget
instead of e.target
to avoid a lot of type assertions. There is more information in this question, but what's important here is that e.currentTarget
will always be the HTMLInputElement
.
const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
setNewPost({
...newPost,
[e.currentTarget.name]: e.currentTarget.value
});
};
@rax's answer is on the right track, but I'm going to go further down that path.
An any point in time, you can know whether the form is valid or not by looking at the current state of newPost
. There are lots of ways to write this, which all do the same thing:
const isValid = Boolean(newPost.title && newPost.author && newPost.content);
Using type coercion. All strings are truthy except for the empty string.
const isValid = newPost.title !== '' && newPost.author !== '' && newPost.content !== '';
From @Vladimir Trotsenko's answer.
const isValid = Object.values(newPost).every(value => value.length > 0)
Looping over all values of newPost
so you don't need to change anything if you add an extra field.
You can use this isValid
variable to conditionally disable the "Save" button.
<button type="submit" disabled={!isValid}>Save</button>
You can also use isValid
to show messages or other visible feedback to the user. For example, you can show a message when hovering over the disabled button which tells them why it has been disabled.
<button
type="submit"
disabled={!isValid}
title={isValid ? "Create your post" : "All fields must be filled out."}
>
Save
</button>
I'm checking if (isValid)
in the createPost
function to be on the safe side, but I believe that this is not actually necessary as the form won't be submitted (even when hitting Enter) if the submit button is disabled.
const createPost = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); // stop the form from reloading the page.
if (isValid) {
// put your actual code here instead.
alert("submit success");
}
};
Complete code:
import React, { useState } from "react";
const New: React.FC = () => {
const initialState = {
title: "",
author: "",
content: ""
};
const [newPost, setNewPost] = useState(initialState);
const isValid = Boolean(newPost.title && newPost.author && newPost.content);
const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
setNewPost({
...newPost,
[e.currentTarget.name]: e.currentTarget.value
});
};
const createPost = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); //stop the form from reloading the page
if (isValid) {
alert("submit success");
}
};
return (
<div className="containerHomepage">
<form className="formulari" onSubmit={createPost}>
<div className="containerBreadCrumb">
<ul className="breadCrumb">
<li>Posts</li>
</ul>
</div>
<div className="containerTitleButton">
<input
className=""
type="text"
placeholder="Post title"
name="title"
onChange={handleInputChange}
value={newPost.title}
/>
<button
className="button"
type="submit"
disabled={!isValid}
title={
isValid ? "Create your post" : "All fields must be filled out."
}
>
Save
</button>
</div>
<div className="containerEdit">
<input
className=""
type="text"
placeholder="Author"
name="author"
onChange={handleInputChange}
value={newPost.author}
/>
<input
className=""
type="text"
placeholder="Content"
name="content"
onChange={handleInputChange}
value={newPost.content}
/>
</div>
</form>
</div>
);
};
export default New;
CodePudding user response:
You can compare your input value to empty string like that :
inputValue === ''
or the size of the string :
inputValue.length === 0
And check the value in if statement with inside your submit.
CodePudding user response:
const createPost = (e) => {
e.preventDefault()
if (newPost.title !== '' && newPost.author !== '' && newPost.content !== '') {
// make api request
} else {
// handle empty fields
}
}
CodePudding user response:
You can validate the empty field inside createPost
which should look something like:
const createPost = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); //stop the form from reloading the page
if (!newPost.title || !newPost.author || !newPost.content) {
//show some error message
} else {
//perform further action
setPost(newPost);
}
}
For a full working example click here.