Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
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" }} > 詳情頁
); }) ) : (
找不到符合的資料
)}
{/* 分頁控制 */}
每頁筆數:
{ setRowsPerPage(Number(e.target.value)); setCurrentPage(1); }} >
5筆
10筆
handlePageChange(currentPage - 1)} disabled={currentPage === 1} > 上一頁
頁面 {currentPage} / {totalPages}
handlePageChange(currentPage + 1)} disabled={currentPage === totalPages} > 下一頁
{/* Footer */} < footer className="footer" >React DataGrid 小練習
); } export default DataGridPage;
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)