Search code examples
javascriptreactjsevent-handling

React handleChange fuction store one input field as number - everything else as string in array


I fairly new to React and JS. I am building an account form as part of a larger form. Users can dynamically add as many "account inputs" as they need to populate. I can currently capture the state of these forms in an array. However all three properties are stored as type string - for balance, I need to store this as a number. I know I can use parseFloat() to make this happen. But I cant quite work it out?

How can I update my existing handleInputChange function to check if the name is balance, and if so... parseFloat(value)?

Everything else is working fine in this form, but my balance data is being stored as a string in my db.

Also open to advice if there is a better function to convert to a number

Code below:

import IconButton from "@mui/material/IconButton";
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline";
import Box from "@mui/material/Box";
import { TextField, Typography } from "@mui/material";

function AccountsForm({ accountInputList, setAccountInputList }) {
  // handle input change
  const handleInputChange = (e, index) => {
    const { name, value } = e.target;
    const list = [...accountInputList];
    list[index][name] = value;
    setAccountInputList(list);
    console.log(accountInputList);
  };

  // handle click event of the Remove button
  const handleRemoveClick = (index) => {
    const list = [...accountInputList];
    list.splice(index, 1);
    setAccountInputList(list);
  };

  // handle click event of the Add button
  const handleAddClick = () => {
    setAccountInputList([
      ...accountInputList,
      { balance: "", name: "", type: "" },
    ]);
  };

  return (
    <Box marginTop={1}>
      <Typography id="modal-modal-enddate" sx={{ mt: 2, mb: 1 }}>
        Add Account
      </Typography>
      {accountInputList.map((x, i) => {
        return (
          <Box key={i} marginTop={1}>
            <TextField
              sx={{ width: "12ch" }}
              name="balance"
              label="Balance"
              value={x.balance}
              onChange={(e) => handleInputChange(e, i)}
            />
            <TextField
              sx={{ width: "12ch" }}
              name="name"
              label="Name"
              value={x.name}
              onChange={(e) => handleInputChange(e, i)}
            />
            <TextField
              sx={{ width: "12ch" }}
              name="type"
              label="Description"
              value={x.type}
              onChange={(e) => handleInputChange(e, i)}
            />
            {accountInputList.length !== 1 && (
              <IconButton onClick={() => handleRemoveClick(i)}>
                <RemoveCircleOutlineIcon />
              </IconButton>
            )}
            {accountInputList.length - 1 === i && (
              <IconButton onClick={handleAddClick}>
                <AddCircleOutlineIcon />
              </IconButton>
            )}
          </Box>
        );
      })}
    </Box>
  );
}

export default AccountsForm;

Inside handleInputChange ive tried a variety of if statements and switch statements, but nothing seems to work. I need my form state stored as an array of accounts.


Solution

  • Just check the input's name:

    list[index][name] = name === 'balance' ? +value : value;