提交后,下拉过滤器不会显示所有选项,并且所应用的过滤器会远离占位符-ReactJS / Javascript

时间:2019-01-03 03:50:17

标签: javascript reactjs react-table

在我的React Table多选中,我有一个父页面和一个子页面,我有一个子页面和一个父页面。父页面包含数据,而子页面具有多选下拉列表。

我能够正确过滤,但是当我提交过滤器然后再次打开过滤器时,过滤器未显示在占位符位置,如下所示。我在下拉菜单中看到了该选定选项,其他选项未显示。我需要在占位符中有选定的选项,而在下拉菜单中是所有选项。所有下拉选择器都将执行此操作。

Project Screenshot

上面的屏幕截图是当我选中特定列的过滤器复选框时

提交并尝试再次过滤后,我得到了

Not Desired

这是我的父页面(该页面包含我要应用过滤器的数据的页面)的代码

import React from "react";
import { render } from "react-dom";
import { makeData } from "./Utils"; // eslint-disable-line
// import matchSorter from "match-sorter";

// import Select from "react-select";
// import "react-select/dist/react-select.css";

import Child from './Child/Child'
import jsondata from './sample'

// Import React Table
import ReactTable from "react-table";
import "react-table/react-table.css";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      // data: makeData(),
      data: jsondata,
      dataDefault: jsondata,
      filtered: [],
      select2: null,
      select3: null,
      childOpen: false
    };
    this.openChild = this.openChild.bind(this);
    this.applyFilter = this.applyFilter.bind(this);
    this.showDefaultView = this.showDefaultView.bind(this);
  }

  applyFilter(filtered) {
    console.log('Entering Apply Filter Function of Parent');
    console.log('The filtered data in parent ' + JSON.stringify(filtered));
    const currentStateChild = this.state.childOpen;
    this.setState({
      childOpen: !currentStateChild
    }, () => {
      console.log('Child is opened ' + this.state.childOpen);
    });
    const filterArray = filtered;
    const apidata = this.state.data;
    let filteredData = apidata.filter(item =>        // filter jsondata
      filterArray.every( f =>                // so every member of filter array
           f.value.includes(item[f.id])) )   // has a corresponding item[id] in value

    console.log('The filtered rows are ' + JSON.stringify(filteredData));
    this.setState({
      data: filteredData
    }, () => {
      console.log('Manipulated rows ' + this.state.data);
    });
  }

  openChild() {
    const currentStateChild = this.state.childOpen;
    this.setState({
      childOpen: !currentStateChild
    }, () => {
      console.log('Child is opened ' + this.state.childOpen);
    });
  }

  showDefaultView() {
    const defaultDataParent = this.state.dataDefault;
    this.setState({
      data: defaultDataParent
    }, () => {
      console.log('Default rows ' + this.state.data);
    });
  }

  render() {
    const { data } = this.state;
    return (
      <div>
        <div className='clickMeToOpenChild' onClick={this.openChild} > Click Me to Open Child</div>
        <div className='clickMeToGetDefaultView' onClick={this.showDefaultView} > Click Me to show Default View</div>
        <br />
        <br />
        <ReactTable
          data={data}
          filterable
          filtered={this.state.filtered}
          onFilteredChange={(filtered, column, value) => {
            this.onFilteredChangeCustom(value, column.id || column.accessor);
          }}
          defaultFilterMethod={(filter, row, column) => {
            const id = filter.pivotId || filter.id;
            if (typeof filter.value === "object") {
              return row[id] !== undefined
                ? filter.value.indexOf(row[id]) > -1
                : true;
            } else {
              return row[id] !== undefined
                ? String(row[id]).indexOf(filter.value) > -1
                : true;
            }
          }}
          columns={[
            {
              Header: "Name",
              columns: [
                {
                  Header: "First Name",
                  accessor: "firstName"
                },
                {
                  Header: "Last Name",
                  id: "lastName",
                  accessor: d => d.lastName
                }
              ]
            },
            {
              Header: "Info",
              columns: [
                {
                  Header: "Age",
                  accessor: "age"
                },
              ]
            }
          ]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        {this.state.childOpen &&
        <Child
          data={data}
          applyFilter={this.applyFilter}
        />}
        <br />
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

这是我的子页面的代码(该页面具有多选下拉菜单-目前只有2个下拉菜单,以后会添加更多内容)

import React, { Component } from 'react'; // eslint-disable-line
import PropTypes from 'prop-types'; // eslint-disable-line
// import uniqBy from 'lodash';
// import _ from 'lodash';
import Select from 'react-select';
import 'react-select/dist/react-select.css';
// import { bindActionCreators } from 'redux';
// import { connect } from 'react-redux';
import './Child.css';

class Child extends Component {
    constructor(props) {
      super(props);
      this.state = {
        data: this.props.data,
        filtered: [],
        select2: null,
        select3: null,
      };
      // this.findUnique = this.findUnique.bind(this);
      this.getOptions = this.getOptions.bind(this);
    }

    getOptions(propertyName) {
      return this.state.data.reduce((accum, elem, i) => {
        const accumulator = [...accum];
        if (!accumulator.some(e => e.value === elem[propertyName])) {
          accumulator.push({
            id: i,
            value: elem[propertyName],
            label: elem[propertyName]
          });
        }
        return accumulator;
      }, []);
    }

    onFilteredChange(value, accessor) {
      const { filtered } = this.state;
      let insertNewFilter = 1;
      if(filtered.length) {
        filtered.forEach((filter, i) => {
          if(filter.id === accessor) {
            if(value === '' || !value.length) filtered.splice(i, 1);
            else filter.value = value;// eslint-disable-line

            insertNewFilter = 0;
          }
        });
      }

      if(insertNewFilter) {
        filtered.push({ id: accessor, value });
      }

      this.setState({ filtered });
    }

    render() {
      console.log('Entering Child Render Method');
      const { data } = this.state; // eslint-disable-line
      const { filtered } = this.state; // eslint-disable-line
      console.log('filtered items in child ' + JSON.stringify(this.state.filtered));
    //   console.log('data in child ' + JSON.stringify(this.state.data));
      return (
        <div className='filter-child' >
          <div className='submitChild' onClick={() => { this.props.applyFilter(filtered); }}> Click Me to Submit Child
          </div>
          <div>
          Select First Name :{" "}
        <Select
          style={{ width: "50%", marginBottom: "20px" }}
          onChange={entry => {
            this.setState({ select2: entry });
            this.onFilteredChange(
              entry.map(o => {
                return o.value;
              }),
             'firstName'
            );
          }}
          value={this.state.select2}
          multi={true}
          options={this.getOptions("firstName")}
        />
        Select Last Name :{" "}
        <Select
          style={{ width: "50%", marginBottom: "20px" }}
          onChange={entry => {
            this.setState({ select3: entry });
            this.onFilteredChange(
              entry.map(o => {
                return o.value;
              }),
              "lastName"
            );
          }}
          value={this.state.select3}
          multi={true}
          options={this.getOptions("lastName")}
        />
          </div>
        </div>
      );
    }
  }

  Child.propTypes = {
    data: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
    applyFilter: PropTypes.func.isRequired
  };

  Child.defaultProps = {
  };


  export default Child;

这是我从中获取数据的示例json对象文件

const jsonData = [
  {
    firstName: "Sam",
    lastName: "Jones",
    age: "10"
  },
  {
    firstName: "Sam",
    lastName: "Jones1",
    age: "10"
  },
  {
    firstName: "Sam2",
    lastName: "Jones1",
    age: "12"
  },
  {
    firstName: "Sam3",
    lastName: "Jones3",
    age: "13"
  },
  {
    firstName: "Sam4",
    lastName: "Jones4",
    age: "14"
  },
  {
    firstName: "Sam5",
    lastName: "Jones5",
    age: "15"
  },
  {
    firstName: "Sam",
    lastName: "Jones11",
    age: "16"
  },
  {
    firstName: "Sam6",
    lastName: "Jones6",
    age: "17"
  },
  {
    firstName: "Sam7",
    lastName: "Jones7",
    age: "18"
  },
  {
    firstName: "Sam8",
    lastName: "Jones8",
    age: "19"
  },
  {
    firstName: "Sam9",
    lastName: "Jones9",
    age: "20"
  },
  {
    firstName: "Sam10",
    lastName: "Jones10",
    age: "21"
  },
  {
    firstName: "Sam11",
    lastName: "Jones11",
    age: "22"
  },
  {
    firstName: "Sam12",
    lastName: "Jones12",
    age: "23"
  }
];

  export default jsonData;

我需要一种可以应用于任意数量的下拉菜单的通用解决方案。

即使提交了子页面(具有下拉菜单的页面),我的下拉菜单也应该看起来像屏幕截图1,但是我得到的却是屏幕截图2。当我提交过滤器然后再次打开过滤器时,过滤器未显示在占位符位置,如下所示。我在下拉菜单中看到了该选定选项,其他选项未显示。我需要在占位符中有选定的选项,而在下拉菜单中是所有选项。所有下拉选择器都将执行此操作。

0 个答案:

没有答案