import React, { useState, useMemo, useEffect } from "react";
import "./DataGridPage.css";
import apiService from "./service/dataGridService"; /* apiService 是自行客製化命名 */
function DataGridPage() {
const [tableHeader, setTableHeader] = useState([]); // table header.
const [tableBody, setTableBody] = useState([]); // table body.
const [searchText, setSearchText] = useState(""); // 搜尋.
const [sortConfig, setSortConfig] = useState({ key: null, direction: "asc" }); // 排序.
const [currentPage, setCurrentPage] = useState(1); // 第幾頁.
const [rowsPerPage, setRowsPerPage] = useState(5); // 多少筆資料做分頁.
useEffect(() => {
/* 當 元件 render 完畢時,fetch data 打後端 Web API 抓取資料 */
console.log("#1 mounted data");
// fetch data.
const tempTableHeader = apiService.getTableHeader();
const tempTableBody = apiService.getTableBody();
console.log("tempTableHeader ", tempTableHeader);
console.log("tempTableBody ", tempTableBody);
setTableHeader(tempTableHeader);
setTableBody(tempTableBody);
return () => {
/* 當元件卸載時清除 */
console.log("#2 unmounted _ ");
};
}, []);
// 搜尋功能.
const filteredData = useMemo(() => {
return tableBody.filter((row) =>
row.title.toLowerCase().includes(searchText.toLowerCase())
);
}, [searchText, tableBody]);
// 排序功能.
const sortedData = useMemo(() => {
if (!sortConfig.key) {
// key 為 null ,則無排序。.
return filteredData;
}
const sorted = [...filteredData].sort((a, b) => {
if (a[sortConfig.key] < b[sortConfig.key]) {
return (sortConfig.direction === "asc") ? -1 : 1;
}
if (a[sortConfig.key] > b[sortConfig.key]) {
return (sortConfig.direction === "asc") ? 1 : -1;
}
return 0;
});
return sorted;
}, [filteredData, sortConfig]);
// 使用者點擊,啟動排序功能。.
function requestSort(hKey) {
// asc 從小排到大.
// desc 從大排到小.
let direction = "asc";
if (sortConfig.key === hKey && sortConfig.direction === "asc") {
// asc 再按一次,進入 desc排序狀態.
direction = "desc";
}
if (sortConfig.key === hKey && sortConfig.direction === "desc") {
// desc 再按一次解除排序.
hKey = null;
direction = "asc";
}
setSortConfig({
key: hKey,
direction: direction
});
};
// 分頁功能.
// 計算總共幾頁.
const totalPages = Math.ceil(sortedData.length / rowsPerPage);
/* 取出某一頁的指定筆數 sortedData.slice(起始值, 終止值) */
const pagedData = sortedData.slice(((currentPage - 1) * rowsPerPage), (currentPage * rowsPerPage));
function handlePageChange(page) {
if ((page >= 1) && (page <= totalPages)) {
setCurrentPage(page);
}
};
// 本地化價格標註,標註新台幣。.
function getPrice(price) {
return `${price} NT`;
};
// sort 排序標籤的 CSS Class.
function getSortClass(key, sortConfig) {
if (sortConfig.key !== key) {
return "";
}
return (sortConfig.direction === "asc") ? "asc" : "desc";
}
// true 代表這個欄位 【不排序】.
// false 這個欄位 【排序】.
function isNonSortableFun(key) {
if (key === "url") {
return true;
}
return false;
}
// 點擊 URL 彈出子視窗.
function openPopup(url) {
window.open(url, "popup", "width=800,height=600,scrollbars=yes");
}
return (
{/* Header */}
React Data Grid Table
{/* Main */}
{/* 搜尋與分頁選擇 */}
{
setSearchText(e.target.value);
setCurrentPage(1);
}}
/>
{/* 資料表 */}
{tableHeader.map((header) => {
/* 『true』 表示此欄位不排序. */
const isNonSortable = isNonSortableFun(header.key);
const tSortClass = getSortClass(header.key, sortConfig);
/* check 檢查 當前的 欄位 是 排序欄位. */
const isActive = (sortConfig.key === header.key);
/* 切換顯示上下符號icon排序 */
const tempArrow = isActive && (sortConfig?.direction === "asc" ? "↑" : "↓");
return (
/* */
{isNonSortable ? (
/* 不可排序. */
{header.label}
) : (
/* 其它欄位顯示為可操作按鈕,並會顯示排序 icon. */
requestSort(header.key)}>
{header.label}
| {tempArrow}
)}
);
})}
{(pagedData.length > 0) ? (
pagedData.map((row) => {
return (
{row.No}
{row.title}
{row.content}
{getPrice(row.price.toLocaleString())}
openPopup(row.url)}
style={{ color: "blue", textDecoration: "underline" }}
>
詳情頁
);
})
) : (
找不到符合的資料
)}
{/* 分頁控制 */}
頁面 {currentPage} / {totalPages}
{/* Footer */}
< footer className="footer" >React DataGrid 小練習
);
}
export default DataGridPage;