Prathamesh Jadhav
Prathamesh Jadhav

Reputation: 55

how sort columns in ascending and descending order?

i am created table using array of objects and now i didnot undestand How We sort table in ascending and descnding order by clicking on column name in reactjs. I am tried lot of concepts on stackoverflow but it seems it doesnot useful for this one. This is very silly question but I am stopped on this from many days.

 class Hello extends Component {
    constructor(props) {
        super(props)
    
        this.state = {
          search: '',
            Data:[
                {
                    id: 1,
                    fullName: 'abc',
                    email:'[email protected]',
                    
                },
                {
                    id: 2,
                    fullName: 'qps',
                    email:'[email protected]',
                    
                },
                {
                    id: 3,
                    fullName: 'qwe',
                    email:'[email protected]',
                    
                },
             ]
        }
    }
         function Sort(){
//what need to write here;
}
        render() {
            return (
                
                <div>
                    <h1>welcome to React</h1>
                    <table className="table table-hover table-dark">
                    
                    <tbody>
                        <tr>
                            <th onChange={this.Sort.bind(this)}>ID</th>
                            <th>Full Name</th>
                            <th>Email</th>
                        </tr>
                    {
                       this.state.Data.map((item,index)=>(
                        <tr key={item.id}>
                            
                            <td >{item.id}</td>
                        
                            <td >{item.fullName}</td>
                            <td>{item.email}</td>
                        </tr>
                    ))
                    }
                    </tbody>
                    </table>
    
                </div>
            )
        }
    }
    export default Hello

Upvotes: 1

Views: 3004

Answers (2)

EvanMorrison
EvanMorrison

Reputation: 1217

  • You need to switch the onChange handler to onClick.
  • add some state to store the last sort direction;
  • Use the Array sort() method, but take care not to mutate your state.
  this.state = {
    order: 'ASC'
  ...

function sort() {
  let sortedList = [...this.state.Data];
  let newOrder = this.state.order === 'ASC' ? 'DESC' : 'ASC';
  if (newOrder === 'ASC') {
    sortedList.sort((a, b) => a.id - b.id)
  } else {
    sortedList.sort((a, b) => b.id - a.id)
  }
  
  this.setState({ Data: sortedList, order: newOrder });
}

To be able to sort on any of the columns, I would make the following change:

  function sort(column) {
    const sortedList = [...this.state.Data];
    const newOrder = this.state.order === "ASC" ? "DESC" : "ASC";
    const sortValue = (v1, v2) => {
      if (column === 'id') return v1.id - v2.id;
      return (v1[column] ?? '')
        .toLowerCase()
        .localeCompare((v2[column] ?? '').toLowerCase())
    }
    if (newOrder === "ASC") {
      sortedList.sort((a, b) => sortValue(a, b));
    } else {
      sortedList.sort((a, b) => sortValue(b, a));
    }
    this.setState({ Data: sortedList, order: newOrder });
  }

And add an appropriate onClick handler for each column heading.

<th onClick={() => this.sort('id')}>ID</th>
<th onClick={() => this.sort('fullName')}>Full Name</th>
<th onClick={() => this.sort('email')}>Email</th>

Edit dawn-paper-1bh7t

Upvotes: 2

WebbH
WebbH

Reputation: 2422

Add a state variable for ascending or descending sort and then in your sort function:

function Sort(a,b){
    if(this.state.ascending){
        return a.id - b.id
    {
    return b.id - a.id
}

And then in your render function add the sort method before the map:

const Data = [...this.state.Data]
//...

      Data.sort((a,b)=>this.Sort(a,b)).map((item,index)=>(
        <tr key={item.id}>           
          <td >{item.id}</td>        
          <td >{item.fullName}</td>
          <td>{item.email}</td>
        </tr>
              
               

Finally change your onClick to just change the state of ascending/descending:

 <th onClick={()=>this.setState({ascending: !this.state.ascending)}>ID</th>

Upvotes: 0

Related Questions