MUI Autocomplete Customization. How to render and set as value one property, but search by another?

huangapple go评论106阅读模式
英文:

MUI Autocomplete Customization. How to render and set as value one property, but search by another?

问题

export const countries = [
  { code: '', label: '', phone: '' },
  { code: 'AD', label: 'Andorra', phone: '376' },
  { code: 'AE', label: 'United Arab Emirates', phone: '971' },
  { code: 'AF', label: 'Afghanistan', phone: '93' }
]

<Controller
  name="userDTO.phoneCode"
  control={control}
  render={({ field, fieldState: { error } }) => (
    <Autocomplete
      {...field}
      options={countries.map((country) => country.label)}
      getOptionLabel={(option) => option}
      onChange={(event, newValue) => setValue("userDTO.phoneCode", newValue, { shouldValidate: true })}
      renderInput={(params) => {
        const selectedCountry = countries.find((country) => country.label === params.inputProps.value);
        const { code, label, phone } = selectedCountry || {
          code: "",
          label: "",
          phone: "",
        };
        return (
          <TextField
            {...params}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                <InputAdornment position="start">
                  <Iconify
                    key={label}
                    icon={`circle-flags:${code.toLowerCase()}`}
                    width={28}
                    sx={{ mr: 1 }}
                  />
                </InputAdornment>
              )
            }}
            label="Phone Code"
          />
        );
      }}
      renderOption={(props, option) => {
        const selectedCountry = countries.find((country) => country.label === option);

        if (!selectedCountry) {
          return null;
        }

        return (
          <li {...props} key={selectedCountry.label}>
            <Iconify
              key={selectedCountry.label}
              icon={`circle-flags:${selectedCountry.code.toLowerCase()}`}
              width={28}
              sx={{ mr: 1 }}
            />
            {selectedCountry.label} ({selectedCountry.code}) +{selectedCountry.phone}
          </li>
        );
      }}
    />
  )}
/>
英文:
export const countries = [
  { code: &#39;&#39;, label: &#39;&#39;, phone: &#39;&#39; },
  { code: &#39;AD&#39;, label: &#39;Andorra&#39;, phone: &#39;376&#39; },
  {
    code: &#39;AE&#39;,
    label: &#39;United Arab Emirates&#39;,
    phone: &#39;971&#39;,
  },
  { code: &#39;AF&#39;, label: &#39;Afghanistan&#39;, phone: &#39;93&#39; }
]

&lt;Controller
  name=&quot;userDTO.phoneCode&quot;
  control={control}
  render={({ field, fieldState: { error } }) =&gt; (
    &lt;Autocomplete
      {...field}
      options={countries.map((country) =&gt; country.label)}
      getOptionLabel={(option) =&gt; option}
      onChange={(event, newValue) =&gt; setValue(&quot;userDTO.phoneCode&quot;, newValue, { shouldValidate: true })}
      renderInput={(params) =&gt; {
        const selectedCountry = countries.find( (country) =&gt; country.label === params.inputProps.value );
        const { code, label, phone } = selectedCountry || {
          code: &quot;&quot;,
          label: &quot;&quot;,
          phone: &quot;&quot;,
        };
        return ( 
          &lt;TextField
            {...params}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                &lt;InputAdornment position=&quot;start&quot;&gt;
                  &lt;Iconify
                    key={label}
                    icon={`circle-flags:${code.toLowerCase()}`}
                    width={28}
                    sx={{mr: 1}}
                  /&gt;
                &lt;/InputAdornment&gt;)
            }}
            label=&quot;Phone Code&quot;
         /&gt;);
      }}
      renderOption={(props, option) =&gt; {
        const {code, label, phone} = countries.filter( (country) =&gt; country.label === option )[0];

        if (!label) {
          return null;
        }

        return (
          &lt;li {...props} key={label}&gt;
            &lt;Iconify
              key={label}
              icon={`circle-flags:${code.toLowerCase()}`}
              width={28}
              sx={{mr: 1}}
           /&gt;
            {label} ({code}) +{phone}
           &lt;/li&gt;
       );
     }}
   /&gt;
 )}
/&gt;

This code will render Autocomplete with search by country.label, country.label as selected value, and country.label will be in submitted data. How to customize this code to have search by country.label, render country.phone and set country.phone as value?

I've read a documentation, but did not found solution.

答案1

得分: 0

你可以使用Autocomplete API的filterOptions属性。使用它,你可以自定义搜索,像这样的方式可能会起作用:

filterOptions={(options,state) =&gt; {
   return countries.filter(country =&gt; 
     country.label.includes(state.inputValue)).map(country =&gt; country.phone);
}}

在options中,你会收到自动完成选项的数组,在state中,你有用户输入。

英文:

You can use the filterOptions property from the Autocomplete API. With it you can customize the search, in this case something like this I think would work:


filterOptions={(options,state) =&gt; {
   return countries.filter(country =&gt; 
     country.label.includes(state.inputValue)).map(country =&gt; country.phone);
}}

In options you receive the autocomplete options array and in state you have the user input.

huangapple
  • 本文由 发表于 2023年7月31日 23:16:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定