skip to Main Content

I am making a form with Material UI in React to send data to MongoDB. What happens is that in my form I have elements like DatePickers, Select, TextField, all from Material UI.

So I have the following code to make the change of the states:

const [project, setProject] = useState({
    project_start: null,
    project_end: null,
    project_name: "",
    usersId: [],
    partnerId: "",
    categoryId: "",
  });

  const handleChange = (name, newVal) => {
    setProject({ ...project, [name]: newVal });
  };

And this would be a summary of what my form consists of:

<form onSubmit={handleSubmit}>
<Box width="50%">
                <LocalizationProvider dateAdapter={AdapterDayjs}>
                  <DatePicker
                    id="project_start"
                    name="project_start"
                    value={project.project_start}
                    onChange={handleChange.bind(null, "project_start")}
                    slotProps={{
                      textField: {
                        size: "small",
                        margin: "dense",
                      },
                    }}
                  />
                </LocalizationProvider>
                <TextField
                  id="nombreP"
                  name="project_name"
                  value={project.project_name}
                  onChange={handleChange}
                  margin="dense"
                  size="small"
                />
                <FormControl size="small" sx={{ m: 1 }}>
                  <Select
                    id="encargadoP"
                    multiple
                    name="usersId"
                    value={project.usersId}
                    onChange={(e) =>
                      handleChange(
                        "usersId",
                        typeof e.target.value === "string"
                          ? e.target.value.split(",")
                          : e.target.value
                      )
                    }
                    MenuProps={MenuProps}
                    renderValue={(selected) => (
                      <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
                        {selected.map((value) => (
                          <Chip key={value} label={value} />
                        ))}
                      </Box>
                    )}
                    sx={{ width: 205 }}
                  >
                    {data?.map(({ _id, name }) => (
                      <MenuItem key={_id} value={name}>
                        {name}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
              </Box>
            </Box>
            <Button
              type="submit"
              variant={"outlined"}
              size={"large"}
              sx={{
                width: 420,
                border: "1px solid white",
                m: "3rem 0 0 0",
                color: "white",
                borderRadius: "30px",
              }}
            >
              Agregar proyecto
            </Button>
          </Box>
        </form>

At the moment the onChange of the TextField does not work, when I write something it does not appear. So I would like to ask, how could I change it?

I am very grateful to people who can help me 🙂

2

Answers


  1. According to the documentation, your handleChange isn’t what TextField expects onChange to look like. It expects your function to accept the usual single parameter, an event object, and then get the field name and value from that. For example:

    const handleChange = (event) => {
        const { name, value } = event.currentTarget;
        setProject({ ...project, [name]: value });
    };
    

    In a comment you’ve said:

    I had it that way before, but this way the DatePicker stops working

    The DatePicker onChange is different, so you can’t use one function for both.

    You might have one function that makes the change, and have each onChange call that function though.

    const handleChange = (name, value) => {
        setProject({ ...project, [name]: value });
    };
    const handleTextChange = ({currentTarget: { name, value }}) =>
        handleChange(name, value);
    const handleDatePickerChange = handleChange.bind("project_start");
    // ...
    
    Login or Signup to reply.
  2. Your solution, if you combine TJ Crowder’s answer with the code you already have, is given in your Select component:

                      <Select
                        id="encargadoP"
                        multiple
                        name="usersId"
                        value={project.usersId}
                        onChange={(e) =>
                          handleChange(
                            "usersId",
                            typeof e.target.value === "string"
                              ? e.target.value.split(",")
                              : e.target.value
                          )
                        }
    

    You can do largely the same thing in your TextField component:

                 <TextField
                      id="nombreP"
                      name="project_name"
                      value={project.project_name}
                      onChange={(e) =>
                          handleChange(
                            "project_name",
                            e.target.value
                          )
                        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search