简体   繁体   English

如何使用复选框使用反应显示隐藏 html 表行

[英]How to show hide html table rows using check boxes using react

I have some data coming from my back-end by which I am rendering my table as well as my check-boxes as they are dynamic.我有一些来自后端的数据,我通过这些数据渲染我的表格以及我的复选框,因为它们是动态的。

What I am trying to do is initially when page loads full data is shown up but when I check one checkbox I want to show that corresponding row only and again if i unchecked all data for all unchecked box should be shown,I am using react to do this我要做的是最初显示页面加载完整数据时,但是当我选中一个复选框时,我只想显示相应的行,如果我取消选中所有未选中框的所有数据,则应显示所有数据,我正在使用对做这个

I have multiple check-boxes我有多个复选框

This is my data这是我的数据

 const data = [
{
  ol_name: "delhi",
  ol_id: "123",
  ol_Amt: "2250",
  ol_Date: "12-04-2019",
  category: "A1"
},
{
  ol_name: "jaipur",
  ol_id: "1235",
  ol_Amt: "1520",
  ol_Date: "12-5-2018",
  category: "A2"
},
{
  ol_name: "kolkata",
  ol_id: "1234",
  ol_Amt: "1126",
  ol_Date: "14-02-2019",
  category: "A1"
},
{
  ol_name: "delhi",
  ol_id: "1263",
  ol_Amt: "5523",
  ol_Date: "03-03-2019",
  category: "A2"
}

]; ];

by this I am making my table and check boxes both, I want to filter my table by these two.通过这个我正在制作我的表格和复选框,我想通过这两个过滤我的表格。

I have google around a lot and found this solutions with j query as I am new to react not getting the way to do this我有很多谷歌,并使用j query找到了这个解决方案,因为我是新手,没有办法做到这一点

Please check working code sandbox检查工作代码沙箱

If you want dynamically fetch data and filters from api refer to full dynamic section at the end of answer, there is an implementation that create everything dynamically.如果您想从 api 动态获取数据和过滤器,请参阅答案末尾的完整动态部分,有一个动态创建所有内容的实现。

Static Version : Create name and category as follow Static 版本:创建名称和类别如下

let id = 0;
const unique = prop => {
    const res = [];
    data.forEach(v => {
      if (res.findIndex(i => i[prop] === v[prop]) === -1)
        res.push({ ol_id: id++, [prop]: v[prop] });
    });
    return res;
};
const checkBoxol_name = unique("ol_name");
const checkBoxol_category = unique("category");

Then write a filter然后写一个过滤器

const [filters, setFilters] = useState({
    category: [],
    ol_name: []
  });
  const filterData = () => {
    let result = data;
    Object.keys(filters).forEach(key => {
      if (filters[key].length !== 0)
        result = result.filter(item => filters[key].indexOf(item[key]) !== -1);
    });
    return result;
  };

Your tableBody should be like this你的 tableBody 应该是这样的

<tbody>
    {filterData().map(item => (
         <tr>
           <td>{item.ol_name}</td>
           <td>{item.ol_id}</td>
           <td>{item.ol_Amt}</td>
           <td>{item.ol_Date}</td>
           <td>{item.category}</td>
         </tr>
       ))
    }
</tbody>

change your category checkboxes as follow更改您的类别复选框如下

<input
       type="checkbox"
       className="custom-control-input"
       id={li.ol_id}
       name={li.category}
       filter="category"
       onChange={handleChange}
       />

change your name checkboxes as follow更改您的姓名复选框如下

 <input
       type="checkbox"
       className="custom-control-input"
       id={li.ol_id}
       name={li.ol_name}
       filter="ol_name"
       onChange={handleChange}
       />

Then add handleChange method然后添加handleChange方法

const handleChange = e => {
    let name = e.target.name;
    let filter = e.target.getAttribute("filter");
    let checked = e.target.checked;
    if (checked) {
      let newFilter = [...filters[filter]];
      newFilter.push(name);
      setFilters({ ...filters, [filter]: newFilter });
    } else {
      setFilters({
        ...filters,
        [filter]: filters[filter].filter(item => item !== name)
      });
    }
  };

Link to the sandbox ( https://codesandbox.io/s/thirsty-edison-is6zy?file=/src/App.js:987-1269 ).链接到沙箱 ( https://codesandbox.io/s/thirsty-edison-is6zy?file=/src/App.js:987-1269 )。

Full Dynamic Version : For a full dynamic version do as follow完整动态版本:对于完整动态版本,请执行以下操作

const data = [....]; // Read from API
const filterBy = [...]; // Read from API

  let id = 0;
  const unique = prop => {
    const res = [];
    data.forEach(v => {
      if (res.findIndex(i => i[prop] === v[prop]) === -1)
        res.push({ ol_id: id++, [prop]: v[prop] });
    });
    return res;
  };

  const filterGroups = {};
  let init = {};
  filterBy.forEach(item => {
    init[item] = [];
    filterGroups[item] = unique(item);
  });

  const [filters, setFilters] = useState(init);

  const filterData = () => {
    let result = data;
    Object.keys(filters).forEach(key => {
      if (filters[key].length !== 0)
        result = result.filter(item => filters[key].indexOf(item[key]) !== -1);
    });
    return result;
  };

  const handleChange = e => {
    let name = e.target.name;
    let filter = e.target.getAttribute("filter");
    let checked = e.target.checked;
    if (checked) {
      let newFilter = [...filters[filter]];
      newFilter.push(name);
      setFilters({ ...filters, [filter]: newFilter });
    } else {
      setFilters({
        ...filters,
        [filter]: filters[filter].filter(item => item !== name)
      });
    }
  };

  return (
    <div className="App">
      {filterBy.map(item => (
        <div className="container-fluid">
          <hr />
          <h5>filter with {item}</h5>
          {filterGroups[item].map(li => (
            <div key={li.ol_id} className="custom-control custom-checkbox">
              <div className="form-group each_form_group">
                <input
                  type="checkbox"
                  className="custom-control-input"
                  id={li.ol_id}
                  filter={item}
                  name={li[item]}
                  onChange={handleChange}
                />
                <label className="custom-control-label" htmlFor={li.ol_id}>
                  {li[item]}
                </label>
              </div>
            </div>
          ))}
        </div>
      ))}
      <div className="table-responsive">
        <table className="table table-bordered">
          <thead className="table-secondary">
            <tr>
              <th>Ol name</th>
              <th>Ol Id</th>
              <th>Ol Amount</th>
              <th>Ol Date</th>
              <th>Ol category</th>
            </tr>
          </thead>
          <tbody>
            {filterData().map(item => (
              <tr>
                <td>{item.ol_name}</td>
                <td>{item.ol_id}</td>
                <td>{item.ol_Amt}</td>
                <td>{item.ol_Date}</td>
                <td>{item.category}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );

Link to full dynamic version: https://codesandbox.io/s/strange-kepler-w8lgl?file=/src/App.js完整动态版链接: https://codesandbox.io/s/strange-kepler-w8lgl?file=/src/App.js

You'll need to use controlled components for the checkboxes, and then filtering the data to render.您需要为复选框使用受控组件,然后过滤要呈现的数据。

My approach was creating an array using useState hook containing filtered rows and show only the rows matching the criteria.我的方法是使用包含过滤行的useState 挂钩创建一个数组,并仅显示符合条件的行。 If no filter selected, then all rows are shown.如果未选择过滤器,则显示所有行。

Updated Code:更新代码:

import React from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";

const App = () => {
  const [filterRows, setFilterRows] = React.useState([]);
  const data = [
    {
      ol_name: "delhi",
      ol_id: "123",
      ol_Amt: "2250",
      ol_Date: "12-04-2019",
      category: "A1"
    },
    {
      ol_name: "jaipur",
      ol_id: "1235",
      ol_Amt: "1520",
      ol_Date: "12-5-2018",
      category: "A2"
    },
    {
      ol_name: "kolkata",
      ol_id: "1234",
      ol_Amt: "1126",
      ol_Date: "14-02-2019",
      category: "A1"
    },
    {
      ol_name: "delhi",
      ol_id: "1263",
      ol_Amt: "5523",
      ol_Date: "03-03-2019",
      category: "A2"
    }
  ];
  let i = 0;
  const checkBoxol_name = Array.from(new Set(data.map(s => s.ol_name))).map(
    test => {
      return {
        ol_name: test,
        ol_id: test + i
      };
    }
  );
  const checkBoxol_category = Array.from(
    new Set(data.map(s => s.category))
  ).map(test => {
    return {
      category: test,
      ol_id: test + i
    };
  });
  console.log(checkBoxol_name);

  const handleToggleFilter = event => {
    const id = event.target.name;
    if (filterRows.includes(id)) {
      return setFilterRows(filterRows.filter(_id => id !== _id));
    }
    return setFilterRows([...filterRows, id]);
  };

  console.log(filterRows);

  const hasRowBeenFiltered = (row) => {
    if(filterRows.length === 0) {
      return true;
    }

    return filterRows.includes(`${row.ol_name}${i}`) || filterRows.includes(`${row.category}${i}`)
  }

  return (
    <div className="App">
      <div className="container-fluid">
        <hr />
        <h5>filter with category</h5>
        {checkBoxol_category.map(li => (
          <div key={li.ol_id} className="custom-control custom-checkbox">
            <div className="form-group each_form_group">
              <input
                type="checkbox"
                className="custom-control-input"
                id={li.ol_id}
                name={li.ol_id}
                checked={filterRows.includes(li.ol_id)}
                onChange={handleToggleFilter}
              />
              <label className="custom-control-label" htmlFor={li.ol_id}>
                {li.category}
              </label>
            </div>
          </div>
        ))}
        <hr />
        <h5>filter with ol name</h5>
        {checkBoxol_name.map(li => (
          <div key={li.ol_id} className="custom-control custom-checkbox">
            <div className="form-group each_form_group">
              <input
                type="checkbox"
                className="custom-control-input"
                id={li.ol_id}
                name={li.ol_id}
                checked={filterRows.includes(li.ol_id)}
                onChange={handleToggleFilter}
              />
              <label className="custom-control-label" htmlFor={li.ol_id}>
                {li.ol_name}
              </label>
            </div>
          </div>
        ))}
      </div>
      <div className="table-responsive">
        <table className="table table-bordered">
          <thead className="table-secondary">
            <tr>
              <th>Ol name</th>
              <th>Ol Id</th>
              <th>Ol Amount</th>
              <th>Ol Date</th>
              <th>Ol category</th>
            </tr>
          </thead>
          <tbody>
            {data
              .filter(hasRowBeenFiltered)
              .map(item => (
                <tr>
                  <td>{item.ol_name}</td>
                  <td>{item.ol_id}</td>
                  <td>{item.ol_Amt}</td>
                  <td>{item.ol_Date}</td>
                  <td>{item.category}</td>
                </tr>
              ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export default App;

https://codesandbox.io/s/loving-perlman-dshsr https://codesandbox.io/s/loving-perlman-dshsr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM