Creating React antd table with sorting and pagination and using antd select and antd modal for filtering and displaying the data.

Follow on LinkedIn

In this article we are creating an antd table with React antd library, antd library is an ant design library, which has a rich set of components for designing. In this article, we are using the antd table, antd select, antd checkbox, and antd modal to create a table with sorting, filtering of data, and a pagination feature.

Let’s first see the look of the design we are going to build and then I will explain to you how you can create the same.

If you unselect one of the checkboxes then that filed column will disappear from the table.

We are using the antd modal also to display all the information that the object of this JSON data has, if you click on any name of the list, then a modal window will open and that will display all the information related to the name you clicked.

We have pagination and sorting as well and one antd select to display several records according to the selected value.

Now for all these features, I have created a single file that you can use in your React project.

Let’s check this file code step by step and understand the functionality.

import './App.css';
import React, { useState } from 'react';
import { Table, Checkbox, Select, Modal } from 'antd';

const { Option } = Select;

function App() {
  const dataSource = [
    { key: '1', name: 'John', age: 25, address: 'New York', occupation: 'Engineer', hobby: 'Reading' },
    { key: '2', name: 'Jane', age: 30, address: 'London', occupation: 'Doctor', hobby: 'Traveling' },
    { key: '3', name: 'Michael', age: 28, address: 'Los Angeles', occupation: 'Artist', hobby: 'Painting' },
    { key: '4', name: 'Emily', age: 27, address: 'Paris', occupation: 'Chef', hobby: 'Cooking' },
    { key: '5', name: 'William', age: 32, address: 'Tokyo', occupation: 'Teacher', hobby: 'Teaching' },
    { key: '6', name: 'Sophia', age: 29, address: 'Sydney', occupation: 'Writer', hobby: 'Writing' },
    { key: '7', name: 'James', age: 33, address: 'Toronto', occupation: 'Pilot', hobby: 'Flying' },
    { key: '8', name: 'Olivia', age: 26, address: 'Berlin', occupation: 'Lawyer', hobby: 'Law' },
    { key: '9', name: 'Alexander', age: 31, address: 'Rome', occupation: 'Doctor', hobby: 'Swimming' },
    { key: '10', name: 'Emma', age: 24, address: 'Barcelona', occupation: 'Engineer', hobby: 'Photography' },
    { key: '11', name: 'Liam', age: 35, address: 'Dubai', occupation: 'Doctor', hobby: 'Traveling' },
    { key: '12', name: 'Ava', age: 23, address: 'Moscow', occupation: 'Artist', hobby: 'Drawing' },
    { key: '13', name: 'Noah', age: 34, address: 'Seoul', occupation: 'Scientist', hobby: 'Research' },
    { key: '14', name: 'Isabella', age: 30, address: 'Singapore', occupation: 'Chef', hobby: 'Cooking' },
  ];

  const [columns, setColumns] = useState([
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      sorter: (a, b) => a.name.localeCompare(b.name),
      render: (text) => <span className="clickable-name" onClick={() => handleNameClick(text)}>{text}</span>,
    },
    {
      title: 'Age',
      dataIndex: 'age',
      key: 'age',
      sorter: (a, b) => a.age - b.age,
    },
    {
      title: 'Address',
      dataIndex: 'address',
      key: 'address',
      sorter: (a, b) => a.address.localeCompare(b.address),
    },
  ]);
  const [selectedColumns, setSelectedColumns] = useState(columns.map((column) => column.key));
  // State variable for number of records to show
  const [pageSize, setPageSize] = useState(5); 
   // State variable for selected name details
  const [selectedNameDetails, setSelectedNameDetails] = useState(null);
  // State variable to control modal visibility
  const [isModalVisible, setIsModalVisible] = useState(false); 

  const handleColumnCheckboxChange = (checkedColumns) => {
    setSelectedColumns(checkedColumns);
  };

  const handlePageSizeChange = (value) => {
    setPageSize(value);
  };

  const handleNameClick = (name) => {
    // Find the details of the clicked name from the dataSource
    const details = dataSource.find((item) => item.name === name);
    setSelectedNameDetails(details);
    setIsModalVisible(true);
  };

  const handleModalClose = () => {
    setIsModalVisible(false);
  };

  const tableConfig = {
    // Exclude extra fields from the table
    dataSource: dataSource.map(({ occupation, hobby, ...rest }) => rest), 
    columns: columns.filter((column) => selectedColumns.includes(column.key)),
    // Use the pageSize state variable here
    pagination: { pageSize }, 
    onChange: (pagination, filters, sorter) => {
      // Handle sorting and filtering here if needed
    },
  };

  return (
    <div className="App">
      <div style={{ marginBottom: 16 }}>
        <span style={{ marginRight: 8 }}>Show Columns:</span>
        {columns.map((column) => (
          <Checkbox
            key={column.key}
            checked={selectedColumns.includes(column.key)}
            onChange={(e) => {
              const checkedColumns = e.target.checked
                ? [...selectedColumns, column.key]
                : selectedColumns.filter((key) => key !== column.key);
              handleColumnCheckboxChange(checkedColumns);
            }}
          >
            {column.title}
          </Checkbox>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
        <span style={{ marginRight: 8 }}>Show Records:</span>
        <Select defaultValue={pageSize} onChange={handlePageSizeChange} style={{ width: 100 }}>
          <Option value={5}>5</Option>
          <Option value={10}>10</Option>
          <Option value={20}>20</Option>
        </Select>
      </div>
      <Table
        {...tableConfig}
        onRow={(record) => ({
          onClick: () => handleNameClick(record.name),
        })}
      />
      <Modal
        title="Name Details"
        visible={isModalVisible}
        onCancel={handleModalClose}
        footer={null}
      >
        {selectedNameDetails && (
          <div>
            <p>Name: {selectedNameDetails.name}</p>
            <p>Age: {selectedNameDetails.age}</p>
            <p>Address: {selectedNameDetails.address}</p>
            {/* Additional fields */}
            <p>Occupation: {selectedNameDetails.occupation}</p>
            <p>Hobby: {selectedNameDetails.hobby}</p>
          </div>
        )}
      </Modal>
    </div>
  );
}
export default App;

Above, you can see the file that has all the code for the running project. now let’s understand how it is working.

React antd Table, antd Select, and antd Modal

First of all, we need to import the required libraries and files.

import './App.css';
// Import useState hook from React Library
import React, { useState } from 'react'; 
// Importing components from the antd library for table,checkbox,select and modal
import { Table, Checkbox, Select, Modal } from 'antd';
//using destructuring to get option component from select component
const { Option } = Select; 

We need some data to display inside the table, for this, we are creating a variable dataSource and giving it some random values.

const dataSource = [

  // Each object has properties like 'key', 'name', 'age', 'address', 'occupation', 'hobby'

  { key: '1', name: 'John', age: 25, address: 'New York', occupation: 'Engineer', hobby: 'Reading' },
  // ... other data objects ...
];

Now, we need to define all the useState variables, that are performing the actual operations and configurations.

// State variable for the table columns configuration
const [columns, setColumns] = useState([]);
// State variable for the checkboxes to show selected columns
const [selectedColumns, setSelectedColumns] = useState([]);
// State variable for our select options to display no of records per page
const [pageSize, setPageSize] = useState(5);
// State variable for storing
const [selectedNameDetails, setSelectedNameDetails] = useState(null);
// State variable to hide and show the modal
const [isModalVisible, setIsModalVisible] = useState(false);

Now, Let’s understand our event handler functions. These functions are executed when a specific event is occurring related to these functions.


const handleColumnCheckboxChange = (checkedColumns) => {
  setSelectedColumns(checkedColumns);
};
const handlePageSizeChange = (value) => {
  setPageSize(value);
};
const handleNameClick = (name) => {
  const details = dataSource.find((item) => item.name === name);
  setSelectedNameDetails(details);
  setIsModalVisible(true); // Open the modal to show the details
};
const handleModalClose = () => {
  setIsModalVisible(false);
};

The handleColumnCheckboxChange handles the event of the checkbox toggle event, it passed the value to setSelectedColumns, and then the associated column is displayed.

handlePageSizeChange handler for when the page size dropdown is changed, handleNameClick is the event handler for when a name in the Table is clicked and handleModalClose is the event handler for when the modal is closed.

Now, configure our table to operate according to these event changes.

const tableConfig = {
  // Exclude extra fields (occupation and hobby) from the table's data source
  dataSource: dataSource.map(({ occupation, hobby, ...rest }) => rest),
  // Use the columns selected by the user to display in the Table
  columns: columns.filter((column) => selectedColumns.includes(column.key)),
  // Use the pageSize state variable to control the number of records per page
  pagination: { pageSize },
  // onChange is a callback function called when the Table's pagination, sorting, or filtering is changed
  onChange: (pagination, filters, sorter) => {
    // This is where you can handle sorting and filtering if needed (not implemented in this code)
  },
};

After all this, our JSX code will come, and that is actually very simple, it has an antd table, antd modal, and antd select component.

This React table component is getting a variable called tableConfig, which is basically a configuration variable that we defined above, On each row we are calling a handleNameClick function and passing the name of the record on which we are clicking and it will get all the information related to this name from the data source variable and it will display the information inside the modal component.

Antd Table

 <Table
      {...tableConfig}
      onRow={(record) => ({
        onClick: () => handleNameClick(record.name),
      })}
    />

antd select and antd modal code are quite simple to understand by just looking into the code you can get an idea of what these components are doing.

The below modal is just displaying the information

Antd Modal

<Modal
      title="Name Details"
      visible={isModalVisible}
      onCancel={handleModalClose}
      footer={null}
    >
      {selectedNameDetails && (
        <div>
          <p>Name: {selectedNameDetails.name}</p>
          <p>Age: {selectedNameDetails.age}</p>
          <p>Address: {selectedNameDetails.address}</p>
          {/* Additional fields */}
          <p>Occupation: {selectedNameDetails.occupation}</p>
          <p>Hobby: {selectedNameDetails.hobby}</p>
        </div>
      )}
    </Modal>

Similar way, Select is just passing the selected value to the handlePageSizeChange method on an onChange event.

Antd Select

 <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
      <span style={{ marginRight: 8 }}>Show Records:</span>
      <Select defaultValue={pageSize} onChange={handlePageSizeChange} style={{ width: 100 }}>
        <Option value={5}>5</Option>
        <Option value={10}>10</Option>
        <Option value={20}>20</Option>
      </Select>
    </div>

That’s it for this article, I hope it’s helpful. Happy Coding 🙂

Related Posts

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

×