Alterar campos no modal

Tenho esta página principal

import { Button, ButtonBase, Grid, Typography } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import React, { useEffect, useState } from "react";
import PropertyIcon from "~/assets/images/property-icon.svg";
import Shape from "~/assets/images/shape.svg";
import ConfirmationDialog from "~/components/ConfirmationDialog";
import LoggedAreaNavbar from "~/components/LoggedAreaNavbar";
import { fetchAllProperties } from "~/services/property";
import { getCurrentUser } from "~/services/user";
import NewPropertyDialog from "./NewPropertyDialog";
const useStyles = makeStyles((theme) => ({
  container: {
    textAlign: "center",
    padding: "0 120px",
  },
  gridWrapper: {
    padding: "100px 0",
  },
  title: {
    fontSize: "26px",
    color: "#000",
    fontWeight: 500,
    marginTop: "100px",
  },
  information: {
    fontSize: "16px",
    color: "#000",
    letterSpacing: "0.34px",
  },
  homeIcon: {
    margin: "100px auto",
  },
  button: {
    borderRadius: "24px",
    display: "block",
    margin: "0 auto 30px",
    minHeight: "50px",
    minWidth: "380px",
    textTransform: "capitalize",
    fontSize: "18px",
  },
  image: {
    width: 128,
    height: 128,
  },
  img: {
    margin: "auto",
    display: "block",
    maxWidth: "100%",
    maxHeight: "100%",
  },
  itemContent: {
    marginLeft: "30px",
  },
  propertyName: {
    fontSize: "18px",
    color: "#000",
    fontWeight: 500,
    textAlign: "left",
  },
  address: {
    fontSize: "14px",
    color: "#8e8e8e",
    textAlign: "left",
    maxWidth: "204px",
  },
}));
function Properties(props) {
  const classes = useStyles();
  const [properties, setProperties] = useState([]);
  const [user, setUser] = useState([]);
  useEffect(() => {
    fetchPropertiesData();
  }, []);
  const fetchPropertiesData = () => {
    getCurrentUser().then((userData) => {
      const userID = userData.data.data.id;
      setUser(userID);
      fetchAllProperties(userID).then((response) => {
        const properties = response.data.data;
        setProperties(properties);
      });
    });
  };
  // Register dialog
  const [open, setOpen] = useState(false);
  const registerNewProperty = () => {
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false);
  };
  // Confirmation dialog
  const [openConfirmation, setOpenConfirmation] = useState(false);
  const openConfirmationDialog = () => {
    setOpen(false);
    setOpenConfirmation(true);
  };
  const closeConfirmationDialog = () => {
    setOpenConfirmation(false);
    window.location.reload(); 
  };

const onEdit = (item) => {
    setOpen(true);
    setItem(item);
 }

  return (
    <>
      <LoggedAreaNavbar {...props} />
      <div className={classes.container}>
        <Typography className={classes.title}>Minhas propriedades</Typography>
        <Typography className={classes.information}>
          Você tem {properties.length} propriedades cadastradas
        </Typography>
        {properties.length === 0 && (
          <img className={classes.homeIcon} alt="Propriedade" src={Shape} />
        )}
        {properties.length > 0 && (
          <Grid container spacing={2} className={classes.gridWrapper}>
            {properties.map((item, index) => (
              <Grid container item sm={12} md={4} lg={4} key={index}>
                <Grid item md={3} lg={3}>
                  <ButtonBase className={classes.image} onClick={() => onEdit(item)}>
                    <img
                      className={classes.img}
                      alt="Propriedade"
                      src={PropertyIcon}
                    />
                  </ButtonBase>
                </Grid>
                <Grid
                  item
                  md={9}
                  lg={9}
                  alignItems="flex-start"
                  direction="column"
                  justify="center"
                  container
                >
                  <Grid className={classes.itemContent}>
                    <Typography className={classes.propertyName}>
                      {item.attributes.name}
                    </Typography>
                    <Typography className={classes.address}>
                      {item.attributes.address}
                    </Typography>
                  </Grid>
                </Grid>
              </Grid>
            ))}
          </Grid>
        )}
        <Button
          variant="contained"
          color="primary"
          className={classes.button}
          onClick={registerNewProperty}
        >
          Cadastrar nova propriedade
        </Button>
      </div>
      <NewPropertyDialog
        open={open}
        handleClose={handleClose}
        openConfirmationDialog={openConfirmationDialog}
        user={user}
      />
      <ConfirmationDialog
        open={openConfirmation}
        handleClose={closeConfirmationDialog}
        contentText={"A propriedade foi cadastrada com sucesso!"}
        buttonText={"Ver lista de propriedades"}
        handleClick={closeConfirmationDialog}
      />
    </>
  );
}
export default Properties;

