Search code examples
reactjsfunctiondrop-down-menuantdreact-props

Passing properties to Dropdown menu from table row in Antd + React + Inertia + Laravel


So my setup is standard Laravel (v10) + Inertia + React + Antd (v5)

I have a table - with a Dropdown menu in each row.

enter image description here

Here are the relevant section from my TaskTable Component

import { Table, Dropdown, Menu, Button, Space  } from 'antd';
import { CloseOutlined, DownOutlined, CheckOutlined, PlusOutlined, EditOutlined} from '@ant-design/icons';

const TaskTable = ({tasks}) => {
var tasklist = {tasks};

let treeData = createDataTree(tasklist.tasks); 
//Creates treedata from laravel controller returned data

const handleCreateChildTask = (record) => {
        // param is the argument you passed to the function --> key or parent_id
        // e is the event object that returned
        console.log(" creating child on " + record);
      };

/** Other handlers removed for brevity **/

const items = [{
      label: 'Add Child ',
      key: '1',
      onClick: handleCreateChildTask,
      icon: <PlusOutlined />,
    },
    {
      label: 'Close Task ',
      key: '2',
      onClick: handleCloseTask,
      icon: <CloseOutlined />,
    },
    {
      label: 'Complete Task ',
      key: '2',
      onClick: handleCompleteTask,
      icon: <CheckOutlined/>,
    },
    {
      label: 'Edit Task ',
      key: '2',
      onClick: handleEditTask ,
      icon: <EditOutlined />,
    }];

const columns1 = useMemo(
        () => [
          {
            title: 'Desc',
            dataIndex: 'title',
            key: 'title',
          },
          { title: 'Priority', dataIndex: 'priority', key: 'priority' },
          { title: 'Status', dataIndex: 'status', key: 'status' },
          {
            title: 'Add',
            dataIndex: '',
            key: 'add',
            render: () => <a>Add a child</a>,
            
          },
          {
            title: 'Actions',
            dataIndex: '',
            key: 'action',
            render: (record) => <Dropdown
            menu= {{
              items,
            }}
          >
            <a onClick={(e) => e.preventDefault()}>
              <Space>
                Hover me
                <DownOutlined />
              </Space>
            </a>
          </Dropdown>,
            
          },
          {
            title: 'Remove',
            dataIndex: '',
            key: 'remove',
            render: () => <a>Remove the node</a>,
          },
        ],
        []
    );

        

    return (
        <Table
          pagination={false}
          columns={columns1}
          dataSource={treeData}
          rowKey="id"
          
        />
    );      

    }

I am not able to get the value of the record in the "Add Child" handler - handleCreateChildTask.

I am pretty new to React and JS, any pointers are helpful.


Solution

  • You do not need to assign each item onClick function. Use <Menu> component onClick function. Once you select any item, it will return you the key of that item (Assign unique key to each item in items list). Now based on key, you can call appropriate function. Now you also have access to record for that particular cell. You can check the Dropdown & Menu component API to check all props that you can pass to Dropdown or follow antd dropdown examples.

    Here's the complete code.

    import { useMemo } from 'react';
    import { Table, Dropdown, Space } from 'antd';
    import { CloseOutlined, DownOutlined, CheckOutlined, PlusOutlined, EditOutlined } from '@ant-design/icons';
    
    const tasks = [
        { id: 1, title: 'Task 1', priority: 'High', status: 'Open', parent_id: null },
        { id: 2, title: 'Task 2', priority: 'Low', status: 'Close', parent_id: null }
    ];
    
    const items = [
        { label: 'Add Child ', key: '1', icon: <PlusOutlined /> },
        { label: 'Close Task ', key: '2', icon: <CloseOutlined /> },
        { label: 'Complete Task ', key: '3', icon: <CheckOutlined /> },
        { label: 'Edit Task ', key: '4', icon: <EditOutlined /> }
    ];
    
    const TaskTable = () => {
        const handleCreateChildTask = (record) => {
            console.log('record', record);
        };
    
        const columns1 = useMemo(
            () => [
                { title: 'Desc', dataIndex: 'title', key: 'title' },
                { title: 'Priority', dataIndex: 'priority', key: 'priority' },
                { title: 'Status', dataIndex: 'status', key: 'status' },
                { title: 'Add', dataIndex: '', key: 'add', render: () => <a>Add a child</a> },
                {
                    title: 'Actions',
                    dataIndex: '',
                    key: 'action',
                    render: (record) => (
                        <Dropdown
                            menu={{
                                items,
                                onClick: ({ key }) => {
                                    if (key === '1') handleCreateChildTask(record);
                                    // else if (key === '2')handleCloseTask
                                }
                            }}
                        >
                            <a onClick={(e) => e.preventDefault()}>
                                <Space>
                                    Hover me
                                    <DownOutlined />
                                </Space>
                            </a>
                        </Dropdown>
                    )
                },
                {
                    title: 'Remove',
                    dataIndex: '',
                    key: 'remove',
                    render: () => <a>Remove the node</a>
                }
            ],
            []
        );
    
        return <Table pagination={false} columns={columns1} dataSource={tasks} rowKey='id' />;
    };
    
    export default TaskTable;