strider
strider

Reputation: 5954

How to add a sortable index column in react-table

So I'd like use react-table to create a sortable column that numbers each row (according to its position in the data set).

According to docs, sorting is done via a sorting function that compares the accessor value. However, the accessor option does not expose the index, unlike the Cell option.

So that means this won't work:

const columns = [
  {
    Header: '#',
    id: 'index',
    accessor: (row) => row.index // 'index' is undefined
  },
  /* ... */
]

My current workaround is to inject an index directly into the dataset like this:

myIndexedData = myData.map((el,index) => ({index, ...el})) //immutable

return (
  <ReactTable
    data={myIndexedData}
    columns={columns}
  />
);

This is not really an optimal solution, especially with a large dataset. Is there a better way that I'm not seeing?

Upvotes: 5

Views: 14223

Answers (5)

ManhNguyen
ManhNguyen

Reputation: 121

   {
      Header: '#',
      Cell: (row) => {
        return <div>{Number(row.row.id) + 1}</div>;
      },
    }

"react-table": "7.7.0", get index for pagination and page size

function getIndex(props) {
  return (
     <div>
       {props.state.pageIndex * props.state.pageSize + 
        Number(props.row.id) + 1}
     </div>
  );
}

Upvotes: 1

Mahdi Mohammadizadeh
Mahdi Mohammadizadeh

Reputation: 195

You can use the second argument as index.

{
      Header: '#',
      id: 'index',
      accessor: (_row: any, i : number) => i + 1 
}

Upvotes: 9

Zapwoi
Zapwoi

Reputation: 51

{
    Header: "Index",
    accessor: "",
    Cell: (row) => {
        return <div>{row.row.id + 1}</div>;
    },
    disableSortBy: true,
    disableFilters: true,
},

ver."react-table": "^7.6.3",

Upvotes: 5

khushbu thakur
khushbu thakur

Reputation: 11

export const SerialNumberColumn = {
    Header: "Sr No", // label of header
    id: "row", 
    maxWidth: 50,
    filterable: false,  
    Cell: (row) => {
      let {pageIndex} = row.state; // get current page index (1 - n)
      let {index} = row.cell.row;  // get current row number (0 - 9)
      let srNo = ``;

      if(pageIndex === 1){
        srNo = index + 1;
      // 1, 2, 3, 4,
     // as index starts from 0

      }else{
        if(index === 9){
          srNo = `${pageIndex}0`;
       // in case of 20, 30, 40, 50
        }else{
          srNo = `${pageIndex - 1}${index + 1}`;
       // for others such as 11, 12, 13, 41, 42, ..., n
        }
      }
        return <div>{srNo}</div>;
    }
};

For example, your page size is 10 (10 rows on each page) and you have 15 pages total. So total records would be 10 * 15 = 150;

What the above code does is,

  1. let {pageIndex} = row.**strong text**state;

This extracts the page number for each row. So from records 0-9, the page number will be 1

  1. let {index} = row.cell.row;

Get row number

So, 0 for the first row 1 for second and so on. For each page, we will get exactly 0-9 records or less as the page size is 10.

  1. As row numbers start from 0, we will increment it by 1.
if(pageIndex === 1){
        srNo = index + 1;

// srNo = 0 + 1 -> 1
// srNo = 1 + 1 -> 2
  1. From the second page onwards when row number is 9, the serial number should be 20, 30, 40

Row number | Serial number 0 11 1 12 2 13 . . . . . . 9 20

So we will just put pageIndex with 0

          srNo = `${pageIndex}0`; 
// srNo = 20
// srNo = 30
// srNo = 40
  1. And finally for the rest of the serial numbers after the first page would be srNo = `${pageIndex - 1}${index + 1}`;

For. e.g.:

srNo = `${2 - 1}${0 + 1}`; 11

Upvotes: 0

WarrenU
WarrenU

Reputation: 106

{
    Header: "",
    id: "row",
    maxWidth: 50,
    filterable: false,
    Cell: (row) => {
        return <div>{row.index}</div>;
    }
},

Upvotes: 8

Related Questions