currently creating my datatable using grid.js in reactjs.
This is my code
<Grid
data={data.filter(e => e.status != 0)}
columns={[
{
id: 'url',
name: 'url',
hidden: true
}, {
id: 'id',
name: '#',
formatter: (cell) => _(this.showIndexNo()) //<-- where i do the function to display row index number
}, {
id: 'name',
name: 'Name'
}, {
id: 'smgk_name',
name: 'SM Name',
formatter: (cell, row) => _(this.showSmlink(row.cells[0].data, row.cells[3].data))
}, {
id: 'email',
name: 'Email',
// formatter: (cell) => _(moment(cell).format(MOMENT_FORMAT))
},
{
id: 'id',
name: 'Actions',
formatter: (cell) => _(this.showButton(cell))
//(cell) => `Name: ${cell}`
}
]}
search={true}
sort={true}
/>
I want to display the row index/ auto increment in my grid js.
How should i edit this code?
showIndexNo() {
const { subscriberData } = this.state;
let a = [];
return (subscriberData.filter(e => e.status != 0).map((item, i) => i ) ) }
and I get this result:
I cannot use ID as the row Index as when I delete one details the Id will still be there only status will changed to deleted(this wont be displayed in grid), so I need row Index. Really appreciate any help
return (subscriberData.filter(e => e.status != 0).map((item, i) =>
return { ...item,
rowIndex: i //use rowIndex as column
}))
}
Related
I want to add a new row at the end of rc-table to show total of column value.
const columns = [
{
title: "Name",
className: "cursor-pointer",
dataIndex: "name",
key: "name",
Footer: "Total",
align: alignLeft,
// onHeaderCell: () => onHeaderClick('name'),
render: (name: any) => <span className="whitespace-nowrap">{name}</span>,
},
];
try this:
const columns = [
{
title: "Name",
className: "cursor-pointer",
dataIndex: "name",
key: "name",
align: alignLeft,
render: (name: any) => <span className="whitespace-nowrap">{name}</span>,
footer: (data: any) => {
let total = 0;
data.forEach((item: any) => {
total += item.name;
});
return <div>{`Total: ${total}`}</div>;
},
},
];
I have an Ant Design table component with a checkbox to check the selected values. Now I want to pass a default state that would check the selected values that was being checked already whenever the table was closed since I put it in the modal. I want to achieve an Ant Design table that would check and save the checked values from my state for further usage.
Here is my Full code:
const rowSelection = {
selections: [
Table.SELECTION_NONE,
],
getCheckboxProps: (record) => ({
id: record.id,
}),
};
const columns = [
{
title: "Document ID",
dataIndex: "id",
key: "id",
defaultSortOrder: "descend",
sorter: (a, b) => a.id - b.id,
},
{
title: "Subject",
dataIndex: "subject",
key: "subject",
width: "25%",
sorter: (a, b) => a.subject.length - b.subject.length,
sortDirections: ["descend", "ascend"],
},
{
title: "Title",
dataIndex: "title",
key: "title",
width: "25%",
sorter: (a, b) => a.title.length - b.title.length,
sortDirections: ["descend", "ascend"],
},
{
title: "Document Type",
dataIndex: "doc_type",
key: "doc_type",
render: (text, record) =>
record.doc_type && record.doc_type.name ? record.doc_type.name : null,
},
{
title: "File Type",
dataIndex: "file_type",
key: "file_type",
render: (text, record) =>
record.file_type && record.file_type.name
? record.file_type.name
: null,
},
{
title: "Public",
dataIndex: "is_public",
key: "is_public",
align: "center",
render: (text, record) =>
record.ispublic ? (
<CheckCircleFilled style={{ color: "#28a745" }} />
) : (
<CloseCircleFilled style={{ color: "#dc3545" }} />
),
},
{
title: "Date Created",
dataIndex: "created_at",
key: "created_at",
render: (text, record) => dateFormatter(new Date(record.created_at)),
},
];
const dateFormatter = (date) => {
const dd = (date.getDate() < 10 ? "0" : "") + date.getDate();
const MM = (date.getMonth() + 1 < 10 ? "0" : "") + (date.getMonth() + 1);
const yyyy = date.getFullYear();
// create the format you want
// return (yyyy + "/" + MM + "/" + dd);
return MM + "/" + dd + "/" + yyyy;
};
const [selectAlready, setSelectAlready] = useState([]);
useEffect(() => {
if(attachmentLists && attachmentLists.length != 0) {
const documentIds = map(attachmentLists,'id');
if(documentIds.length != 0) {
setAlreadySelectedRows(documentIds);
}
}
}, [attachmentLists])
<Table
rowKey={(record) => record.id}
rowSelection={{
type: "checkbox",
selectedRowKeys: selectAlready,
onChange: (keys, selectedRowKeys, selectedRows) => {
setSelectAlready(keys);
setSelectedDocuments(selectedRowKeys);
},
preserveSelectedRowKeys: true,
...rowSelection,
}}
columns={columns}
dataSource={data}
pagination={{
pageSize: 10,
showSizeChanger: false,
total: pageTotalSize,
position: ["bottomLeft"],
}}
loading={loading}
onChange={(pagination, filters, sorter) => handleTableChange(pagination)}
/>;
Now my problem is, whenever the useEffect alreadySelectedRows was populate, it will select selectedRowKeys the rows that was being selected already based on the provided ID's, but when I go switch to another page, the data will return some undefined values and will not catch the other values that was already being selected. The main problem is selectedRowKeys returns undefined from previous page table in array.
I am using antd to create a table with filter feature,
but I got a problem, I want to custom filter search of antd to call api,
antd table
How can I do that with react and antd,
Here is my code
const columns: ColumnsType<Product> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: (name, record) => (
<div className="flex items-center">
<Avatar src={record.avatar}>{name[0].toUpperCase()}</Avatar>
<span style={{ marginLeft: 10 }} className="whitespace-nowrap">
<a title="View & Edit" href={'/product/' + record.id}>
{name}
</a>
</span>
</div>
),
},
{
title: 'About',
dataIndex: 'about',
key: 'about',
render: (about: string) => <p className="text-ellipsis line-clamp-2">{about}</p>,
width: 400,
},
{
title: 'Categories',
dataIndex: 'categories',
key: 'categories',
filterSearch: true,
filters: categories!.map((category: Category) => ({ text: category.name, value: category.id })),
render: (categories: any) => {
console.log(categories);
return '-';
},
// width: 400,
},
{ title: 'Addresses', dataIndex: 'contract_addresses', key: 'address', render: addresses => addresses?.[0] },
];
To filter the table, I usually provide a function that filters the data before it is passed to the table (In my example the function getData. This function can also be used to adjust the filter accordingly. Here is an example, which also consists of a Search-Input to modify the search:
const CustomersTable = (props: any) => {
const [searchText, setSearchText] = useState<string | undefined>(undefined);
const [customers, setCustomers] = useState<ICustomer[]>([]);
const getData = (
sourceData: Array<ICustomer>,
searchText: string | undefined
) => {
if (!searchText) {
return sourceData;
}
return sourceData.filter((item) => {
const comparisonString = `${item.firstname.toLowerCase()}${item.familyname.toLowerCase()}`;
//here you can provide a more sophisticared search
return comparisonString.includes(searchText.toLowerCase());
});
};
const columns = [
{
title: "Vorname",
dataIndex: "firstname",
key: "firstname",
sorter: (a: ICustomer, b: ICustomer) => {
if (a.firstname.toLowerCase() > b.firstname.toLowerCase()) {
return -1;
} else if (a.firstname.toLowerCase() < b.firstname.toLowerCase()) {
return 1;
} else {
return 0;
}
},
},
{
title: "Nachname",
dataIndex: "familyname",
key: "familyname",
},
];
return (
<>
<Search
placeholder="Vorname, Nachname"
value={searchText}
onChange={(e) => {
setSearchText(e.target.value);
}}
/>
<Table
columns={columns}
dataSource={getData(customers, searchText)}
/>
</>
);
};
This is an example table where I am using the same remote data concept in my code, I have also tried debounce interval prop but still while typing values in the filter, it renders and text won't stay in the filtering box.
function RemoteData() {
return (
<MaterialTable
title="Remote Data Preview"
columns={[
{
title: 'Avatar',
field: 'avatar',
render: rowData => (
<img
style={{ height: 36, borderRadius: '50%' }}
src={rowData.avatar}
/>
),
},
{ title: 'Id', field: 'id' },
{ title: 'First Name', field: 'first_name' },
{ title: 'Last Name', field: 'last_name' },
]}
data={query =>
new Promise((resolve, reject) => {
let url = 'https://reqres.in/api/users?'
url += 'per_page=' + query.pageSize
url += '&page=' + (query.page + 1)
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result.data,
page: result.page - 1,
totalCount: result.total,
})
})
})
}
/>
)
}
Can someone please help me with how to make the text stay up in the filter input field itself without making it re-render?
I am using react-table to generate tables(https://react-table.js.org/#/story/readme). I have a state defined as following:
this.state = {
sampleTable:[
{author: 'Mac', books: [{title:'One', price: 20}, {title:'Two', price: 20}]},
{author: 'Rick', books: [{title:'Three', price: 20}, {title:'Four', price: 20}]}
],
sampleTableColumns:[
{Header: 'Author', accessor: 'author'},
{Header: 'Books', accessor: 'books.title'},
],
};
And I am trying to make table as following:
<ReactTable
className="-highlight"
data={this.state.sampleTable}
columns={this.state.sampleTableColumns}
defaultPageSize={10}
/>
However in the books column I see nothing. I am not sure how am I supposed to iterate over books array so that I can print say book titles in books column?
I had to write my accessor like following:
sampleTableColumns:[
{
Header: 'Author',
accessor: 'author',
},
{
Header: 'Books',
id:'books',
accessor: data => {
let output = [];
_.map(data.books, book => {
output.push(book.title);
});
return output.join(', ');
},
},
],
It's simple without using any dependencies like lodash...
You just need to use React-table Cell attribute
sampleTableColumns:[
{
Header: 'Author',
accessor: 'author',
},
{
Header: 'Books',
accessor: 'books',
Cell: (props) => {
const { sampleTable} = props.original;
return (
{ sampleTable.books.map( (book) =>(<h4>{book.title}</h4>)) }
);
},
},],
I believe Shivam Modi answered it. Using TypeScript his solution could be rendered something like (using built-in row selector):
{
Header: "Books",
accessor: "books",
Cell: ({ row }) => {
return (
row.original.books
.map((book: Book) => (
<div key={book.id}>
<h4>{book.name}</h4>
</div>
))
);
},
},
Your books data is an array and I don't believe react-table knows how to render those by default. You can instead supply your own render function in the sampleTableColumns for that cell, which would look something like:
sampleTableColumns:[
{Header: 'Author', accessor: 'author'},
{
Header: 'Books',
accessor: 'books'
render: (rowInfo) => {
return (
<span>
{rowInfo.value.map(book => (<span>{book.title}</span>))}
</span>
},
},
],
Well, I am too late for the party but all above doesn't work for me and I tried to use ES6 syntax. I have requested data in array, so here we go (I renamed variables):
export const returnPreparedField = (array) => {
const newArray = [];
for (let arrayValue of array) {
const newElement = {
id: "element",
header: element,
accessor: data => data.element.find(elementToFind => (elementToFind.name === element))?.value,
show: true,
width: 100
};
newArray.push(newElement);
}
return newArray;
};