React Table单列自定义搜索不起作用-ReactJS / Javascript

时间:2019-01-05 08:12:29

标签: javascript reactjs react-table

我正在使用React Table-Demo。我正在尝试创建一个自定义框,该框只能过滤第一列-firstName。基于第一列搜索,将显示其他列的相应行。我有很多代码,为简单起见,我使用注释标记了哪些代码块与搜索功能相关。

这是我的父组件

import React from "react";
import { render } from "react-dom";
import TypeChecker from 'typeco';
// import matchSorter from "match-sorter";
import  SearchField from './SearchField';
import './App.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,
      basicExampleList: jsondata, // this field is related to search
      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);
    this.onBasicExampleChange = this.onBasicExampleChange.bind(this); // this field is related to search
    this.onEnterExample = this.onEnterExample.bind(this); // this field is related to search
    this.onSearchClickExample = this.onSearchClickExample.bind(this); // this field is related to search
    this.getMatchedList = this.getMatchedList.bind(this); // this field is related to search
  }


  getMatchedList(searchText) { // this method is related to search
    if (TypeChecker.isEmpty(searchText)) return this.state.basicExampleList;
    return this.state.basicExampleList.filter(item => item.firstName.includes(searchText) ||
      item.firstName.includes(searchText));
  };

  onBasicExampleChange(value) { // this method is related to search
    this.setState({
      basicExampleList: this.getMatchedList(value),
    });
  }

  onEnterExample(value) { // this method is related to search
    this.setState({
      basicExampleList: this.getMatchedList(value),
    });
  }

  onSearchClickExample(value) { // this methods is related to search
    this.setState({
      basicExampleList: this.getMatchedList(value),
    });
  }



  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 />
        <SearchField
            placeholder="Search item" // this block is related to search
            onChange={this.onBasicExampleChange}
            onEnter={this.onEnterExample}
            onSearchClick={this.onSearchClickExample}
          />
        <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"));

这是我的SearchField页面

import React from 'react';
import PropTypes from 'prop-types';
import TypeChecker from 'typeco';

const ENTER_KEY = 13;
const SEARCH_BUTTON_EDGE = 35;

const searchFieldStyle = {
  border: '1px #ddd solid',
  display: 'inline-flex',
  justifyContent: 'space-between',
  height: SEARCH_BUTTON_EDGE,
};

const searchFieldButtonStyle = {
  height: SEARCH_BUTTON_EDGE - 2, // reduces 2px because of top and bottom border
  width: SEARCH_BUTTON_EDGE - 2,
  outline: 'none',
  backgroundColor: 'white',
  cursor: 'pointer',
  padding: 5,
  boxSizing: 'border-box',
  appearance: 'none',
  border: 'none',
  borderLeft: '1px #ddd solid',
};

const searchFieldInputStyle = {
  outline: 'none',
  border: 'none',
  fontSize: 14,
  padding: 10,
  flex: 1,
  color: '#5a5a5a',
  fontWeight: 100,
  height: SEARCH_BUTTON_EDGE - 2,
};

const SearchIcon = () => {
  const iconEdge = Math.ceil(SEARCH_BUTTON_EDGE * 0.60);
  const searchIconStyle = {
    fill: '#727272',
  };
  return (
    <svg
      version="1.1"
      x="0px"
      y="0px"
      width={iconEdge}
      height={iconEdge}
      viewBox="0 0 635 635"
      style={searchIconStyle}
    >
      <g>
        <path d="M255.108,0C119.863,0,10.204,109.66,10.204,244.904c0,135.245,109.659,244.905,244.904,244.905
          c52.006,0,100.238-16.223,139.883-43.854l185.205,185.176c1.671,1.672,4.379,1.672,5.964,0.115l34.892-34.891
          c1.613-1.613,1.47-4.379-0.115-5.965L438.151,407.605c38.493-43.246,61.86-100.237,61.86-162.702
          C500.012,109.66,390.353,0,255.108,0z M255.108,460.996c-119.34,0-216.092-96.752-216.092-216.092
          c0-119.34,96.751-216.091,216.092-216.091s216.091,96.751,216.091,216.091C471.199,364.244,374.448,460.996,255.108,460.996z"
        />
      </g>
    </svg>
  );
};

class SearchField extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: this.props.searchText,
    };

    this.onChangeBound = this.onChangeBound.bind(this);
    this.onEnterBound = this.onEnterBound.bind(this);
    this.onSearchClick = this.onSearchClick.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.searchText !== nextProps.searchText) {
      this.setState({
        value: nextProps.searchText,
      });
    }
  }

  onChangeBound(event) {
    this.setState({
      value: event.target.value,
    });
    if (TypeChecker.isFunction(this.props.onChange)) {
      this.props.onChange(event.target.value, event);
    }
  }

  onEnterBound(event) {
    const isEnterPressed = event.which === ENTER_KEY || event.keyCode === ENTER_KEY;
    if (isEnterPressed && TypeChecker.isFunction(this.props.onEnter)) {
      this.props.onEnter(event.target.value, event);
    }
  }

  onSearchClick() {
    if (TypeChecker.isFunction(this.props.onSearchClick)) {
      this.props.onSearchClick(this.state.value);
    }
  }

  render() {
    const {
      classNames,
      placeholder,
    } = this.props;
    const className = `react-search-field ${classNames}`;

    return (
      <div
        className={className}
        style={searchFieldStyle}
      >
        <input
          className="react-search-field-input"
          style={searchFieldInputStyle}
          onChange={this.onChangeBound}
          onKeyPress={this.onEnterBound}
          placeholder={placeholder}
          type="text"
          value={this.state.value}
        />
        <button
          className="react-search-field-button"
          type="button"
          style={searchFieldButtonStyle}
          onClick={this.onSearchClick}
        >
          <SearchIcon />
        </button>
      </div>
    );
  }
}

SearchField.propTypes = {
  classNames: PropTypes.string,
  searchText: PropTypes.string,
  placeholder: PropTypes.string,
  onChange: PropTypes.func,
  onEnter: PropTypes.func,
  onSearchClick: PropTypes.func,
};

SearchField.defaultProps = {
  classNames: '',
  searchText: '',
  placeholder: 'Search',
  onChange: null,
  onEnter: null,
  onSearchClick: null,
};

export default SearchField;

这是用于填充行的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;

我没有发布CSS,如果您想看到的话,请参阅Demo。我的搜索框未在搜索和过滤值。请帮助。

0 个答案:

没有答案