Shubham Sanchela
Shubham Sanchela

Reputation: 25

Multiple Filter in One Table

This is my table data from where the data comes

  let mainArray = [
    {
      id: 1,
      name: "foo",
      city: "dallas",
      category: "one",
      type: "A",
      active: "FALSE",
      // state: "guj"
    },
    {
      id: 2,
      name: "bar",
      city: "dallas",
      category: "one",
      type: "B",
      active: "FALSE",
      //state: "guj"
    },
    {
      id: 3,
      name: "jim",
      city: "san francisco",
      category: "one",
      type: "B",
      active: "TRUE",
      //state: "raj"
    },
    {
      id: 4,
      name: "jane",
      city: "denver",
      category: "two",
      type: "C",
      active: "FALSE",
      //state: "mah"
    },
  ];

This is my JSX part

<div className="App">
      {mainArray.map((u, key) => (
        <>
          <div>
            <div>
              City : {u.city} <input type="checkbox"></input>
            </div>
            <br></br>
          </div>
          <>
            <div>
              Category :{u.category} <input type="checkbox"></input>
            </div>
            <br></br>
          </>
          <>
            <div>
              Type :{u.type} <input type="checkbox"></input>
            </div>
            <br></br>
          </>
          <>
            <div>
              Active :{u.active} <input type="checkbox"></input>
            </div>
            <br></br>
          </>
        </>
      ))}
      Name : <input type="text" name="" />
      <br></br>
      <table border="5px" align="center">
        <thead>
          <td>ID</td>
          <td>Name</td>
          <td>City</td>
          <td>Category</td>
          <td>Type</td>
          <td>Status</td>
        </thead>
        <tbody>
          {mainArray.map((item, i) => {
            return (
              <>
                <tr key={i}>
                  <td>{item.id}</td>
                  <td>{item.name}</td>
                  <td>{item.city}</td>
                  <td>{item.category}</td>
                  <td>{item.type}</td>
                  <td>{item.active}</td>
                </tr>
              </>
            );
          })}
        </tbody>
      </table>
    </div>

My Question is that I want all the data to be filtered If I checked. If I checked any one of the data then it should be filtered, and changes occurs in table.

I used w3School code for my page and it works fine but it only filters one column, don’t know how create loops but hopping there is easier solution.

here is the link : https://stackblitz.com/edit/react-nw38ow

Upvotes: 1

Views: 219

Answers (2)

Ayush Singh
Ayush Singh

Reputation: 126

I have made some modifications in your code. I think this is what you want

import React, { useState, useEffect } from 'react';
import './style.css';

