Home > Mobile >  React JS Filter Methods: Hiding table columns using array filters and state
React JS Filter Methods: Hiding table columns using array filters and state

Time:10-14

This is the code I am trying to rebuild using functional component, but my arrays do not behave correctly.
EXPECTED RESULT: https://stackblitz.com/edit/antd-showhidecolumns

My forked functional component version: MY WORK https://stackblitz.com/edit/antd-showhidecolumns-rdyc8h

Main issue here is I am not able to show/hide column cells, I am not sure why my array is different when I use the same method as the original code.

My code:

  const onChange = (e) => {
    let { checkedColumns } = colmenu;
    if (e.target.checked) {
      checkedColumns = checkedColumns.filter((id) => {
        return id !== e.target.id;
      });
      console.log('if checked columns is', checkedColumns);
    } else if (!e.target.checked) {
      checkedColumns.push(e.target.id);
      console.log('elseif checked columns', checkedColumns);
    }
    const filtered = checkedColumns.filter((el) => {
      return el.dataIndex !== checkedColumns.el;
    });
    console.log('filtered items', filtered);
    setColmenu({ ...colmenu, columns: filtered });
  };

working version from the old code (class component)

 onChange = (e) => {
    var checkedColumns = this.state.checkedColumns
    if(e.target.checked){
    checkedColumns = checkedColumns.filter(id => {return id !== e.target.id})
    
    }
    else if(!e.target.checked){
    checkedColumns.push(e.target.id)
  
    }

  var filtered = this.state.initialColumns;
    for(var i =0;i< checkedColumns.length; i  )
    filtered = filtered.filter(el => {return el.dataIndex !== checkedColumns[i]})

    this.setState({columns: filtered, checkedColumns: checkedColumns})
  }

CodePudding user response:

Something really went wrong with your code (or homework i guess?)

Please have a look at least at the docs for React.useState to set some basics.

First you should init your initalColumns and later you should filter on them.

Additional i init the checkColumns with the correct values and changed the wrong logic for changing them.

Have a look how the filtering is done via Array.includes maybe someone will ask for this ;-)

Another point is that you may split the state object in separate primitive states.

Nevertheless here is a working stackblitz and the depending code.

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Button, Dropdown, Menu, Checkbox } from 'antd';

const App = () => {
  const columns = [
    {
      title: 'Description',
      dataIndex: 'description',
    },
    {
      title: 'Employees',
      dataIndex: 'employees',
    },
  ];
  const [colmenu, setColmenu] = React.useState({
    value: false,
    checkedColumns: ['description', 'employees'],
    visibleMenuSettings: false,
    columns,
    initialColumns: columns,
  });
  const onChange = (e) => {
    let { checkedColumns, columns, initialColumns } = colmenu;
    if (!e.target.checked) {
      checkedColumns = checkedColumns.filter((id) => {
        return id !== e.target.id;
      });
      console.log('if checked columns is', checkedColumns);
    } else if (e.target.checked) {
      checkedColumns.push(e.target.id);
      console.log('elseif checked columns', checkedColumns);
    }
    console.log(columns);
    columns = initialColumns.filter((col) =>
      checkedColumns.includes(col.dataIndex)
    );
    setColmenu({ ...colmenu, columns, checkedColumns });
  };
  const handleVisibleChange = (flag) => {
    setColmenu({ ...colmenu, visibleMenuSettings: flag });
  };
  const menu = (
    <Menu>
      <Menu.ItemGroup title="Columns">
        <Menu.Item key="0">
          <Checkbox id="description" onChange={onChange} defaultChecked>
            Description
          </Checkbox>
        </Menu.Item>
        <Menu.Item key="1">
          <Checkbox id="employees" onChange={onChange} defaultChecked>
            Employees
          </Checkbox>
        </Menu.Item>
      </Menu.ItemGroup>
    </Menu>
  );

  const dataSource = [
    {
      key: '1',
      description: 'Holiday 1',
      employees: '79',
    },
    {
      key: '2',
      description: 'Holiday 2',
      employees: '12',
    },
    {
      key: '3',
      description: 'Holiday 3',
      employees: '0',
    },
  ];

  return (
    <div>
      <div className="row">
        <div className="col-12 mb-3 d-flex justify-content-end align-items-center">
          <Dropdown
            overlay={menu}
            onVisibleChange={handleVisibleChange}
            visible={colmenu.visibleMenuSettings}
          >
            <Button>Show/Hide Columns</Button>
          </Dropdown>
        </div>
      </div>
      <div className="row">
        <div className="col-12">
          <Table
            columns={colmenu.columns}
            dataSource={dataSource}
            size="small"
            pagination={{
              pageSizeOptions: ['20', '50'],
              showSizeChanger: true,
            }}
          />
        </div>
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('container'));

  • Related