How to use rowspan in react-table
Asked Answered
K

1

7

Any idea how to use rowSpan in react table. for below example usernameFormatter there are multiple values. Note: attach picture is copied but that's looks like what I wanted

const columns = [
     {
         accessor: "id",
         show: false,
     },
     {
        Header: "Username",
        id: "username",
        accessor: "username",
        Cell: this.usernameFormatter,
        enableRowSpan: true
     }
]
          
<ReactTable
    data={this.state.users}
    filterable={true}
    columns={columns}
    defaultPageSize={18}
    getTdProps={(state, rowInfo, column) => {
        const index = rowInfo ? rowInfo.index : -1;
        return {
            onClick: (e, handleOriginal) => {
                if (column.Header === undefined) {
                    handleOriginal();
                } else {
                    if (rowInfo !== undefined) {
                        this.selectedRow = index;
                        this.onRowSelect(rowInfo.original.id);
                    }
                }
            },
        };
    }}
/>
                

enter image description here

Kurth answered 10/11, 2020 at 21:10 Comment(1)
Does this answer your question? HTML table rowspan in reactjsRadiotelephony
S
0

Please check this demo

Idea is array of data set, We are going to render inside table should know, what are the cells going to use row span. This case, individual person has category and that and "categorySpan"

const defaultData: Person[] = [
  {
    category:"category one",
    categorySpan:4,
    firstName: 'tanner',
    lastName: 'linsley',
    age: 24,
    visits: 100,
    status: 'In Relationship',
    progress: 50,
  },
  {
    category:"category one",
    firstName: 'tandy',
    lastName: 'miller',
    age: 40,
    visits: 40,
    status: 'Single',
    progress: 80,
  },
  {
    category:"category one",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category one",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category two",
    categorySpan:2,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category two",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category three",
    categorySpan:1,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category four",
    categorySpan:1,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  
] 

So you can add row span property to td base on category and category span

    <tr key={row.id}>
      {row.getVisibleCells().map(cell => {
        if(cell.column.id=="category"){
          if(row.original.categorySpan){
          return (  <td key={cell.id} rowSpan={row.original.categorySpan}>
            {flexRender(cell.column.columnDef.cell, cell.getContext())}
          </td>);
          }
        }
        else{
          return (
            <td key={cell.id}>
              {flexRender(cell.column.columnDef.cell, cell.getContext())}
            </td>
          )
        }
      })}
    </tr>

Final code will be like this

import * as React from 'react'
import ReactDOM from 'react-dom/client'

import './index.css'

import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  useReactTable,
} from '@tanstack/react-table'

type Person = {
  category:string
  categorySpan?:number
  firstName: string
  lastName: string
  age: number
  visits: number
  status: string
  progress: number
}

const defaultData: Person[] = [
  {
    category:"category one",
    categorySpan:4,
    firstName: 'tanner',
    lastName: 'linsley',
    age: 24,
    visits: 100,
    status: 'In Relationship',
    progress: 50,
  },
  {
    category:"category one",
    firstName: 'tandy',
    lastName: 'miller',
    age: 40,
    visits: 40,
    status: 'Single',
    progress: 80,
  },
  {
    category:"category one",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category one",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category two",
    categorySpan:2,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category two",
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category three",
    categorySpan:1,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  ,
  {
    category:"category four",
    categorySpan:1,
    firstName: 'joe',
    lastName: 'dirte',
    age: 45,
    visits: 20,
    status: 'Complicated',
    progress: 10,
  }
  
]

const columnHelper = createColumnHelper<Person>()

const columns = [
  columnHelper.accessor('category', {
    cell: info => info.getValue(),
    footer: info => info.column.id,
  }),
  columnHelper.accessor('firstName', {
    cell: info => info.getValue(),
    footer: info => info.column.id,
  }),
  columnHelper.accessor(row => row.lastName, {
    id: 'lastName',
    cell: info => <i>{info.getValue()}</i>,
    header: () => <span>Last Name</span>,
    footer: info => info.column.id,
  }),
  columnHelper.accessor('age', {
    header: () => 'Age',
    cell: info => info.renderValue(),
    footer: info => info.column.id,
  }),
  columnHelper.accessor('visits', {
    header: () => <span>Visits</span>,
    footer: info => info.column.id,
  }),
  columnHelper.accessor('status', {
    header: 'Status',
    footer: info => info.column.id,
  }),
  columnHelper.accessor('progress', {
    header: 'Profile Progress',
    footer: info => info.column.id,
  }),
]

function App() {
  const [data, setData] = React.useState(() => [...defaultData])
  const rerender = React.useReducer(() => ({}), {})[1]

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  })

  return (
    <div className="p-2">
      <table>
        <thead>
          {table.getHeaderGroups().map(headerGroup => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map(header => (
                <th key={header.id}>
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext()
                      )}
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map(row => (
            <tr key={row.id}>
              {row.getVisibleCells().map(cell => {
                if(cell.column.id=="category"){
                  if(row.original.categorySpan){
                  return (  <td key={cell.id} rowSpan={row.original.categorySpan}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </td>);
                  }
                }
                else{
                  return (
                    <td key={cell.id}>
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </td>
                  )
                }
              })}
            </tr>
          ))}
        </tbody>
      </table>
      <div className="h-4" />
      <button onClick={() => rerender()} className="border p-2">
        Rerender
      </button>
    </div>
  )
}

const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)
Sematic answered 13/12, 2023 at 4:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.