Neste onClick <ButtonBase className={classes.image} onClick={() => onEdit(item)}>, eu chamo um modal. Ele abre corretamente. preenche os campos. Mas não consigo alterar os valores.

O código

import Button from "@material-ui/core/Button";
import Chip from '@material-ui/core/Chip';
import Dialog from "@material-ui/core/Dialog";
import MuiDialogContent from "@material-ui/core/DialogContent";
import MuiDialogTitle from "@material-ui/core/DialogTitle";
import FormControl from "@material-ui/core/FormControl";
import IconButton from "@material-ui/core/IconButton";
import MenuItem from "@material-ui/core/MenuItem";
import Select from "@material-ui/core/Select";
import Snackbar from '@material-ui/core/Snackbar';
import { makeStyles, useTheme } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import CloseIcon from "@material-ui/icons/Close";
import { Alert } from '@material-ui/lab';
import React, { useEffect, useState } from "react";
import Input from "~/components/Input";
import { getBeeDatabases } from "~/services/beedatabases";
import { getPlantDatabase } from "~/services/plantdatabase";
import { getCreatePropertie, getUpdatePropertie } from '~/services/property';
const useStyles = makeStyles((theme) => ({
  root: {
    margin: 0,
    padding: theme.spacing(2),
  },
  content: {
    padding: "0px",
    textAlign: "center",
  },
  closeButton: {
    position: "absolute",
    right: theme.spacing(1),
    top: theme.spacing(1),
    color: "#02482b",
  },
  closeIcon: {
    fill: "#02482b",
    fontSize: "2.5rem",
  },
  title: {
    margin: "100px auto 0",
    fontWeight: "bold",
    fontSize: "26px",
    color: "#02482b",
    maxWidth: "304px",
  },
  text: {
    fontSize: "18px",
    color: "#8e8e8e",
    margin: "50px 0 15px",
  },
  map: {
    backgroundColor: "#CCC",
    width: "100%",
    height: "240px",
  },
  wrapper: {
    padding: "51px 205px 64px",
  },
  formControl: {
    textAlign: "left",
    width: "100%",
  },
  selectLabel: {
    fontSize: "18px",
    color: "#8e8e8e",
    margin: "0px 0 15px",
  },
  selectPlaceholder: {
    fontSize: "18px",
    fontStyle: "inherit",
    color: "#000",
    fontWeight: 500,
    letterSpacing: "0.05px",
  },
  button: {
    borderRadius: "24px",
    margin: "0 auto 30px",
    display: "block",
    minHeight: "50px",
    minWidth: "380px",
    textTransform: "capitalize",
    fontSize: "18px",
  },
  cancel: {
    color: "#02482b",
    cursor: "pointer",
    fontSize: "18px",
    fontWeight: "500",
    marginBottom: "100px",
  },
  chips: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  chip: {
    margin: 2,
  },
}));
export default function NewPropertyDialog(props) {
  const classes = useStyles();
  const { open, handleClose, openConfirmationDialog, user, item } = props;
  const [loading, setLoading] = useState(false);
  const theme = useTheme();
  const [plantSelect, setPlantSelect] = useState([]);
  const [beeSelect, setBeeSelect] = useState([]);
  const [nameError, setNameError] = useState(false);
  const [addressError, setAddressError] = useState(false);
  const [beeError, setBeeError] = useState(false);
  const [plantError, setPlantError] = useState(false);
  const [beeDatabases , setBeeDatabases ] = useState([]);
  const [plantDatabase, setPlantDatabase] = useState([]);
  const MenuProps = {
    PaperProps: {
      style: {
        maxHeight: 48 * 4.5 + 8,
        width: 250,
      },
    },
  };
  const handlePlantsChange = (event) => {
    setPlantSelect(event.target.value);
  };
  const handleBeesChange = (event) => {
    setBeeSelect(event.target.value);
  };
  const onSalvar = async (propriedade) => {
    //setLoading(true);
    const body = {
      kind: document.querySelector('#kind').value,
      address: document.querySelector('#address').value,
      totalPlantedArea: document.querySelector('#total-planted-area').value,
      totalForestArea: document.querySelector('#total-forest-area').value,
      apiariesInUse: document.querySelector('#apiaries-in-use').value,
    };
    const isValid = validateFields(body);
    if(isValid) {
      const plants = [];
      plantSelect.map(plant => {
        const properties = {
          kind: plant
        };
        plants.push(properties);
      });
      const bees = [];
      beeSelect.map(plant => {
        const properties = {
          kind: plant
        };
        bees.push(properties);
      });
      let response = null;
      if(item !== undefined && item !== undefined) {
        response = await getUpdatePropertie(user, body, plants, bees, item.id);
      } else {
        response = await getCreatePropertie(user, body, plants, bees);
      }
      if (response) {
        openConfirmationDialog();
        //setOpen(true);
      } else {
        //setAlertOpen(true);
      }
    }
    //setLoading(false);
  }
  const validateFields = (body) => {
    cleanErrors();
    if (body.kind === '') {
      setNameError(true);
      return false;
    }
    if (body.address === '') {
      setAddressError(true);
      return false;
    }
    if (plantSelect === undefined || plantSelect.length === 0) {
      setPlantError(true);
      return false;
    }
    if (beeSelect === undefined || beeSelect.length === 0) {
      setBeeError(true);
      return false;
    }
    return true;
  }
  const cleanErrors = () => {
    setNameError(false);
    setAddressError(false);
    setBeeError(false);
    setPlantError(false);
  };
  useEffect(() => {
    fetchPlantDatabase();
    fetchBeeDatabases();
  }, []);
  const fetchPlantDatabase = () => {
    const plants = [];
    getPlantDatabase().then((response) => {
      response.data.data.map(plant => (
        plants.push(plant.attributes)
      ))
    })
    setPlantDatabase(plants);
  }
  const fetchBeeDatabases = () => {
    const bees = [];
    getBeeDatabases().then((response) => {
      response.data.data.map(bee => (
        bees.push(bee.attributes)
      ))
    })
    setBeeDatabases(bees);
  }
  const getStyles = (name, personName, theme) => {
    return {
      fontWeight:
        personName.indexOf(name) === -1
          ? theme.typography.fontWeightRegular
          : theme.typography.fontWeightMedium,
    };
  }
  return (
    <div>
      <Dialog
        onClose={handleClose}
        aria-labelledby="customized-dialog-title"
        open={open}
        fullWidth={true}
        maxWidth={"md"}
      >
        <MuiDialogTitle disableTypography className={classes.root}>
          <IconButton
            aria-label="close"
            className={classes.closeButton}
            onClick={handleClose}
          >
            <CloseIcon className={classes.closeIcon} />
          </IconButton>
        </MuiDialogTitle>
        <MuiDialogContent className={classes.content}>
          <Typography gutterBottom className={classes.title}>
            Nova propriedade
          </Typography>
          <Typography gutterBottom className={classes.text}>
            Qual é o endereço desta propriedade?
          </Typography>
          {
          //Aonde aparacerá o mapa
          //<div id="map" className={classes.map}></div>
          }
          <div className={classes.wrapper}>
            <Input
              id="kind"
              label="Nome da propriedade"
              value={item?.attributes?.name}
            />
            <Input id="address"
              label="Endereço"
              value={item?.attributes?.address}
            />
            <Input
              id="total-planted-area"
              label="Area total plantada"
              value={item?.attributes?.['total-planted-area']}
            />
            <Input
              id="total-forest-area"
              label="Area total de mata"
              value={item?.attributes?.['total-forest-area']}
            />
            <Input
              id="apiaries-in-use"
              label="Quantos apiários já estão em uso?"
              value={item?.attributes?.['apiaries-in-use']}
            />
            <FormControl className={classes.formControl}>
              <Typography className={classes.selectLabel}>
                Selecione os tipos de plantas que são cultivadas nesta
                propriedade:
              </Typography>
              <Select
                labelId="typePlant"
                id="typePlant"
                multiple
                displayEmpty
                value={plantSelect}
                onChange={handlePlantsChange}
                renderValue={(selected) => (
                  <div className={classes.chips}>
                    {selected.map((value) => (
                      <Chip key={value} label={value} className={classes.chip} />
                    ))}
                  </div>
                )}
                MenuProps={MenuProps}
              >
                <MenuItem value="">
                  <em className={classes.selectPlaceholder}>
                    Selecionar plantas
                  </em>
                </MenuItem>
                {plantDatabase.map(planta => {
                  return (
                    <MenuItem key={planta['species-name']} value={planta['species-name']} 
                      style={getStyles(planta, plantSelect, theme)}>
                      {planta['species-name']}
                    </MenuItem>
                  )
                })}
              </Select>
            </FormControl>
            <FormControl className={classes.formControl}>
              <Typography className={classes.text}>
                Selecione os tipos de abelhas que você aceita nesta propriedade:
              </Typography>
              <Select
                labelId="typeBee"
                id="typeBee"
                multiple
                displayEmpty
                value={beeSelect}
                onChange={handleBeesChange}
                renderValue={(selected) => (
                  <div className={classes.selectPlaceholder}>
                    {selected.map((value) => (
                      <Chip key={value} label={value} className={classes.chip} />
                    ))}
                  </div>
                )}
                MenuProps={MenuProps}
              >
                <MenuItem value="">
                  <em className={classes.selectPlaceholder}>
                    Selecionar plantas
                  </em>
                </MenuItem>
                {beeDatabases.map(bee => {
                  return (
                    <MenuItem key={bee['species-name']} value={bee['species-name']} 
                      style={getStyles(bee, beeSelect, theme)}>
                      {bee['species-name']}
                    </MenuItem>
                  )
                })}
              </Select>
            </FormControl>
            <FormControl className={classes.formControl}>
              <Typography className={classes.text}>Shapefiles:</Typography>
              <input
                accept="zip/*"
                className={classes.input}
                id="contained-button-file"
                type="file"
              />
            </FormControl>
          </div>
          <Button
            variant="contained"
            color="primary"
            className={classes.button}
            onClick={onSalvar}
            disabled={loading}
          >
            Cadastrar
          </Button>
          <Typography 
            className={classes.cancel}
            onClick={handleClose}
          >
            Cancelar
          </Typography>
        </MuiDialogContent>
      </Dialog>
     {
        (nameError) ?
        <Snackbar open={nameError} autoHideDuration={6000}>
          <Alert severity="error">
            Nome da propriedade é obrigatório !
          </Alert>
        </Snackbar>
        : ''
      }
      {
        (addressError) ?
        <Snackbar open={addressError} autoHideDuration={6000}>
          <Alert severity="error">
            Endereço da propriedade é obrigatório !
          </Alert>
        </Snackbar>
        : ''
      }
      {
        (beeError) ?
        <Snackbar open={beeError} autoHideDuration={6000}>
          <Alert severity="error">
          Deve serlecionar pelo menos um tipo de abelha !
          </Alert>
        </Snackbar>
        : ''
      }
      {
        (plantError) ?
        <Snackbar open={plantError} autoHideDuration={6000}>
          <Alert severity="error">
            Deve serlecionar pelo menos um tipo de planta !
          </Alert>
        </Snackbar>
        : ''
      }
    </div>
  );
}

Como selecionar os campos typePlant e typeBee com os valores que vem do banco de dados ?

O que pode ser ?

Sei que tem que ter o onChange, mas como não estou o state, como fazer ?

Alguma novidade em relação ?

para conseguir alterar valores do campo voce precisa controlar o estado dele. o campo deve estar sem estado. entao voce nao consegue mudar. o onchange tem que chamar um setState para mudar o valor

SIm concordo.

O que eu fiz e não funcionou.

const [kind, setKind] = useState(item?.attributes?.name);

<Input
    id="kind"
    label="Nome da propriedade"
    value={kind}
/>

Desta maneira ele nem mostrou o valor que está em item?.attributes?.name. E olha que ele tem valor

eh pq voce esta recebendo esse valor de outro componente, voce tem que alterar o estado dele no pai com uma callback

1 curtida

Está parte tem que está no formulário pai ?
const [kind, setKind] = useState(item?.attributes?.name);
e passar pelo props ?

Pode me dar um help ?