how to create React search filter for search multiple object key values

前端 未结 2 730
轻奢々
轻奢々 2021-02-01 21:44

I want to create a search filter for my data array.it has multiple objects and keys like this one,

[
    {
        \"fname\": \"Jayne\",
        \"lname\": \"Was         


        
相关标签:
2条回答
  • 2021-02-01 21:45

    You can keep a value filter in your component state and use that to see if it is contained as a substring in any of the array element properties.

    Example

    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>

    0 讨论(0)
  • 2021-02-01 22:01

    Search filter for multiple objects key values and also highlights the search terms

    Implemented two functions - highlighter and filterHandler.

    filterHandler function filters the data based on the input given and then it sends the filtered data to highlighter function for highlighting.

    highlighter function takes two arguments obj and input and it returns highlightable HTML code as a string.

    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>

    Note: dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack.

    To read more: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

    Using Regular expressions :

    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>

    0 讨论(0)
提交回复
热议问题