【问题标题】:Display number of matching search options on Textfield input in Material UI Autocomplete在 Material UI 自动完成中的 Textfield 输入中显示匹配搜索选项的数量
【发布时间】:2021-01-08 00:16:14
【问题描述】:

我正在尝试自定义 Material UI 自动完成并在用户搜索并在搜索框中输入字符串后显示当前显示在 Popper 菜单中的选项计数(这是在您选择一个选项之前,它变成value 很容易用value.length 计算)。当用户在 renderInput<Textfield/> 中输入击键时,我可能会丢失该道具,以便从整个选项数组中获取选项的数量显示 <Autocomplete/> .

代码如下:

 <Autocomplete
        value={value}
        onClose={handleClose}
        onChange={(event, newValue) => {
          setValue(newValue);
        }}
        options={options}
        getOptionLabel={option => option.title}
        renderInput={params => (
          <React.Fragment>
            <TextField
              {...params}
              variant="underlined"
              placeholder="Search"
            />
            <span className={classes.visibleFilterNum}>
              Showing X of {options.length}
            </span>
          </React.Fragment>
        )}
      />

这是目前为止的组件,需要不断更新显示选项总数 X 的计数

这里是从 Material UI 示例文档中提取的 codepen of something similar,作为起始代码集的更好示例

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    使用useAutocomplete 挂钩很简单,因为它公开了groupedOptions 变量(即filtered options)。

    这是一个例子:

    export default function UseAutocomplete() {
      const classes = useStyles();
      const {
        getRootProps,
        getInputLabelProps,
        getInputProps,
        getListboxProps,
        getOptionProps,
        groupedOptions
      } = useAutocomplete({
        id: "use-autocomplete-demo",
        options: top100Films,
        getOptionLabel: (option) => option.title
      });
    
      return (
        <div>
          <div {...getRootProps()}>
            <label className={classes.label} {...getInputLabelProps()}>
              useAutocomplete
            </label>
            <input className={classes.input} {...getInputProps()} />
          </div>
          {groupedOptions.length > 0 ? (
            <>
              <div>
                Showing {groupedOptions.length} of {top100Films.length}
              </div>
              <ul className={classes.listbox} {...getListboxProps()}>
                {groupedOptions.map((option, index) => (
                  <li {...getOptionProps({ option, index })}>{option.title}</li>
                ))}
              </ul>
            </>
          ) : null}
        </div>
      );
    }
    


    groupedOptions 不会以任何直接的方式被 Autocomplete 组件公开,但可以通过检查 HTML 以在呈现后计算选项来确定显示选项的数量。下面的示例通过覆盖Paper component 来实现这一点。选项显示在Paper 元素中,所有选项都收到data-option-index attribute。下面的示例使用这些方面来计算使用来自Paper 元素的querySelectorAll 的选项:

    import React from "react";
    import TextField from "@material-ui/core/TextField";
    import Autocomplete from "@material-ui/lab/Autocomplete";
    import Paper from "@material-ui/core/Paper";
    
    const NumResultsHeader = ({ children, ...other }) => {
      const headerRef = React.useRef();
      const countRef = React.useRef();
      const paperRef = React.useRef();
      React.useEffect(() => {
        const numOptions = paperRef.current.querySelectorAll(
          "li[data-option-index]"
        ).length;
        countRef.current.innerHTML = numOptions;
        if (numOptions > 0) {
          headerRef.current.style.display = "block";
        } else {
          headerRef.current.style.display = "none";
        }
      });
      return (
        <>
          <div ref={headerRef} style={{ display: "none" }}>
            Showing <span ref={countRef}></span> of {top100Films.length}
          </div>
          <Paper {...other} ref={paperRef}>
            {children}
          </Paper>
        </>
      );
    };
    export default function ComboBox() {
      return (
        <Autocomplete
          id="combo-box-demo"
          options={top100Films}
          getOptionLabel={(option) => option.title}
          style={{ width: 300 }}
          PaperComponent={NumResultsHeader}
          renderInput={(params) => (
            <TextField {...params} label="Combo box" variant="outlined" />
          )}
        />
      );
    }
    

    【讨论】:

    • 这是一个很棒的解决方案,并且非常深入地解释了如何完成!谢谢瑞恩 :)
    • 如果 top100Films 数组未在我们创建 NumResultsHeader 的同一文件中定义,我如何访问要在 &lt;span&gt;Showing {countRef} of {top100Films.length}&lt;/span&gt; 中显示的选项的 top100Films/数量?我试过传入,但出现长度=未定义
    • @user10782250 我建议您使用代码沙箱创建一个新问题,以重现您遇到的问题。
    • 啊,谢谢!这是将选项数组从ComboBox 文件/组件中分离出来的问题的代码框。在这里的示例中:codesandbox.io/s/…,我将 ComboBox 导入我的App.js 文件并通过道具传递选项。
    • @user10782250 目前没有任何好的方法来处理这个问题,但我已经记录了一个关于它的问题:github.com/mui-org/material-ui/issues/23043。我认为 v5 可能会以某种方式支持这一点,但距离稳定版本还有几个月的时间。
    猜你喜欢
    • 2020-07-05
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 2020-03-18
    • 2023-01-24
    • 1970-01-01
    • 2017-07-18
    相关资源
    最近更新 更多