Reputation: 533
I have several buttons on one form. I have a few buttons that toggle different fields of the form, but when I click on the button it submits the form instead, not letting anyone type in the form field (it pops up for just a second and then submits the form). If you could get the toggle to open, it would have both an add and delete button that have their own functions (Not sure if they work since I can't get to them). Each of my buttons have their own onClick function, which I assigned to each button, then I have an overall button that's assigned to submit the form. I will share part of my code, as if I can get one button to function correctly, I should be able to apply it to the others. I am using React and was styling with styled components which is why the tags may look weird.
export default function UserEdit(props) {
const [info, setInfo] = useState({
country: "",
daysAvailable: "",
timeAvailable: "",
});
const [expandCountry, setExpandCountry] = useState(false);
const [expandDay, setExpandDay] = useState(false);
const [expandTime, setExpandTime] = useState(false);
const { push } = useHistory();
const id = window.localStorage.getItem("id");
const changeHandler = (e) => {
setInfo({
...info,
[e.target.name]: e.target.value,
});
};
const handleSubmit = (e) => {
e.preventDefault();
axiosWithAuth()
.put(
`https://school-in-the-cloud-be.herokuapp.com/api/auth/users/${id}`,
info
)
.then((res) => {
setInfo(res.data);
console.log(res.data);
push("/volunteerDash");
})
.catch((err) => console.log(err));
};
const submitDay = (e) => {
e.preventDefault();
props.addDay(info);
setInfo({ daysAvailable: "" });
};
const submitTime = (e) => {
e.preventDefault();
props.addTime(info);
setInfo({ timeAvailable: "" });
};
const submitCountry = (e) => {
e.preventDefault();
props.addCountry(info);
setInfo({ country: "" });
};
return (
<>
<Container>
<div className="title">
<h1>Edit Profile</h1>
</div>
<Cards>
<Forms onSubmit={handleSubmit}>
<Sections>
<h4>Country: </h4>
{expandCountry && (
<FormContainer>
<Label>Country</Label>
<Input
type="text"
name="country"
placeholder="Enter your Country"
value={info.country}
onChange={changeHandler}
/>
<CancelAdd>
<AddButton onClick={submitCountry}>Add</AddButton>
<CancelButton onClick={() => setExpandCountry(false)}>
Cancel
</CancelButton>
</CancelAdd>
</FormContainer>
)}
<p>Stuff</p>
<AddCountry addNewCountry={props.addNewCountry} />
<Button onClick={() => setExpandCountry(true)}>Edit Country</Button>
</Sections>
<Sections>
<h4>Day(s) Available: </h4>
{expandDay && (
<FormContainer>
<Label>Days Available: </Label>
<Select
name="daysAvailable"
value={info.daysAvailable}
onChange={changeHandler}
>
<option value="" disabled={true}>
Select day of Week
</option>
<option value="Monday">Monday</option>
<option value="Tuesday">Tuesday</option>
<option value="Wednesday">Wednesday</option>
<option value="Thursday">Thursday</option>
<option value="Friday">Friday</option>
</Select>
<CancelAdd1>
<AddButton onClick={submitDay}>Add</AddButton>
<CancelButton onClick={() => setExpandDay(false)}>
Cancel
</CancelButton>
</CancelAdd1>
</FormContainer>
)}
<DayList addNewDay={props.addNewDay} />
<Button onClick={() => setExpandDay(true)}>Change Day</Button>
</Sections>
Upvotes: 1
Views: 59
Reputation: 202836
Buttons by default have a type of "submit" if not specified otherwise.
If your buttons are not for submitting form data to a server, be sure to set their
type
attribute tobutton
. Otherwise they will try to submit form data and to load the (nonexistent) response, possibly destroying the current state of the document.
You need to specify type="button"
for all your buttons.
<AddButton
onClick={submitCountry}
type="button"
>
Add
</AddButton>
<CancelButton
onClick={() => setExpandCountry(false)}
type="button"
>
Cancel
</CancelButton>
If using styled-components you can do this as a default for all your buttons using attrs
const NonSubmitButton = styled.button.attrs(() => ({
type: 'button',
}))`
// button styles...
`;
Upvotes: 1