export default function App() {
  const [filters, setFilters] = useState({
    city: [],
    category: [],
    type: [],
    active: [],
  });

  const [filterState, setFilterState] = useState({
    name: '',
    city: [],
    category: [],
    type: [],
    active: [],
  });

  let mainArray = [
    {
      id: 1,
      name: 'foo',
      city: 'dallas',
      category: 'one',
      type: 'A',
      active: 'FALSE',
      // state: "guj"
    },
    {
      id: 2,
      name: 'bar',
      city: 'dallas',
      category: 'one',
      type: 'B',
      active: 'FALSE',
      //state: "guj"
    },
    {
      id: 3,
      name: 'jim',
      city: 'san francisco',
      category: 'one',
      type: 'B',
      active: 'TRUE',
      //state: "raj"
    },
    {
      id: 4,
      name: 'jane',
      city: 'denver',
      category: 'two',
      type: 'C',
      active: 'FALSE',
      //state: "mah"
    },
  ];
  const handleCity = (e) => {
    let arr = filterState.city;
    if (e.target.checked) {
      if (!arr.indexOf(e.target.value) > -1) {
        arr.push(e.target.value);
        setFilterState({
          ...filterState,
          city: arr,
        });
      }
    } else {
      if (arr.indexOf(e.target.value) > -1) {
        arr.splice(arr.indexOf(e.target.value), 1);
        setFilterState({
          ...filterState,
          city: arr,
        });
      }
    }
  };
  const handleCategory = (e) => {
    let arr = filterState.category;
    if (e.target.checked) {
      if (!arr.indexOf(e.target.value) > -1) {
        arr.push(e.target.value);
        setFilterState({
          ...filterState,
          category: arr,
        });
      }
    } else {
      if (arr.indexOf(e.target.value) > -1) {
        arr.splice(arr.indexOf(e.target.value), 1);
        setFilterState({
          ...filterState,
          category: arr,
        });
      }
    }
  };
  const handleType = (e) => {
    let arr = filterState.type;
    if (e.target.checked) {
      if (!arr.indexOf(e.target.value) > -1) {
        arr.push(e.target.value);
        setFilterState({
          ...filterState,
          type: arr,
        });
      }
    } else {
      if (arr.indexOf(e.target.value) > -1) {
        arr.splice(arr.indexOf(e.target.value), 1);
        setFilterState({
          ...filterState,
          type: arr,
        });
      }
    }
  };
  const handleActive = (e) => {
    let arr = filterState.active;
    if (e.target.checked) {
      if (!arr.indexOf(e.target.value) > -1) {
        arr.push(e.target.value);
        setFilterState({
          ...filterState,
          active: arr,
        });
      }
    } else {
      if (arr.indexOf(e.target.value) > -1) {
        arr.splice(arr.indexOf(e.target.value), 1);
        setFilterState({
          ...filterState,
          active: arr,
        });
      }
    }
  };
  const getCities = (cities) => (
    <div>
      <div>
        City :{' '}
        {cities
          .filter((item, i, ar) => ar.indexOf(item) === i)
          .map((city) => (
            <>
              {city}{' '}
              <input
                type="checkbox"
                value={city}
                onChange={(e) => handleCity(e)}
              ></input>
            </>
          ))}
      </div>
      <br></br>
    </div>
  );

  const getCategories = (categories) => (
    <div>
      Category :
      {categories
        .filter((item, i, ar) => ar.indexOf(item) === i)
        .map((category) => (
          <>
            {category}{' '}
            <input
              type="checkbox"
              value={category}
              onChange={(e) => handleCategory(e)}
            ></input>
          </>
        ))}
    </div>
  );

  const getTypes = (types) => (
    <div>
      Type :
      {types
        .filter((item, i, ar) => ar.indexOf(item) === i)
        .map((type) => (
          <>
            {type}{' '}
            <input
              type="checkbox"
              value={type}
              onChange={(e) => handleType(e)}
            ></input>
          </>
        ))}
    </div>
  );

  const getActive = (actives) => (
    <div>
      Active :
      {actives
        .filter((item, i, ar) => ar.indexOf(item) === i)
        .map((active) => (
          <>
            {active}{' '}
            <input
              type="checkbox"
              value={active}
              onChange={(e) => handleActive(e)}
            ></input>
          </>
        ))}
    </div>
  );

  useEffect(() => {
    let city = filters.city;
    let category = filters.category;
    let type = filters.type;
    let active = filters.active;

    mainArray.forEach((item) => {
      city.push(item.city);
      category.push(item.category);
      type.push(item.type);
      active.push(item.active);
    });
    setFilters({
      ...filters,
      city: city,
      category: category,
      type: type,
      active: active,
    });
  }, []);
  return (
    <div>
      {getCities(filters.city)}
      {getCategories(filters.category)}
      <br></br>
      {getTypes(filters.type)}
      <br></br>
      {getActive(filters.active)}
      <br></br>
      Name :{' '}
      <input
        type="text"
        name=""
        onChange={(e) =>
          setFilterState({ ...filterState, name: e.target.value })
        }
      />
      <br></br>
      <table border="5px" align="center">
        <thead>
          <td>ID</td>
          <td>Name</td>
          <td>City</td>
          <td>Category</td>
          <td>Type</td>
          <td>Status</td>
        </thead>
        <tbody>
          {mainArray
            .filter(
              (item) =>
                (item.name.includes(filterState.name) ||
                  filterState.name == '') &&
                (filterState.city.includes(item.city) ||
                  filterState.city.length == 0) &&
                (filterState.category.includes(item.category) ||
                  filterState.category.length == 0) &&
                (filterState.type.includes(item.type) ||
                  filterState.type.length == 0) &&
                (filterState.active.includes(item.active) ||
                  filterState.active.length == 0)
            )
            .map((item, i) => {
              return (
                <>
                  <tr key={i}>
                    <td>{item.id}</td>
                    <td>{item.name}</td>
                    <td>{item.city}</td>
                    <td>{item.category}</td>
                    <td>{item.type}</td>
                    <td>{item.active}</td>
                  </tr>
                </>
              );
            })}
        </tbody>
      </table>
    </div>
  );
}


Upvotes: 0

Rishab Vaigankar
Rishab Vaigankar

Reputation: 443

stackblitz

I tried using state in react.

const [mainArray, setMainArray] = useState([values from mainArray ])

           <div>
              City : {u.city}{' '}
              <input
                type="checkbox"
                value={u.city}
                onChange={(event) => filterData(event.target, 'city')}
              ></input>
            </div> 



 function filterData(target, type) {
    if (target.checked) {
      let result = mainArray.filter((res) => res[type] == target.value);
      setMainArray([...result]);
    }
  }

onClick of checkout mainArray state will be filtered

Upvotes: 1

Related Questions