如何创建React搜索过滤器以搜索多个对象键值

时间:2018-08-11 17:03:03

标签: javascript reactjs loops

我想为我的数据数组创建一个搜索过滤器。它具有多个对象和键,就像这样,

[
    {
        "fname": "Jayne",
        "lname": "Washington",
        "email": "jaynewashington@exposa.com",
        "gender": "female"
    },
    {
        "fname": "Peterson",
        "lname": "Dalton",
        "email": "petersondalton@exposa.com",
        "gender": "male"
    },
    {
        "fname": "Velazquez",
        "lname": "Calderon",
        "email": "velazquezcalderon@exposa.com",
        "gender": "male"
    },
    {
        "fname": "Norman",
        "lname": "Reed",
        "email": "normanreed@exposa.com",
        "gender": "male"
    }
]

我想要搜索过滤器在此数组的任何位置进行搜索。 例如:当我输入框时,我想搜索对象内的任何地方。像fname,lname,email,gender

我该怎么做?请帮助我

4 个答案:

答案 0 :(得分:3)

您可以在组件状态中保留值filter,并使用该值查看它是否作为子字符串包含在任何数组元素属性中。

示例

class App extends React.Component {
  state = {
    filter: "",
    data: [
      {
        fname: "Jayne",
        lname: "Washington",
        email: "jaynewashington@exposa.com",
        gender: "female"
      },
      {
        fname: "Peterson",
        lname: "Dalton",
        email: "petersondalton@exposa.com",
        gender: "male"
      },
      {
        fname: "Velazquez",
        lname: "Calderon",
        email: "velazquezcalderon@exposa.com",
        gender: "male"
      },
      {
        fname: "Norman",
        lname: "Reed",
        email: "normanreed@exposa.com",
        gender: "male"
      }
    ]
  };

  handleChange = event => {
    this.setState({ filter: event.target.value });
  };

  render() {
    const { filter, data } = this.state;
    const lowercasedFilter = filter.toLowerCase();
    const filteredData = data.filter(item => {
      return Object.keys(item).some(key =>
        item[key].toLowerCase().includes(lowercasedFilter)
      );
    });

    return (
      <div>
        <input value={filter} onChange={this.handleChange} />
        {filteredData.map(item => (
          <div key={item.email}>
            <div>
              {item.fname} {item.lname} - {item.gender} - {item.email}
            </div>
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

答案 1 :(得分:0)

最后,我创建了我的react-mui-datatables库。您可以在其中下载

https://www.npmjs.com/package/react-mui-datatables

答案 2 :(得分:0)

搜索多个对象键值的过滤器,并突出显示搜索词

实现了两个功能-highlighterfilterHandler

filterHandler函数根据给定的输入过滤数据,然后将过滤后的数据发送到荧光笔功能以突出显示。

highlighter函数接受两个参数obj和input,并以字符串形式返回高亮显示的HTML代码。

class App extends React.Component {
  state = {
    input: "",
    fData: [{
        fname: "Jayne",
        lname: "Washington",
        email: "jaynewashington@exposa.com",
        gender: "female"
      },
      {
        fname: "Peterson",
        lname: "Dalton",
        email: "petersondalton@exposa.com",
        gender: "male"
      },
      {
        fname: "Velazquez",
        lname: "Calderon",
        email: "velazquezcalderon@exposa.com",
        gender: "male"
      },
      {
        fname: "Norman",
        lname: "Reed",
        email: "normanreed@exposa.com",
        gender: "male"
      }
    ],
    data: [{
        fname: "Jayne",
        lname: "Washington",
        email: "jaynewashington@exposa.com",
        gender: "female"
      },
      {
        fname: "Peterson",
        lname: "Dalton",
        email: "petersondalton@exposa.com",
        gender: "male"
      },
      {
        fname: "Velazquez",
        lname: "Calderon",
        email: "velazquezcalderon@exposa.com",
        gender: "male"
      },
      {
        fname: "Norman",
        lname: "Reed",
        email: "normanreed@exposa.com",
        gender: "male"
      }
    ]
  };


  handleChange = event => {
    this.setState({
      input: event.target.value
    }, this.filterHandler);
  };

  highlighter = (obj, lowercasedInput) => {
    let rawObj = obj.replace(`<span class='highlight'>`, '').replace(`</span>`, '');

    if (rawObj.indexOf(lowercasedInput) != -1) {
      const startIndex = rawObj.indexOf(lowercasedInput);
      const endIndex = startIndex - 1 + lowercasedInput.length;

      if (startIndex != 0) {
        return rawObj.slice(0, startIndex) + `<span class='highlight'>${lowercasedInput}</span>` + rawObj.slice(endIndex + 1, rawObj.length);
      } else {
        return rawObj.slice(0, startIndex) + `<span class='highlight'>${lowercasedInput}</span>` + rawObj.slice(endIndex + 1, rawObj.length);
      }
    } else {
      return rawObj
    }
  }


  filterHandler = () => {
    const {
      input,
      data
    } = this.state;
    const lowercasedInput = input.toLowerCase();

    const filteredData = data.filter(item => {
      return Object.keys(item).some(key =>
        item[key].toLowerCase().includes(lowercasedInput)
      );
    });

    let highlightFD = [];
    filteredData.map((values, index) => {
      highlightFD.push({ ...values
      });
    })


    if (lowercasedInput.trim().length > 0) {
      highlightFD.map((val, index) => {
        for (let key in val) {
          highlightFD[index][key] = this.highlighter(val[key].toLowerCase(), lowercasedInput);
        }
      });
    }

    this.setState({
      fData: highlightFD
    });

  }

  render() {
    const {
      input,
      fData
    } = this.state;



    return ( <
        div >
        <
        input value = {
          input
        }
        onChange = {
          this.handleChange
        }
        /> {
        fData.map(item => ( <div key ={item.email} className = "results" >
         <div dangerouslySetInnerHTML = {{__html: item.fname}}/>&nbsp;|&nbsp; 
         <div dangerouslySetInnerHTML = {{__html: item.lname}}/>&nbsp;|&nbsp; 
         <div dangerouslySetInnerHTML = {{__html: item.gender}}/>&nbsp;|&nbsp; 
          <div dangerouslySetInnerHTML = {{__html: item.email}}/>  
        </div >
        ))
      } </div>
  );
}
}

ReactDOM.render( < App / > , document.getElementById("root"));
.results {
  display: flex
}

span {
  background-color:black;
  color:white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

注意:危险地,SetInnerHTML是React在浏览器DOM中使用innerHTML的替代品。通常,从代码设置HTML是有风险的,因为很容易在无意间使用户遭受跨站点脚本(XSS)攻击。

要了解更多信息,请访问:https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

使用正则表达式:

class App extends React.Component {
  state = {
    input: "",
    fData: [{
        fname: "Jayne",
        lname: "Washington",
        email: "jaynewashington@exposa.com",
        gender: "female"
      },
      {
        fname: "Peterson",
        lname: "Dalton",
        email: "petersondalton@exposa.com",
        gender: "male"
      },
      {
        fname: "Velazquez",
        lname: "Calderon",
        email: "velazquezcalderon@exposa.com",
        gender: "male"
      },
      {
        fname: "Norman",
        lname: "Reed",
        email: "normanreed@exposa.com",
        gender: "male"
      }
    ],
    data: [{
        fname: "Jayne",
        lname: "Washington",
        email: "jaynewashington@exposa.com",
        gender: "female"
      },
      {
        fname: "Peterson",
        lname: "Dalton",
        email: "petersondalton@exposa.com",
        gender: "male"
      },
      {
        fname: "Velazquez",
        lname: "Calderon",
        email: "velazquezcalderon@exposa.com",
        gender: "male"
      },
      {
        fname: "Norman",
        lname: "Reed",
        email: "normanreed@exposa.com",
        gender: "male"
      }
    ]
  };


  handleChange = event => {
    this.setState({
      input: event.target.value
    }, this.filterHandler);
  };

  highlighter = (obj, lowercasedInput) => {
    let rawObj = obj.replace(`<span class='highlight'>`, '').replace(`</span>`, '');

    if (rawObj.indexOf(lowercasedInput) != -1) {
      const startIndex = rawObj.indexOf(lowercasedInput);
      const endIndex = startIndex - 1 + lowercasedInput.length;

      if (startIndex != 0) {
        return rawObj.slice(0, startIndex) + `<span class='highlight'>${lowercasedInput}</span>` + rawObj.slice(endIndex + 1, rawObj.length);
      } else {
        return rawObj.slice(0, startIndex) + `<span class='highlight'>${lowercasedInput}</span>` + rawObj.slice(endIndex + 1, rawObj.length);
      }
    } else {
      return rawObj
    }
  }


  filterHandler = () => {
    const {
      input,
      data
    } = this.state;
    const lowercasedInput = input.toLowerCase();

    const filteredData = data.filter(item => {
      return Object.keys(item).some(key =>{
         const regex= new RegExp(`^${lowercasedInput.trim()}`,'i');
            return regex.test(item[key].toLowerCase()) ;
         }
      );
    });

    let highlightFD = [];
    filteredData.map((values, index) => {
      highlightFD.push({ ...values
      });
    })


    if (lowercasedInput.trim().length > 0) {
      highlightFD.map((val, index) => {
        for (let key in val) {
          highlightFD[index][key] = this.highlighter(val[key].toLowerCase(), lowercasedInput);
        }
      });
    }

    this.setState({
      fData: highlightFD
    });

  }

  render() {
    const {
      input,
      fData
    } = this.state;



    return ( <
        div >
        <
        input value = {
          input
        }
        onChange = {
          this.handleChange
        }
        /> {
        fData.map(item => ( <div key ={item.email} className = "results" >
         <div dangerouslySetInnerHTML = {{__html: item.fname}}/>&nbsp;|&nbsp; 
         <div dangerouslySetInnerHTML = {{__html: item.lname}}/>&nbsp;|&nbsp; 
         <div dangerouslySetInnerHTML = {{__html: item.gender}}/>&nbsp;|&nbsp; 
          <div dangerouslySetInnerHTML = {{__html: item.email}}/>  
        </div >
        ))
      } </div>
  );
}
}

ReactDOM.render( < App / > , document.getElementById("root"));
.results {
  display: flex
}

span {
  background-color:black;
  color:white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

答案 3 :(得分:0)

fData.filter((person) => {
  return object
    .value(person)
    .join('')
    .toLowerCase()
    .include(searchinput.toLowerCase())
})

此处的 searchinput 是您在输入中键入的值,该值由状态控制。