Search code examples
javascriptreactjsjsxstyled-components

Several Buttons on one Form


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>


Solution

  • Buttons by default have a type of "submit" if not specified otherwise.

    Button Notes

    If your buttons are not for submitting form data to a server, be sure to set their type attribute to button. 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...
    `;