javascript - 如何根据所选数据自动填充其他自动完成值,并添加数据(如果尚不存在)?

标签 javascript reactjs material-ui

如何匹配名字和姓氏,然后让它自动填充其他自动完成字段?可能存在多个相似的名字或姓氏但地址不同的情况。另外,如果数据中不存在,请添加名字、姓氏和地址。

到目前为止,我无法匹配名字和姓氏。但是,如果用户不存在,我可以添加并在控制台中查看他们的名字、姓氏和地址。

重新创建的代码和框:https://codesandbox.io/s/freesolocreateoption-demo-material-ui-forked-oclo3s?file=/demo.js

代码:

export default function FreeSoloCreateOption() {
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [streetAddress, setStreetAddress] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(firstName, "firstName");
    console.log(lastName, "firstName");
    console.log(streetAddress, "street address");
  };
  return (
    <form onSubmit={handleSubmit}>
      <Autocomplete
        required
        value={firstName}
        onChange={(event, newValue) => {
          if (typeof newValue === "string") {
            setFirstName(newValue);
          } else if (newValue && newValue.inputValue) {
            // Create a new value from the user input
            setFirstName(newValue.inputValue);
          } else {
            setFirstName(newValue);
          }
        }}
        filterOptions={(options, params) => {
          const filtered = filter(options, params);

          const { inputValue } = params;
          // Suggest the creation of a new value
          const isExisting = options.some(
            (option) => inputValue === option.firstName
          );
          if (inputValue !== "" && !isExisting) {
            filtered.push({
              inputValue,
              firstName: `Add "${inputValue}"`
            });
          }

          return filtered;
        }}
        selectOnFocus
        clearOnBlur
        handleHomeEndKeys
        id="free-solo-with-text-demo"
        options={data}
        getOptionLabel={(option) => {
          // Value selected with enter, right from the input
          if (typeof option === "string") {
            return option;
          }
          // Add "xxx" option created dynamically
          if (option.inputValue) {
            return option.inputValue;
          }
          // Regular option
          return option.firstName;
        }}
        renderOption={(props, option) => <li {...props}>{option.firstName}</li>}
        sx={{ width: 300 }}
        freeSolo
        renderInput={(params) => <TextField {...params} label="First Name" />}
      />
      <br />

      <Autocomplete
        value={lastName}
        onChange={(event, newValue) => {
          if (typeof newValue === "string") {
            setLastName(newValue);
          } else if (newValue && newValue.inputValue) {
            // Create a new value from the user input
            setLastName(newValue.inputValue);
          } else {
            setLastName(newValue);
          }
        }}
        filterOptions={(options, params) => {
          const filtered = filter(options, params);

          const { inputValue } = params;
          // Suggest the creation of a new value
          const isExisting = options.some(
            (option) => inputValue === option.lastName
          );
          if (inputValue !== "" && !isExisting) {
            filtered.push({
              inputValue,
              lastName: `Add "${inputValue}"`
            });
          }

          return filtered;
        }}
        selectOnFocus
        clearOnBlur
        handleHomeEndKeys
        id="free-solo-with-text-demo"
        options={data}
        getOptionLabel={(option) => {
          // Value selected with enter, right from the input
          if (typeof option === "string") {
            return option;
          }
          // Add "xxx" option created dynamically
          if (option.inputValue) {
            return option.inputValue;
          }
          // Regular option
          return option.lastName;
        }}
        renderOption={(props, option) => <li {...props}>{option.lastName}</li>}
        sx={{ width: 300 }}
        freeSolo
        renderInput={(params) => <TextField {...params} label="Last Name" />}
        required
      />

      <br />
      <Autocomplete
        value={streetAddress}
        onChange={(event, newValue) => {
          if (typeof newValue === "string") {
            setStreetAddress(newValue);
          } else if (newValue && newValue.inputValue) {
            // Create a new value from the user input
            setStreetAddress(newValue.inputValue);
          } else {
            setStreetAddress(newValue);
          }
        }}
        filterOptions={(options, params) => {
          const filtered = filter(options, params);

          const { inputValue } = params;
          // Suggest the creation of a new value
          const isExisting = options.some(
            (option) => inputValue === option.streetAddress
          );
          if (inputValue !== "" && !isExisting) {
            filtered.push({
              inputValue,
              streetAddress: `Add "${inputValue}"`
            });
          }

          return filtered;
        }}
        selectOnFocus
        clearOnBlur
        handleHomeEndKeys
        id="free-solo-with-text-demo"
        options={data}
        getOptionLabel={(option) => {
          // Value selected with enter, right from the input
          if (typeof option === "string") {
            return option;
          }
          // Add "xxx" option created dynamically
          if (option.inputValue) {
            return option.inputValue;
          }
          // Regular option
          return option.streetAddress;
        }}
        renderOption={(props, option) => (
          <li {...props}>{option.streetAddress}</li>
        )}
        sx={{ width: 300 }}
        freeSolo
        renderInput={(params) => (
          <TextField {...params} label="Street Address" />
        )}
        required
      />
      <Button type="submit">submit</Button>
    </form>
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const data = [
  {
    streetAddress: "Street Address 1",
    firstName: "Alex",
    lastName: "Dhan"
  },
  {
    streetAddress: "Street Address 2",
    firstName: "Alex",
    lastName: "Dhan"
  },
  {
    streetAddress: "Street Address 3",
    firstName: "Alex",
    lastName: "Last name"
  },
  {
    streetAddress: "Street Address 4",
    firstName: "Jin",
    lastName: "Iu"
  },
  {
    streetAddress: "Street Address 5",
    firstName: "Po",
    lastName: "Yie"
  }
];
 

最佳答案

您需要一个助手来根据您为选项定义的内容(firstNamelastNamestreetAddress)来过滤选项。它可能是这样的:

function filterData(allData, { firstName, lastName }) {
  const filteredData = allData.filter((dt) => {
    const first =
      typeof firstName === "string" ? firstName : firstName?.firstName;
    const last = typeof lastName === "string" ? lastName : lastName?.lastName;

    return (
      (!first || first === dt.firstName) && (!last || last === dt.lastName)
    );
  });

  // TODO: This line enables you to select from list data if nothing left!
  // Remove it and just return filteredData if you want filter works normally :)
  return filteredData.length ? filteredData : allData;
}

这可以帮助您:

  1. 过滤选项,
  2. 并且,设置值

接下来会根据您当前选择的内容自动完成。

看看 this code on Codesandbox 看看它是如何工作的。

按照代码中的TODO标签获取有关可用选项的更多数据。

关于javascript - 如何根据所选数据自动填充其他自动完成值,并添加数据(如果尚不存在)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72456390/

相关文章:

reactjs - 是否应该在reactjs Flux中存储调用操作?

css - 使用 styled-components 动画背景渐变

javascript - 在 Highcharts.js 中自定义工具提示?

javascript - 如何避免React中3个类似按钮的代码重复?

reactjs - 如何在手机语言更改时禁用 rtl?

css - 如何在 Material ui makeStyles 中使用 @supports css 规则?

javascript - React : TypeError: Object(. ..) 不是 Material UI 中的函数

javascript - 有没有办法散列用于 map 的 html dom 元素?

javascript - Node.js 中多个事件监听器的代码效率

javascript - 使用 jquery 根据列的累积宽度将列分为组(行)