Sort the table ascending & descending order when i click on button in reactjs

function TopicsTable(props) {
  return (
    <Table className="tablecss">

      <thead>
        <tr>
          <th>
             <button type="button">
              {props.getHeader[0]}
            </button>            
          </th>
          <th>
             <button type="button">
              {props.getHeader[1]}
            </button>            
          </th>
          <th>
             <button type="button">
              {props.getHeader[2]}
            </button>            
          </th>
          <th>
             <button type="button">
              {props.getHeader[3]}
            </button>            
          </th>
          <th>
             <button type="button">
              {props.getHeader[4]}
            </button>            
          </th>
          <th>
             <button type="button">
              {props.getHeader[5]}
            </button>            
          </th>
          </tr>
          </thead>

      <TableBody>
        {(props.getRowInfo)}
      </TableBody>
    </Table>
  );
}

 getRowsData = () => {
    var rowContents = this.state.data;

    return rowContents.map((rowContent, index) => {
      this.state.rowCount = this.state.rowCount + 1;
      return <React.Fragment><TableRow key={index} onClick={() => this.handleClick(index)}>{this.RenderCell(rowContent)}</TableRow>  {this.state.show && this.state.id === index ? <ChildComponent/>:""} </React.Fragment>
    })
  }




render() {
    return (
      <div className="Main">
        <header className="App-header">
          <h2 className="hdr"><i>Openion</i></h2>
        </header>
        <h4><Actionunit /></h4>
        <br />
        <TopicsTable getHeader={this.getHeader()} getRowInfo={this.getRowsData()}/>
      </div>
    );
  }

Sort the table ascending & descending order when i click on button in reactjs

Upvotes: 0

Views: 7813

Answers (2)

Akber Iqbal
Akber Iqbal

Reputation: 15031

I think the requirements you're looking for is:

  • dynamically select which column is to be sorted
  • sort ascending or descending
  • the number of columns can be dynamic
  • the number of rows can be dynamic

My solution doesn't use <table> but that is something you can manage easily...

Relevant component which gets headers, rows... sorts and prints data:

import React, { useState, useEffect } from "react";

export const MyTable = props => {
  const { header, data } = props;
  const [sortedRows, setSortedRows] = useState([]);
  const [headers, setHeaders] = useState([]);

  useEffect(() => {
    setSortedRows(data);
    setHeaders(header);
  }, []);

  const Sorter = fieldToSort => {
    let sortedArray = sortedRows;
    if(fieldToSort.dir === 'asc' ){

    sortedArray.sort((a, b) =>
      a[fieldToSort.label] > b[fieldToSort.label] ? 1 : b[fieldToSort.label] > a[fieldToSort.label] ? -1 : 0
    );
    } else {
          sortedArray.sort((a, b) =>
      a[fieldToSort.label] < b[fieldToSort.label] ? 1 : b[fieldToSort.label] < a[fieldToSort.label] ? -1 : 0
    );
    }
    (fieldToSort.dir === 'asc') ? fieldToSort.dir = 'dsc' : fieldToSort.dir = 'asc';
    let newHeaders = header;
    newHeaders[fieldToSort.dir] = fieldToSort.dir;

    setHeaders([...newHeaders]);
    setSortedRows([...sortedArray]);
  };

  return (
    <>
      <h2>Actual Table</h2>
      {headers.map((val, ind) => {
        return (
          <button type="button" key={ind} onClick={() => Sorter(val)}>
            {val.label} ({val.dir})
          </button>
        );
      })}
      {sortedRows.length > 0 ? (
        <ul>
          {sortedRows.map((val, ind) => {
            return (
              <li>
                {val.name} - {val.age}{" "}
              </li>
            );
          })}{" "}
        </ul>
      ) : (
        "no data available"
      )}
    </>
  );
};

complete working stackblitz here

Upvotes: 1

Enchew
Enchew

Reputation: 1001

First, define your state, to save your current sort order:

  state = {
    sortedBy: '',
    sortDirection: 0
  }

Then, define constants, to show the order direction (outside of your class):

const sortAsc = 1;
const sortDesc = -1;

Then, define your sort function:

  sortTable = (columnName) => {
    let sortDirection = sortAsc;
    if (this.state.columnName === columnName) {
      if (this.state.sortDirection === sortAsc) {
        sortDirection = sortDesc;
      } 
    } 
    this.s.TableData.sort((x1, x2) =>  x1[columnName] < x2[columnName] ? -1 * sortDirection :  sortDirection )
    this.setState({
      columnName, sortDirection, data: this.state.data
    })
  };

Then, attach this function to each table header:

 <th>
     <button type="button" onClick={() => props.sortTable(props.getHeader[0])> // <-- here you pass the header NAME (Upvote, Downvote, Comment and etc.)
      {props.getHeader[0]}
    </button>            
  </th>

Keep in mind, that this code is taken out of context, and you may face errors with naming, parameters passing and etc, in general it is a basic abstraction. The sort function was tested out and working. I hope you will manage to integrate it in your application. Good luck!

Upvotes: 0

Related Questions