英文:
Modifying React Data Table Extension Component
问题
我想修改 react 数据表格扩展组件,添加以下功能,但我卡住了,无法修改它。
1. 将自动筛选更改为基于事件的筛选,设置为按钮 onClick
2. 将默认搜索图标更改为 bootstrap 按钮
3. 使用导出和打印按钮(当前根据文档将... 数据设置为数据表格扩展,但只显示数据表中的数据,我无法使用打印和导出功能)。
我目前正在使用 react 18
我尝试将数据放入 react 数据表格组件中,这样做时,打印和导出功能可以正常工作,但数据表中不显示任何数据。
我的代码如下:
```jsx
import DataTable from "react-data-table-component";
import { tableCustomStyles } from "../../utils/CommonFunctions";
import DataTableExtensions from "react-data-table-component-extensions";
export default function UsersPage() {
const dataTableColumns = [
{
name: "#",
selector: (row, index) => `${index + 1}`,
sortable: false,
width: "50px",
},
{
name: "姓氏",
selector: (row) => row.lastName,
sortable: true,
width: "150px",
},
{
name: "名字",
selector: (row) => row.firstName,
sortable: true,
width: "150px",
},
{
name: "角色",
selector: (row) => row?.roles?.map((role) => role?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "部门",
selector: (row) =>
row?.departments?.map((department) => department?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "位置",
selector: (row) =>
row?.locations?.map((location) => location?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "状态",
selector: (row) => row?.status,
sortable: true,
width: "100px",
},
{
name: "选项",
cell: (row) => (
<>
<Dropdown>
<Dropdown.Toggle variant='link' id='dropdown-basic'>
<VerticalDots style={{ height: 20 }} />
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={() => handleViewFullProfile(row)}>
查看完整档案
</Dropdown.Item>
<Dropdown.Item onClick={() => handleResetPassword(row)}>
重置密码
</Dropdown.Item>
<Dropdown.Item onClick={() => handleUserStatus(row)}>
{row.status === "Active" ? "停用" : "启用"} 用户
</Dropdown.Item>
<Dropdown.Item onClick={() => handleOptionClick(row)}>
其他选项
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
),
ignoreRowClick: true,
allowOverflow: true,
button: true,
sortable: false,
width: "100px",
},
];
const tableData = {
columns: dataTableColumns,
data: users,
};
return (
<div>
<a
className='btn btn-primary'
to='/admin/administer/new-user'
onClick={handleNavigation}
>
+ 添加用户
</a>
<DataTableExtensions
{...tableData}
export={true}
print={true}
extensions={extensions}
>
<DataTable
// columns={dataTableColumns}
// data={users}
noHeader
defaultSortField='lastName'
defaultSortAsc={false}
customStyles={tableCustomStyles}
pagination
responsive='true'
highlightOnHover
/>
</DataTableExtensions>
</div>
)
}
英文:
I want to modify the react data table extension component with the below functionalities but I'm stuck and unable to modify it.
- Change auto filter to event based filter set to button onClick
- Change default search icon to bootstrap button
- Use the export and print button (currently set the ... Data to the data-table-extension as per documentation but it is only displays the data in the data table but I'm unable to use print and export functionality).
I'm currently using react 18
I have tried to put data in the react data table component, when I do so the print and export functionality works perfectly fine but no data gets display in the data table.
My code is as under:
import DataTable from "react-data-table-component";
import { tableCustomStyles } from "../../utils/CommonFunctions";
import DataTableExtensions from "react-data-table-component-extensions";
export default function UsersPage() {
const dataTableColumns = [
{
name: "#",
selector: (row, index) => `${index + 1}`,
sortable: false,
width: "50px",
},
{
name: "Last Name",
selector: (row) => row.lastName,
sortable: true,
width: "150px",
},
{
name: "First Name",
selector: (row) => row.firstName,
sortable: true,
width: "150px",
},
{
name: "Role(s)",
selector: (row) => row?.roles?.map((role) => role?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "Department(s)",
selector: (row) =>
row?.departments?.map((department) => department?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "Location(s)",
selector: (row) =>
row?.locations?.map((location) => location?.name).join(", "),
sortable: true,
width: "230px",
},
{
name: "Status",
selector: (row) => row?.status,
sortable: true,
width: "100px",
},
{
name: "Option(s)",
cell: (row) => (
<>
<Dropdown>
<Dropdown.Toggle variant='link' id='dropdown-basic'>
<VerticalDots style={{ height: 20 }} />
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={() => handleViewFullProfile(row)}>
View Full Profile
</Dropdown.Item>
<Dropdown.Item onClick={() => handleResetPassword(row)}>
Reset Password
</Dropdown.Item>
<Dropdown.Item onClick={() => handleUserStatus(row)}>
{row.status === "Active" ? "Deactivate" : "Activate"} User
</Dropdown.Item>
<Dropdown.Item onClick={() => handleOptionClick(row)}>
Other Option
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
),
ignoreRowClick: true,
allowOverflow: true,
button: true,
sortable: false,
width: "100px",
},
];
const tableData = {
columns: dataTableColumns,
data: users,
return (
<div>
<a
className='btn btn-primary'
to='/admin/administer/new-user'
onClick={handleNavigation}
>
+ Add User
</a>
<DataTableExtensions
{...tableData}
export={true}
print={true}
extensions={extensions}
>
<DataTable
// columns={dataTableColumns}
// data={users}
noHeader
defaultSortField='lastName'
defaultSortAsc={false}
customStyles={tableCustomStyles}
pagination
responsive='true'
highlightOnHover
/>
</DataTableExtensions>
</div>
)}
答案1
得分: 0
I finally managed to resolve my concerns... And I learned that currently react-data-table-component and extension don't give much flexibility when it comes to updating the component to your specific requirements. And the last update of the component was one year old, with total downloads within 2-2.5k
So I used my custom input and search button and filtered the data being received through back end and to fix the issues of export and print I gave data as string in the selector instead of (row) => row.name method
Also one more challenge that I was facing was that data table was displaying content that was growing outside the container giving a horizontal scroll option which was not required so I used wrap property for columns with more text and gave fixed width to columns with less text to resolve this issue.
My updated Code is as under:
import DataTable from "react-data-table-component";
import {
searchFunctionality,
tableCustomStyles,
} from "../../utils/CommonFunctions";
import DataTableExtensions from "react-data-table-component-extensions";
import "react-data-table-component-extensions/dist/index.css";
export default function RolesData() {
const [roles, setRoles] = useState([]);
const [filteredValue, setFilteredValue] = useState("");
const [finalFilteredValue, setFinalFilteredValue] = useState("");
const [filteredData, setFilteredData] = useState([]);
useEffect(() => {
const filteredData = searchFunctionality(
roles,
dataTableColumns,
finalFilteredValue
);
setFilteredData(filteredData);
}, [roles, finalFilteredValue]);
const callGetRolesApi = async () => {
try {
let res = await getRoles();
const { message, data, status } = res;
console.log(res);
if (status == clientSideStatus.success) {
data.forEach((user, index) => {
user.serial = index + 1;
user.refinedRoles = user?.roles?.map((role) => role?.name).join(", ");
});
setRoles(data);
setFilteredData(data);
console.log(data);
} else {
toast.error(message);
}
} catch (err) {
console.error(err);
toast.error(clientDefinedMessages.rolesError);
}
};
const dataTableColumns = [
{
name: "#",
selector: "serial",
sortable: false,
width: "50px",
},
{
name: "Role Name",
selector: "name",
sortable: true,
// width: "140px",
wrap: true,
},
{
name: "Type of Role",
selector: "roleTypeName",
sortable: true,
// width: "140px",
wrap: true,
},
{
name: "Status",
selector: "status",
sortable: true,
width: "140px",
wrap: true,
},
{
name: "Member(s)",
selector: "usersCount",
style: { "text-decoration": "link", color: "blue" },
sortable: false,
// width: "140px",
wrap: true,
ignoreRowClick: true,
allowOverflow: true,
button: true,
width: "150px",
cell: (row) => (
<>
<button
type='button'
className='btn btn-link '
onClick={() => handleMembersCountNavigation(row)}
>
{row.usersCount}
</button>
</>
),
},
{
name: "Option(s)",
cell: (row) => (
<>
<Dropdown>
<Dropdown.Toggle
variant='fade-primary'
id={`dropdown-${row?.role?.id}`}
className='d-flex'
>
<VerticalDots style={{ height: 20 }} />
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item
onClick={() => handleViewDetailsNavigation(row?.id)}
>
View Details
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
),
sortable: false,
// width: "140px",
wrap: true,
ignoreRowClick: true,
allowOverflow: true,
button: true,
width: "150px",
},
];
const tableData = {
columns: dataTableColumns,
data: filteredData,
};
return (
<>
{!roles ? (
<div className='d-flex justify-content-center p-3'>Loading...</div>
) : (
<div
className='d-flex align-intems-center flex-wrap col-md-6 col-lg-12'
style={{ width: "100%", justifyContent: "center" }}
>
<a
className='btn btn-primary d-flex align-items-center'
to='/admin/administer/new-user'
onClick={handleNavigation}
>
+ Add User
</a>
<div
className='input-group ms-auto'
style={{ width: 340, display: "inline-flex" }}
>
<input
type='text'
className='form-control'
placeholder='Search Users'
value={filteredValue}
aria-describedby='button-addon2'
onChange={(event) => setFilteredValue(event.target.value)}
/>
<button
className='btn btn-outline-primary'
type='button'
id='button-addon2'
onClick={() => setFinalFilteredValue(filteredValue)}
>
Go
</button>
<button
type='button'
className='btn btn-outline-primary'
aria-label='Clear'
onClick={() => {
setFilteredValue("");
setFinalFilteredValue("");
}}
>
Clear
</button>
</div>
<DataTableExtensions {...tableData} filter={false}>
<DataTable
columns={dataTableColumns}
data={roles}
noHeader
// defaultSortField='lastName'
defaultSortAsc={false}
customStyles={tableCustomStyles}
pagination
highlightOnHover
/>
</DataTableExtensions>
</div>
)}
</>
);
}
The common functions created for the styling and filtering data are as under:
export const tableCustomStyles = {
headCells: {
style: {
fontSize: "14px",
fontWeight: "bold",
paddingLeft: "8px",
justifyContent: "left",
color: "#1e78fd",
},
},
cells: {
style: {
fontSize: "14px",
paddingLeft: "8px",
justifyContent: "left",
whiteSpace: "normal",
},
},
container: {
display: "flex",
justifyContent: "flex-end",
marginBottom: "20px",
// Add any other custom styles you need
},
filterInput: {
marginRight: "10px",
// Add any other custom styles for the filter input
},
};
export const searchFunctionality = (data, dataTableColumns, filteredValue) => {
let data1 = data?.filter((dat) => {
if (filteredValue !== "") {
for (let i = 0; i < dataTableColumns.length; i++) {
if (dataTableColumns[i]?.selector) {
if
<details>
<summary>英文:</summary>
I finally managed to resolve my concerns... And I learned that currently react-data-table-component and extension don't give much flexibility when it comes to updating the component to your specific requirements. And the last update of the component was one year old, with total downloads within 2-2.5k
So I used my custom input and search button and filtered the data being received through back end and to fix the issues of export and print I gave data as string in the selector instead of (row) => row.name method
Also one more challenge that I was facing was that data table was displaying conent that was growing outside the container giving a horizontal scroll option which was not required so I used wrap property for columns with more text and gave fixed width to columns with less text to resolve this issue.
My updated Code is as under:
import DataTable from "react-data-table-component";
import {
searchFunctionality,
tableCustomStyles,
} from "../../utils/CommonFunctions";
import DataTableExtensions from "react-data-table-component-extensions";
import "react-data-table-component-extensions/dist/index.css";
export default function RolesData() {
const [roles, setRoles] = useState([]);
const [filteredValue, setFilteredValue] = useState("");
const [finalFilteredValue, setFinalFilteredValue] = useState("");
const [filteredData, setFilteredData] = useState([]);
useEffect(() => {
const filteredData = searchFunctionality(
roles,
dataTableColumns,
finalFilteredValue
);
setFilteredData(filteredData);
}, [roles, finalFilteredValue]);
const callGetRolesApi = async () => {
try {
let res = await getRoles();
const { message, data, status } = res;
console.log(res);
if (status == clientSideStatus.success) {
data.forEach((user, index) => {
user.serial = index + 1;
user.refinedRoles = user?.roles?.map((role) => role?.name).join(", "); });
setRoles(data);
setFilteredData(data);
console.log(data);
} else {
toast.error(message);
}
} catch (err) {
console.error(err);
toast.error(clientDefinedMessages.rolesError);
}
};
const dataTableColumns = [
{
name: "#",
selector: "serial",
sortable: false,
width: "50px",
},
{
name: "Role Name",
selector: "name",
sortable: true,
// width: "140px",
wrap: true,
},
{
name: "Type of Role",
selector: "roleTypeName",
sortable: true,
// width: "140px",
wrap: true,
},
{
name: "Status",
selector: "status",
sortable: true,
width: "140px",
wrap: true,
},
{
name: "Member(s)",
selector: "usersCount",
style: { "text-decoration": "link", color: "blue" },
sortable: false,
// width: "140px",
wrap: true,
ignoreRowClick: true,
allowOverflow: true,
button: true,
width: "150px",
cell: (row) => (
<>
<button
type='button'
className='btn btn-link '
onClick={() => handleMembersCountNavigation(row)}
>
{row.usersCount}
</button>
</>
),
},
{
name: "Option(s)",
cell: (row) => (
<>
<Dropdown>
<Dropdown.Toggle
variant='fade-primary'
id={dropdown-${row?.role?.id}
}
className='d-flex'
>
<VerticalDots style={{ height: 20 }} />
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item
onClick={() => handleViewDetailsNavigation(row?.id)}
>
View Details
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
),
sortable: false,
// width: "140px",
wrap: true,
ignoreRowClick: true,
allowOverflow: true,
button: true,
width: "150px",
},
];
const tableData = {
columns: dataTableColumns,
data: filteredData,
};
return (
<>
{!roles ? (
<div className='d-flex justify-content-center p-3'>Loading...</div>
) : (
<div
className='d-flex align-intems-center flex-wrap col-md-6 col-lg-12'
style={{ width: "100%", justifyContent: "center" }}
>
<a
className='btn btn-primary d-flex align-items-center'
to='/admin/administer/new-user'
onClick={handleNavigation}
>
+ Add User
</a>
<div
className='input-group ms-auto'
style={{ width: 340, display: "inline-flex" }}
>
<input
type='text'
className='form-control'
placeholder='Search Users'
value={filteredValue}
aria-describedby='button-addon2'
onChange={(event) => setFilteredValue(event.target.value)}
/>
<button
className='btn btn-outline-primary'
type='button'
id='button-addon2'
onClick={() => setFinalFilteredValue(filteredValue)}
>
Go
</button>
<button
type='button'
className='btn btn-outline-primary'
aria-label='Clear'
onClick={() => {
setFilteredValue("");
setFinalFilteredValue("");
}}
>
Clear
</button>
</div>
<DataTableExtensions {...tableData} filter={false}>
<DataTable
columns={dataTableColumns}
data={roles}
noHeader
// defaultSortField='lastName'
defaultSortAsc={false}
customStyles={tableCustomStyles}
pagination
highlightOnHover
/>
</DataTableExtensions>
</div>
)}
</>
);
The common functions created for the styling and filtering data are as under:
export const tableCustomStyles = {
headCells: {
style: {
fontSize: "14px",
fontWeight: "bold",
paddingLeft: "8px",
justifyContent: "left",
color: "#1e78fd",
},
},
cells: {
style: {
fontSize: "14px",
paddingLeft: "8px",
justifyContent: "left",
whiteSpace: "normal",
},
},
container: {
display: "flex",
justifyContent: "flex-end",
marginBottom: "20px",
// Add any other custom styles you need
},
filterInput: {
marginRight: "10px",
// Add any other custom styles for the filter input
},
};
export const searchFunctionality = (data, dataTableColumns, filteredValue) => {
let data1 = data?.filter((dat) => {
if (filteredValue !== "") {
for (let i = 0; i < dataTableColumns.length; i++) {
if (dataTableColumns[i]?.selector) {
if (
dat[dataTableColumns[i]?.selector]
?.toString()
?.toLowerCase()
?.includes(filteredValue?.toLowerCase())
)
return true;
}
}
return false;
}
return true;
});
data1?.forEach((user, index) => {
user.serial = index + 1;
});
return data1;
};
[1]: https://i.stack.imgur.com/P1JNH.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论