Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add thead row to Antd table component

Tags:

reactjs

antd

I would like to add another row in Antd table component, so it will look like this:

enter image description here

I cannot add the row as a <tbody> row since it will get filtered and sorted with the rest of the data. I would like it to be an external part of the table's data.

Placing the inputs within the already existing <th> cells is far from a satisfying solution because I would need to hack the CSS quite a lot to make it work, and loose some LESS variables along the way.

This is my current try, with form elements inside the first thead > th

enter image description here

To keep the background on the form row only, I would need to have it separated from the first (and only) thead's <tr> element to it's own "custom" row.

Does anyone have an idea how implement this design with Antd <Table> ?


I would like the end-result to look like this: (modified via inspector)

enter image description here

like image 240
vsync Avatar asked Nov 07 '22 16:11

vsync


1 Answers

First Solution

A wrapper component which manages the state of two Tables:

  1. The input table with a single row.
  2. The data table without a header.
function TableWrapper() {
  ...
  return (
    <Flexbox>
      <Table
        size="medium"
        rowSelection={rowSelection}
        columns={columnsInput}
        dataSource={[{}]}
        pagination={false}
      />
      <Table
        size="medium"
        showHeader={false}
        rowSelection={rowSelection}
        columns={columns}
        dataSource={dataSource}
      />
      <Button onClick={handleAdd} type="primary" style={{ margin: '3%' }}>
        Add a row
      </Button>
    </Flexbox>
  );
}

enter image description here

The sorting done by the wrapper, you need at least two items so sort can be called: dataSource={[{},{}]}

// columnsInput
    {
      title: 'Age',
      dataIndex: 'age',
      render: () => <Input />,
      sort: () => // setDataSource...
    }

Second solution

In dataSource value which supplied to Table, add a front mock item and then render row accordingly, for example:

const initial = {
  key: 'initial',
  name: 'initial',
  age: 'initial',
  address: 'initial'
};

Then in row rendering:

const columns = [
  {
    title: 'Name',
    dataIndex: 'name',
    render: value => (value === 'initial' ? <Input /> : value)
  },
  {
    title: 'Age',
    dataIndex: 'age',
    render: value => (value === 'initial' ? <Input /> : value),
    sorter: (a, b) => a.age - b.age
  },
  {
    title: 'Address',
    dataIndex: 'address',
    render: value => (value === 'initial' ? <Input /> : value)
  },
  {
    title: '',
    dataIndex: 'action',
    width: '50px',
    render: (_, record) => (
      <>
        {record.name === 'initial' && <Button icon="plus" shape="circle" />}
        {record.name !== 'initial' && (
          <Button icon="delete" shape="circle" type="danger" />
        )}
      </>
    )
  }
];

Will result:

![enter image description here

in the next component:

function TweakedTable() {
  const [dataSource, setDataSource] = useState([makeRow(0)]);
  const [counter, setCounter] = useState(1);
  const handleAdd = () => {
    setDataSource([...dataSource, makeRow(counter)]);
    setCounter(prev => prev + 1);
  };
  return (
    <Flexbox>
      <Table
        size="small"
        rowSelection={rowSelection}
        columns={columns}
        dataSource={[initial, ...dataSource]}
      />
      <Button onClick={handleAdd} type="primary" style={{ margin: '3%' }}>
        Add a row
      </Button>
    </Flexbox>
  );
}

No overhead for sorting, just add a sorter in table columns.

Moreover your dataSource is decoupled from the first row.

Edit SO-56619026-TableHeader

Note: I didn't make any state management in the demo, I'm sure you will be able to handle it, also if you want to remove the disabled Checkbox you should not use rowSelection={rowSelection} and render Checkbox on every row and manage them by yourself.

like image 76
Dennis Vash Avatar answered Nov 11 '22 08:11

Dennis Vash