I am using Antd table here, I successfully populated one of the title
vertically and I want to populate the other one horizontally, refer to the images for clarification.
Here is my table column:
const columns = [
{
title: 'Days',
dataIndex: 'date',
defaultSorter: 'ascend',
key: 'title',
sorter: (a, b) => a.date.localeCompare(b.date),
sortDirections: ['descend', 'ascend'],
render: (date) => getDayName(new Date(date)),
},
{
title: 'period',
dataIndex: 'period',
},
}
Datasource or data from api:
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [query, setQuery] = useState('');
const fetchData = async () => {
setLoading(true);
const { data } = await getTimetable();
setData(data);
setLoading(false);
};
useEffect(() => {
fetchData();
}, []);
Rendering table data:
<TableContainer columns={columns} rowKey={(record) => record.login.uuid} dataSource={data} />
What I want to achieve:
What I have right now:
In antd
Table, columns need to passed as below format.
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
// .... rest of the cols
];
So to create dynamic columns from the response data you get here, 1st you need to create the array of objects (cols) as the above format that need to pass for <Table columns={formattedColsfromResponseData}
.
So in your case you need to create columns[] like below format.
let cols = [
{
title: "Days",
dataIndex: "date",
defaultSorter: "ascend",
key: "title",
sorter: (a, b) => a.date.localeCompare(b.date),
sortDirections: ["descend", "ascend"]
render: (date) => getDayName(new Date(date)),
},
{
title: "period 1"
key: "period 1"
render: (row) => row.section + " - " + row.subject; // render function for customized data.
},
{
title: "period 2"
key: "period 2"
render: (row) => row.section + " - " + row.subject; // render function for customized data
},
// .... rest of the 'Period n' cols in the response.
];
With the below method you can create cols as required format by passing the response data.
This method works assuming response data has only unique 'Periods'.
const generateColumns = (data) => {
let cols = [];
const days = {
title: "Days",
dataIndex: "date",
defaultSorter: "ascend",
key: "title",
sorter: (a, b) => a.date.localeCompare(b.date),
sortDirections: ["descend", "ascend"]
render: (date) => getDayName(new Date(date)),
};
cols.push(days); // add 'Days' obj to Columns.
// for render: property in cols need to return a function. Here creates that.
const generateRender = (row) => {
console.log("gen row----", row);
return (row) => row.section + " - " + row.subject;
};
// create the col objects for each 'Period'. This method works assuming response data has only unique 'Periods'.
data.map((row) => {
let period = {}; // for create 'Period' obj for cols.
period["title"] = row.period;
period["key"] = row.period;
period["render"] = generateRender(row); // only need this if you render customized data.
cols.push(period); // add Current Period obj to Columns.
});
return cols;
};
Now you can pass this method to columns
prop in Table
with response data which returns the dynamic cols.
const App = () => (
<div>
<Table columns={generateColumns(data)} dataSource={data} />
</div>
);
Check this full demo antd-dynamic-cols-example code.