Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

antd table filter does not unfilter after deleting search query

I am attempting to create a simple filter mechanism for data in an antd table component. The filter is triggered by the onChange event in an antd search input.

I have managed to get the filter to work correctly when typing into the search input, but when I delete the initial input I don’t get my original table results back. It’s as if the state is not updating after the most recent onChange event.

This example demonstrates precisely what I am trying to do, but it is mapping some data to elements instead of using an antd table. This leads me to think there is something I am missing specifically when it comes to filtering data in an antd table.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This example also demonstrates what I am trying to do, but it is implemented as a class, so I’m having some trouble translating the logic over to my functional component. Particularly on line 128 I’m seeing the map function again, but I don’t understand what’s happening there.

I would also like to add that I did not experience this problem with the same implementation using a basic html table with map function to insert the data.

Here is my code:

export default function DriversModal({ isVisible, handleClose }) {
  const initialUserData = [
    { type: 2, user: { name: 'TestName1', username: 'name1@email.com'}, phone: '(123) 456-1111', ops: 37 },
    { type: 1, user: { name: 'TestName2', username: 'name2@email.com'}, phone: '(123) 456-2222', ops: 16 },
    { type: 2, user: { name: 'TestName3', username: 'name3@email.com'}, phone: '(123) 456-3333', ops: 4 },
    { type: 1, user: { name: 'TestName4', username: 'name4@email.com'}, phone: '(123) 456-4444', ops: 52 }
  ]

  const columns = [
    {
      title: 'Name',
      dataIndex: 'user',
      render: (user) => (
        <>
          <div className="list-modal-cell-text-primary">{user.name}</div>
          <div className="list-modal-cell-text-secondary">{user.username}</div>
        </>
      ),
      width: 320,
      key: '1',
    },
    {
      title: 'Phone',
      dataIndex: 'phone',
      width: 144,
      key: '2',
    },
    {
      title: 'Ops',
      dataIndex: 'ops',
      key: '3',
    },
  ];

  const [users, setUsers] = useState(initialUserData);
  const [query, setQuery] = useState('');

  const handleChange = (e) => {
    setQuery(e.target.value);
  }

  useEffect(() => {
    setUsers(users.filter(item =>
      item.user.name.toLowerCase().includes(query.toLowerCase()) ||
      item.user.username.toLowerCase().includes(query.toLowerCase())
    ))
  }, [query, users])

  return (
    <Modal
      title={<DriversModalHeader handleChange={handleChange} handleSort={handleSort} query={query} />}
      bodyStyle={{ height: '264px'}}
      visible={isVisible}
      closable={false}
      destroyOnClose={true}
      footer={[
        <Button
          onClick={handleClose}
        >
          Close
        </Button>
      ]}
    >
      <Table
        dataSource={users}
        columns={columns}
        pagination={false}
        scroll={{
          y: 240,
        }}
        row
      />
    </Modal>
  )
}

DriversModalHeader:

export default function DriversModalHeader({ handleChange, handleSort, query }) {
  const menu = (
    <Menu>
      <Menu.Item key="availability" onClick={handleSort}>Sort by availability</Menu.Item>
      <Menu.Item key="alphabetic" onClick={handleSort}>Sort alphabetically</Menu.Item>
    </Menu>
  )

  return (
    <div className="list-modal-header">
      <div className="title">
        <div className="title">
          Drivers
        </div>
      </div>
      <div className="elements">
        <div className="list-modal-input-with-button">
          <Input.Search
            value={query}
            placeholder="Search"
            onChange={handleChange}
          />
          <span className="icon">
            <Icon component={Search} style={{fontSize: '16px'}} />
          </span>
        </div>
        <div className="list-modal-dropdown">
          <StateSelect />
        </div>
        <div>
          <Dropdown.Button
            placement={"bottomRight"}
            className="union"
            overlay={menu}
            trigger={['click']}
            icon={<Icon component={Union} style={{fontSize: '24px'}}/>}
          >
          </Dropdown.Button>
        </div>
      </div>
    </div>
  );
};

>Solution :

I just checked the first example you mentioned.

As you said, it doesn’t unfilter after deleting the search query.
The reason is simple. It’s because the app should have to filter the data with empty string from initial data but instead it’s trying to filter data that you already filtered with search query.

So the solution is replace "users.filter … " with "initialUserData.filter …" on useEffect hook.

  useEffect(() => {
    setUsers(
      users.filter( //replace with initialUserData.filter
        (item) =>
          item.user.name.toLowerCase().includes(search.toLowerCase()) ||
          item.user.username.toLowerCase().includes(search.toLowerCase())
      )
    ); }, [search, users]);

I hope it will be helpful for you.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading