首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >列上的默认筛选器值

列上的默认筛选器值
EN

Stack Overflow用户
提问于 2018-10-05 14:58:17
回答 4查看 9.3K关注 0票数 2

我想我缺少一些React或JavaScript知识来解决我想要做的事情。

背景:

我用React

  • 做了一个表格。

  • 它为每一列都有一个输入框过滤器。组件中的状态自动接受查询字符串并将其解析为对象。当页面加载解析后的查询string.

  • However,时,会自动填充输入框。表中显示的数据仍然是所有数据,而不仅仅是过滤后的数据。我必须遍历每个输入框并按enter键,才能按该值进行过滤。因此,自动输入到输入框中的值仅用于显示

My problem:

我希望在加载时对表进行筛选。但我不知道如何在加载所有内容时触发一次过滤器。

列标题代码:

代码语言:javascript
复制
//    ***Generate the column structure necessary for ReactTable
generateColumnHeaders(api_part_labels) {
    let label_array = []
    for (var key in api_part_labels) {
        const hasHeader = api_part_labels[key].includes(">")

        if (hasHeader) {
            label_array.push([api_part_labels[key].split(">")[0], api_part_labels[key].split(">")[1], key]);
        } else {
            label_array.push([api_part_labels[key], api_part_labels[key], key]);
        }
    }
    let mainHeaders = label_array.map((x) => x[0]);
    mainHeaders = Array.from(new Set(mainHeaders));
    let output = [];
    console.log(this.state.parsed);
    for (var i in mainHeaders) {
        let labels = label_array.filter(x => x[0] === mainHeaders[i]);

        if (labels.length === 1) {
            let param = labels[0][2];
            output.push({
                Header: labels[0][1],
                accessor: param,
                id: param,
                width: this.calculateColumnWidth(param, labels[0][1]),

            });
        } else {
            let columns = [];
            for (var i_label in labels) {
                var label = labels[i_label];
                let param = label[2];
                columns.push({
                    Header: label[1],
                    accessor: param,
                    id: param,
                    width: this.calculateColumnWidth(param, label[1]),
                    filteredValue: this.state.parsed[param],
                    Filter: ({ filter, onChange }) => {
                        return (
                            <input
                                onKeyPress={event => {
                                    if (event.keyCode === 13 || event.which === 13) {
                                        let value = event.target.value;
                                        onChange(value);

                                        // update the parsed state with the event filter value
                                        this.updateParsed(param, value);

                                        // update 1) the query string, and 2) the URL
                                        let stringified = queryString.stringify(this.state.parsed);
                                        this.props.location.search = stringified;
                                        this.props.history.push(`?${stringified}`);
                                    }
                                }}
                                defaultValue={this.state.parsed[param]}
                            />
                        )},
                });
            }
            output.push({ Header: labels[0][0], columns: columns });
        }
    }

    return output;
};

My React表:

代码语言:javascript
复制
return (
            <ReactTable
                // data and columns
                data = { this.parts }
                noDataText = "Whoops! No data available!"
                columns = { this.part_columns }

                // appearance
                defaultPageSize = {20}
                className = "-striped -highlight"
                style = {{ height: "800px" }}

                // sorting and filtering
                defaultSorted = {[ { id: "part_number", desc: false } ]}
                filterable
                defaultFilterMethod = {(filter, row) =>

String(row[filter.id]).toLowerCase().includes(filter.value.toLowerCase())}
            />
        )
EN

回答 4

Stack Overflow用户

发布于 2019-06-05 06:34:45

我认为你需要(Ed)ReactTable上的defaultFiltered属性:

代码语言:javascript
复制
            defaultFiltered={[
              {
                id: 'reporting_year',
                value: new Date().getFullYear(),
              },
            ]}

我还想将筛选器框中的编辑控件自定义为包含列中唯一值的下拉列表。由于文档相当薄弱(或者我速度很慢和/或太晚了),我也会在这里包含列定义:

代码语言:javascript
复制
    {
      Header: 'Report Yr',
      accessor: 'reporting_year',
      Filter: ({ filter, onChange }) => {
        let found = {}
        let options = this.props.dashboard
          // remove duplicates
          .filter(function(row) {
            if (!found[row.reporting_year]) {
              found[row.reporting_year] = true
              return true
            }
            return false
          })
          // sort
          .sort((a, b) => (a.reporting_year > b.reporting_year ? 1 : b.reporting_year > a.reporting_year ? -1 : 0))
          // return option list
          .map(function(row) {
            return (
              <option value={row.reporting_year} key={row.reporting_year}>
                {row.reporting_year}
              </option>
            )
          })
        return (
          <select
            onChange={event => {
              onChange(event.target.value)
            }}
            style={{ width: '100%' }}
            value={filter ? filter.value : 'all'}>
            {options}
          </select>
        )
      },
    },

默认筛选器文本框被替换为一个下拉列表,其中包含数据中的所有值,默认为defaultFiltered设置(在本例中为当前年份)。

请注意,如果您不想要All选项,则此表示不是很好,因为该列只能包含单个值,这是对水平屏幕空间的浪费。

为了避免每一列的重复代码,我创建了一个更高阶的函数。这非常方便-只需在任何列上设置FilterfilterMethod属性,就可以将文本过滤器切换到包含所有唯一值的下拉列表。

代码语言:javascript
复制
class MyCmp extends Component {
  ...
  filterFn = accessor => ({ filter, onChange }) => {
    let found = {}
    let options = this.props.dashboard
      .filter(function(row) {
        if (row[accessor] && !found[row[accessor]]) {
          found[row[accessor]] = true
          return true
        }
        return false
      })
      .sort((a, b) => (a[accessor] > b[accessor] ? 1 : b[accessor] > a[accessor] ? -1 : 0))
      .map(function(row) {
        return (
          <option value={row[accessor]} key={row[accessor]}>
            {row[accessor]}
          </option>
        )
      })
    return (
      <select
        onChange={event => {
          onChange(event.target.value)
        }}
        style={{ width: '100%' }}
        value={filter ? filter.value : 'all'}>
        <option value='all' key={'all'}>
          All
        </option>
        {options}
      </select>
    )
  }
  filterMethod = (filter, row, column) => {
    if (filter.value === 'all') {
      return true
    }
    const id = filter.pivotId || filter.id
    return row[id] !== undefined ? String(row[id]) === String(filter.value) : true
  }

然后,要向列中添加下拉列表,只需添加FilterfilterMethod属性:

代码语言:javascript
复制
  columns = [
    {
      Header: 'CSP Code',
      accessor: 'csp_code',
      Filter: this.filterFn('csp_code'),
      filterMethod: this.filterMethod,
    },
    {
      Header: 'Report Yr',
      accessor: 'reporting_year',
      Filter: this.filterFn('reporting_year'),
      filterMethod: this.filterMethod,
    },
    ...

请注意,这会忽略空单元格-它们只在选择了All时显示,并且不能被过滤。例如,它不区分' 12‘和’12‘。它还忽略了自定义单元格和对底层值的过滤--我的一些单元格是图标,但下拉列表显示和过滤底层数据值(这是我想要的行为,并充当图标的一种键)。

This example有一些方便的代码示例和技术。

票数 1
EN

Stack Overflow用户

发布于 2018-10-05 16:03:35

您需要在componentDidMount()方法中调用一个函数来过滤表数据。

如果你不知道什么是compoenetDidMount()方法,请阅读这篇关于Lifecycle Events in React的指南,这是在React中需要理解的核心概念之一,以基于文档的触发事件来实现一些操作。

票数 0
EN

Stack Overflow用户

发布于 2018-10-05 16:24:59

正如@Elharony所说,您需要在componentDidMount()方法中设置按查询项过滤--我已经为您编写了here代码,也请参阅注释。

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52659961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档