admin管理员组

文章数量:1404923

I am working on a project in which I am trying to show a div of content that says No results found for if the user types letters in the search input that do not match any filter in the list. I've tried using this similar solution as reference: React: How to show message when result is zero in react, but without success.

Here is a snippet of my code and one solution (of many) I have tried so far:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchQuery: ""
    };
  }

  handleSearchQuery = event => {
    this.setState({ searchQuery: event.target.value });
  };

  resetInputField = () => {
    this.setState({ searchQuery: "" });
  };

  render() {
    const { subContent, type, options, label } = this.props;
    const { searchQuery } = this.state;
    return (
      <div
        style={{
          display: "grid",
          alignItems: "center",
          width: "100%",
          margin: "0 0 24px 0",
          fontSize: "14px"
        }}
      >
        <div style={sx.rangeInputContainer}>
          <input
            style={sx.rangeInputLong}
            type="text"
            placeholder={placeholderText}
            onChange={this.handleSearchQuery}
            value={searchQuery}
          />
        </div>
        <div>
          {options
            .filter(
              option =>
                option.label
                  .toLowerCase()
                  .includes(searchQuery.toLowerCase()) || !searchQuery
            )
            .map((option, index) => {
              return option.label.length !== 0 ? (
                <div key={index} style={sx.filterOption}>
                  <SquareCheckbox
                    type="checkbox"
                    id={"multiSelectCheckbox-" + option.label}
                  />
                  <label
                    style={{ color: "#FFF" }}
                    htmlFor={"multiSelectCheckbox-" + option.label}
                  >
                    {option.label}
                  </label>
                </div>
              ) : (
                <div
                  key={index}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    marginTop: "16px"
                  }}
                >
                  <img
                    style={{ width: "20px", cursor: "pointer" }}
                    src={resetIconSVG}
                    onClick={this.resetInputField}
                  />
                  <div style={{ marginLeft: "16px" }}>
                    No results found for {searchQuery}
                  </div>
                </div>
              );
            })}
        </div>
      </div>
    );
  }
}

Here's a snippet of options, which is in my parent ponent:

this.state = {
        filters: [


            {
                label: 'Materials',
                type: FILTER_TYPE.MULTI_SELECT,
                expandedHandle: ()=> {  
                this.handleExpandedToggle('Materials'); },
                options:materials,
                expanded:false,
            },
            {
                label: 'Status',
                type: FILTER_TYPE.SELECT,
                expandedHandle: ()=> {  this.handleExpandedToggle('Status'); 
             },
                options: status,
                expanded:false,
            },


        ],
    };

And the dummy .json data I am using:

export const materials = [
{ value: 'brass', label: 'brass' },
{ value: 'chrome', label: 'chrome' },
{ value: 'ceramic', label: 'ceramic' },
{ value: 'glass', label: 'glass' },
{ value: 'concrete', label: 'concrete' },

];

export const status = [
{ value: 'Show All', label: 'Show All' },
{ value: 'Enabled Only', label: 'Enabled Only' },

];

I am working on a project in which I am trying to show a div of content that says No results found for if the user types letters in the search input that do not match any filter in the list. I've tried using this similar solution as reference: React: How to show message when result is zero in react, but without success.

Here is a snippet of my code and one solution (of many) I have tried so far:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchQuery: ""
    };
  }

  handleSearchQuery = event => {
    this.setState({ searchQuery: event.target.value });
  };

  resetInputField = () => {
    this.setState({ searchQuery: "" });
  };

  render() {
    const { subContent, type, options, label } = this.props;
    const { searchQuery } = this.state;
    return (
      <div
        style={{
          display: "grid",
          alignItems: "center",
          width: "100%",
          margin: "0 0 24px 0",
          fontSize: "14px"
        }}
      >
        <div style={sx.rangeInputContainer}>
          <input
            style={sx.rangeInputLong}
            type="text"
            placeholder={placeholderText}
            onChange={this.handleSearchQuery}
            value={searchQuery}
          />
        </div>
        <div>
          {options
            .filter(
              option =>
                option.label
                  .toLowerCase()
                  .includes(searchQuery.toLowerCase()) || !searchQuery
            )
            .map((option, index) => {
              return option.label.length !== 0 ? (
                <div key={index} style={sx.filterOption}>
                  <SquareCheckbox
                    type="checkbox"
                    id={"multiSelectCheckbox-" + option.label}
                  />
                  <label
                    style={{ color: "#FFF" }}
                    htmlFor={"multiSelectCheckbox-" + option.label}
                  >
                    {option.label}
                  </label>
                </div>
              ) : (
                <div
                  key={index}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    marginTop: "16px"
                  }}
                >
                  <img
                    style={{ width: "20px", cursor: "pointer" }}
                    src={resetIconSVG}
                    onClick={this.resetInputField}
                  />
                  <div style={{ marginLeft: "16px" }}>
                    No results found for {searchQuery}
                  </div>
                </div>
              );
            })}
        </div>
      </div>
    );
  }
}

Here's a snippet of options, which is in my parent ponent:

this.state = {
        filters: [


            {
                label: 'Materials',
                type: FILTER_TYPE.MULTI_SELECT,
                expandedHandle: ()=> {  
                this.handleExpandedToggle('Materials'); },
                options:materials,
                expanded:false,
            },
            {
                label: 'Status',
                type: FILTER_TYPE.SELECT,
                expandedHandle: ()=> {  this.handleExpandedToggle('Status'); 
             },
                options: status,
                expanded:false,
            },


        ],
    };

And the dummy .json data I am using:

export const materials = [
{ value: 'brass', label: 'brass' },
{ value: 'chrome', label: 'chrome' },
{ value: 'ceramic', label: 'ceramic' },
{ value: 'glass', label: 'glass' },
{ value: 'concrete', label: 'concrete' },

];

export const status = [
{ value: 'Show All', label: 'Show All' },
{ value: 'Enabled Only', label: 'Enabled Only' },

];
Share Improve this question edited Nov 13, 2018 at 14:17 ShowstopperCode1 asked Nov 13, 2018 at 13:49 ShowstopperCode1ShowstopperCode1 1301 gold badge4 silver badges16 bronze badges 4
  • 1 "but without success" Can you be more specific? Is there an error message? Do you get an unexpected result? – Damon Commented Nov 13, 2018 at 13:55
  • please provide a sample data of this.props.options – Tu Nguyen Commented Nov 13, 2018 at 14:04
  • I actually get no response. However if I start the the ternary expression with === 0, then I see the message No results found for repeated four times – ShowstopperCode1 Commented Nov 13, 2018 at 14:07
  • @NguyễnThanhTú I've updated the question with a snippet of my options and dummy json data I am using – ShowstopperCode1 Commented Nov 13, 2018 at 14:18
Add a ment  | 

2 Answers 2

Reset to default 4

I've made an assumption about your options data, hopefully this helps (I simplified the codes)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      searchQuery: ''
    };
  }
  handleSearchQuery = event => {
    this.setState({ searchQuery: event.target.value });
  };
  resetInputField = () => {
    this.setState({ searchQuery: '' });
  };
  render() {
    const { searchQuery } = this.state;
    const options = [
      { label: 'react' },
      { label: 'angular' },
      { label: 'vue' }
    ];
    const filteredOptions = options.filter(
      option =>
        option.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
        !searchQuery
    );
    return (
      <div>
        <div>
          <input
            type="text"
            onChange={this.handleSearchQuery}
            value={searchQuery}
          />
        </div>
        <div>
          {filteredOptions.length > 0 ? (
            filteredOptions.map((option, index) => {
              return <div key={index}>{option.label}</div>;
            })
          ) : (
            <div>
              No results found for {searchQuery}
            </div>
          )}
        </div>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg./react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg./react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

Seems like your using a ternary operator inside of a return on your filter method. I would put the filter into a variable

const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchQuery.toLowerCase()) || !searchQuery).map((option, index) => {
  return option.label.length !== 0 ? <div key={index} style={sx.filterOption}>
    <SquareCheckbox type='checkbox' id={'multiSelectCheckbox-' + option.label} />
    <label style={{ color: '#FFF' }} htmlFor={'multiSelectCheckbox-' + option.label}> {option.label} </label>
  </div> })

and in your render use the ternary to check the length of the array

render {
 return (
  {filteredOptions.length > 0 ? filteredOptions : <div style = {{ marginLeft: '16px' }}>No results found for { searchQuery }</div>}
  )
}

本文标签: javascriptHow to show message when filtered list is empty in ReactStack Overflow