後台調整
This commit is contained in:
parent
f027c4e523
commit
2909ed1f65
@ -2,7 +2,7 @@
|
|||||||
<html lang="zh-Hant">
|
<html lang="zh-Hant">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>居民列表</title>
|
<title>居民訊息列表</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
@ -10,21 +10,24 @@
|
|||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<div class="d-flex justify-content-between mb-3">
|
<div class="d-flex justify-content-between mb-3">
|
||||||
<h2>居民訊息列表</h2>
|
<h2>居民訊息列表</h2>
|
||||||
<!-- 右上搜尋按鈕已移除 -->
|
<!-- 新增按鈕:開啟 Modal -->
|
||||||
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#searchModal">🔍 搜尋居民</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 原本的搜尋欄位區塊 -->
|
||||||
<div class="row g-2 mb-3">
|
<div class="row g-2 mb-3">
|
||||||
<div class="col-sm-6 col-md-3 col-lg-2">
|
<div class="col-sm-6 col-md-3 col-lg-2">
|
||||||
<input type="text" id="searchName" class="form-control" placeholder="搜尋姓名">
|
<input type="text" id="searchName" class="form-control" placeholder="搜尋姓名">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-2">
|
<div class="col-sm-6 col-md-3 col-lg-2">
|
||||||
<input type="text" id="searchroom" class="form-control" placeholder="搜尋 房號">
|
<input type="text" id="searchRoom" class="form-control" placeholder="搜尋 房號">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-2 col-lg-2">
|
<div class="col-6 col-md-2 col-lg-2">
|
||||||
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="window.alert('依據查詢關鍵字列出');">搜尋</button>
|
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="searchResidents()">搜尋</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 居民表格 -->
|
||||||
<table class="table table-bordered table-hover">
|
<table class="table table-bordered table-hover">
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
@ -38,6 +41,7 @@
|
|||||||
<tbody id="residentTable"></tbody>
|
<tbody id="residentTable"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- 分頁按鈕 -->
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<div>第 <span id="currentPage">1</span> 頁,共 <span id="totalPages">1</span> 頁</div>
|
<div>第 <span id="currentPage">1</span> 頁,共 <span id="totalPages">1</span> 頁</div>
|
||||||
<div>
|
<div>
|
||||||
@ -47,7 +51,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 原先搜尋浮框 modal 已完全移除 -->
|
<!-- Modal 搜尋浮框 -->
|
||||||
|
<div class="modal fade" id="searchModal" tabindex="-1" aria-labelledby="searchModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="searchModalLabel">搜尋居民</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="關閉"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="text" id="modalSearchInput" class="form-control mb-3" placeholder="請輸入姓名或房號">
|
||||||
|
<ul class="list-group" id="modalSearchResult"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
@ -66,56 +84,89 @@
|
|||||||
{ id: 12, name: "鄧紫棋", room: "A202", lastMessage: "...今晚電梯會維修。", read: false }
|
{ id: 12, name: "鄧紫棋", room: "A202", lastMessage: "...今晚電梯會維修。", read: false }
|
||||||
];
|
];
|
||||||
|
|
||||||
const pageSize = 5;
|
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
|
const pageSize = 5;
|
||||||
|
let filteredResidents = [...residents];
|
||||||
|
|
||||||
function renderTable() {
|
function renderTable() {
|
||||||
const tbody = document.getElementById("residentTable");
|
const tbody = document.getElementById("residentTable");
|
||||||
tbody.innerHTML = "";
|
tbody.innerHTML = "";
|
||||||
|
const start = (currentPage - 1) * pageSize;
|
||||||
|
const pageData = filteredResidents.slice(start, start + pageSize);
|
||||||
|
|
||||||
const startIndex = (currentPage - 1) * pageSize;
|
pageData.forEach(r => {
|
||||||
const pageResidents = residents.slice(startIndex, startIndex + pageSize);
|
const status = r.read ? "⚪ 已讀" : "🟡 未讀";
|
||||||
|
const message = r.read ? r.lastMessage : `<strong>${r.lastMessage}</strong>`;
|
||||||
pageResidents.forEach(r => {
|
tbody.innerHTML += `
|
||||||
const tr = document.createElement("tr");
|
<tr>
|
||||||
const statusBadge = r.read
|
|
||||||
? `<span class="text-secondary">⚪ 已讀</span>`
|
|
||||||
: `<span class="text-warning">🟡 未讀</span>`;
|
|
||||||
const messageText = r.read ? r.lastMessage : `<strong>${r.lastMessage}</strong>`;
|
|
||||||
tr.innerHTML = `
|
|
||||||
<td>${r.name}</td>
|
<td>${r.name}</td>
|
||||||
<td>${r.room}</td>
|
<td>${r.room}</td>
|
||||||
<td>${messageText}</td>
|
<td>${message}</td>
|
||||||
<td>${statusBadge}</td>
|
<td><span class="${r.read ? 'text-secondary' : 'text-warning'}">${status}</span></td>
|
||||||
<td><a href="message.html?id=${r.id}" class="btn btn-outline-secondary btn-sm">查看訊息</a></td>
|
<td><a href="message.html?id=${r.id}" class="btn btn-outline-secondary btn-sm">查看訊息</a></td>
|
||||||
|
</tr>
|
||||||
`;
|
`;
|
||||||
tbody.appendChild(tr);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalPages = Math.ceil(residents.length / pageSize);
|
const totalPages = Math.ceil(filteredResidents.length / pageSize) || 1;
|
||||||
document.getElementById("currentPage").textContent = currentPage;
|
document.getElementById("currentPage").textContent = currentPage;
|
||||||
document.getElementById("totalPages").textContent = totalPages;
|
document.getElementById("totalPages").textContent = totalPages;
|
||||||
|
|
||||||
document.getElementById("prevBtn").disabled = currentPage === 1;
|
document.getElementById("prevBtn").disabled = currentPage === 1;
|
||||||
document.getElementById("nextBtn").disabled = currentPage === totalPages;
|
document.getElementById("nextBtn").disabled = currentPage === totalPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("prevBtn").addEventListener("click", () => {
|
document.getElementById("prevBtn").onclick = () => {
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
currentPage--;
|
currentPage--;
|
||||||
renderTable();
|
renderTable();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
document.getElementById("nextBtn").addEventListener("click", () => {
|
document.getElementById("nextBtn").onclick = () => {
|
||||||
const totalPages = Math.ceil(residents.length / pageSize);
|
const totalPages = Math.ceil(filteredResidents.length / pageSize);
|
||||||
if (currentPage < totalPages) {
|
if (currentPage < totalPages) {
|
||||||
currentPage++;
|
currentPage++;
|
||||||
renderTable();
|
renderTable();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
// 已移除 searchInput 的事件監聽與功能
|
function searchResidents() {
|
||||||
|
const nameKey = document.getElementById("searchName").value.trim().toLowerCase();
|
||||||
|
const roomKey = document.getElementById("searchRoom").value.trim().toLowerCase();
|
||||||
|
|
||||||
|
filteredResidents = residents.filter(r =>
|
||||||
|
r.name.toLowerCase().includes(nameKey) &&
|
||||||
|
r.room.toLowerCase().includes(roomKey)
|
||||||
|
);
|
||||||
|
|
||||||
|
currentPage = 1;
|
||||||
|
renderTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modal 搜尋
|
||||||
|
document.getElementById("modalSearchInput").addEventListener("input", function () {
|
||||||
|
const keyword = this.value.trim().toLowerCase();
|
||||||
|
const resultBox = document.getElementById("modalSearchResult");
|
||||||
|
resultBox.innerHTML = "";
|
||||||
|
|
||||||
|
if (!keyword) return;
|
||||||
|
|
||||||
|
const results = residents.filter(r =>
|
||||||
|
r.name.toLowerCase().includes(keyword) || r.room.toLowerCase().includes(keyword)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
resultBox.innerHTML = `<li class="list-group-item text-muted">找不到相關居民</li>`;
|
||||||
|
} else {
|
||||||
|
results.forEach(r => {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.className = "list-group-item list-group-item-action";
|
||||||
|
li.innerHTML = `<strong>${r.name}</strong> - ${r.room}`;
|
||||||
|
li.onclick = () => window.location.href = `message.html?id=${r.id}`;
|
||||||
|
resultBox.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
renderTable();
|
renderTable();
|
||||||
</script>
|
</script>
|
||||||
|
@ -14,21 +14,9 @@
|
|||||||
}
|
}
|
||||||
.container.mt-4 {
|
.container.mt-4 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-bottom: 70px;
|
/* Removed padding-bottom as pagination is no longer fixed */
|
||||||
}
|
|
||||||
nav.pagination-fixed {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 10px 0;
|
|
||||||
border-top: 1px solid #dee2e6;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
nav.pagination-fixed .pagination {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
/* Removed .pagination-controls fixed styling */
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -37,13 +25,13 @@
|
|||||||
|
|
||||||
<div class="row g-2 mb-3">
|
<div class="row g-2 mb-3">
|
||||||
<div class="col-4 col-md-2 col-lg-1">
|
<div class="col-4 col-md-2 col-lg-1">
|
||||||
<a href="repair_firm_add.html" class="btn btn-outline-success w-100 rounded-pill btn-sm">新增</a>
|
<a href="repair_firm_add.html" class="btn btn-outline-success w-100 rounded-pill">新增</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 col-md-2 col-lg-1">
|
<div class="col-4 col-md-2 col-lg-1">
|
||||||
<a href="repair_firm_import.html" class="btn btn-outline-info w-100 rounded-pill btn-sm">匯入</a>
|
<a href="repair_firm_import.html" class="btn btn-outline-info w-100 rounded-pill">匯入</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 col-md-2 col-lg-1">
|
<div class="col-4 col-md-2 col-lg-1">
|
||||||
<button class="btn btn-outline-secondary w-100 rounded-pill btn-sm" onclick="exportVendors()">匯出</button>
|
<button class="btn btn-outline-secondary w-100 rounded-pill" onclick="exportVendors()">匯出</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -55,10 +43,10 @@
|
|||||||
<input type="text" id="searchAddress" class="form-control" placeholder="搜尋地址">
|
<input type="text" id="searchAddress" class="form-control" placeholder="搜尋地址">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-2 col-lg-2">
|
<div class="col-6 col-md-2 col-lg-2">
|
||||||
<button class="btn btn-outline-primary w-100 rounded-pill btn-sm" onclick="search()">搜尋</button>
|
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="performSearch()">搜尋</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 col-md-2 col-lg-1">
|
<div class="col-6 col-md-2 col-lg-1">
|
||||||
<button class="btn btn-outline-danger w-100 rounded-pill btn-sm" onclick="deleteSelected()">刪除勾選</button>
|
<button class="btn btn-outline-danger w-100 rounded-pill" onclick="deleteSelected()">刪除勾選</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -77,28 +65,36 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody id="vendorTable"></tbody>
|
<tbody id="vendorTable"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||||
|
<div>第 <span id="currentPageInfo">1</span> 頁,共 <span id="totalPagesInfo">1</span> 頁</div>
|
||||||
|
<div>
|
||||||
|
<button id="prevPageBtn" class="btn btn-sm btn-outline-secondary me-1" onclick="prevPage()">上一頁</button>
|
||||||
|
<button id="nextPageBtn" class="btn btn-sm btn-outline-secondary" onclick="nextPage()">下一頁</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav class="pagination-fixed">
|
</div> <script>
|
||||||
<ul class="pagination justify-content-center" id="pagination"></ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const pageSize = 5;
|
const pageSize = 5;
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
|
let currentFilteredData = []; // To store the currently filtered data for pagination
|
||||||
|
|
||||||
let vendors = [
|
let vendors = [
|
||||||
{ id: 1, name: "好修電器", contact: "陳先生", phone: "0912-111-222", address: "台北市大安區仁愛路一段1號", service: "家電維修" },
|
{ id: 1, name: "好修電器", contact: "陳先生", phone: "0912-111-222", address: "台北市大安區仁愛路一段1號", service: "家電維修" },
|
||||||
{ id: 2, name: "強力水電", contact: "林小姐", phone: "0988-333-444", address: "新北市板橋區文化路二段88號", service: "水電工程" },
|
{ id: 2, name: "強力水電", contact: "林小姐", phone: "0988-333-444", address: "新北市板橋區文化路二段88號", service: "水電工程" },
|
||||||
{ id: 3, name: "快速冷氣", contact: "張先生", phone: "0922-555-666", address: "桃園市中壢區中正路100號", service: "冷氣維修" },
|
{ id: 3, name: "快速冷氣", contact: "張先生", phone: "0922-555-666", address: "桃園市中壢區中正路100號", service: "冷氣維修" },
|
||||||
{ id: 4, name: "安全消防", contact: "李經理", phone: "0966-777-888", address: "台中市西屯區市政北七路22號", service: "消防設備" }
|
{ id: 4, name: "安全消防", contact: "李經理", phone: "0966-777-888", address: "台中市西屯區市政北七路22號", service: "消防設備" },
|
||||||
|
{ id: 5, name: "安心居家修繕", contact: "黃太太", phone: "0911-222-333", address: "高雄市苓雅區三多四路110號", service: "綜合修繕" },
|
||||||
|
{ id: 6, name: "速達通管", contact: "許先生", phone: "0977-888-999", address: "台南市東區大學路1號", service: "水管疏通" },
|
||||||
|
{ id: 7, name: "光明電力", contact: "劉師傅", phone: "0933-444-555", address: "新竹市科學園區工業東九路2號", service: "電力維修" },
|
||||||
|
{ id: 8, name: "完美油漆", contact: "吳小姐", phone: "0955-666-777", address: "台北市信義區市府路45號", service: "油漆工程" }
|
||||||
];
|
];
|
||||||
|
|
||||||
function renderTable(data) {
|
function renderTable(dataToRender) {
|
||||||
const tbody = document.getElementById("vendorTable");
|
const tbody = document.getElementById("vendorTable");
|
||||||
tbody.innerHTML = "";
|
tbody.innerHTML = "";
|
||||||
const start = (currentPage - 1) * pageSize;
|
const start = (currentPage - 1) * pageSize;
|
||||||
const pageData = data.slice(start, start + pageSize);
|
const pageData = dataToRender.slice(start, start + pageSize);
|
||||||
|
|
||||||
pageData.forEach(v => {
|
pageData.forEach(v => {
|
||||||
const row = document.createElement("tr");
|
const row = document.createElement("tr");
|
||||||
@ -118,38 +114,60 @@
|
|||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
|
||||||
renderPagination(data.length);
|
updatePaginationControls(dataToRender.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPagination(totalItems) {
|
function updatePaginationControls(totalItems) {
|
||||||
const totalPages = Math.ceil(totalItems / pageSize);
|
const totalPages = Math.ceil(totalItems / pageSize) || 1;
|
||||||
const pagination = document.getElementById("pagination");
|
const currentPageDisplay = document.getElementById("currentPageInfo");
|
||||||
pagination.innerHTML = "";
|
const totalPagesDisplay = document.getElementById("totalPagesInfo");
|
||||||
|
const prevButton = document.getElementById("prevPageBtn");
|
||||||
|
const nextButton = document.getElementById("nextPageBtn");
|
||||||
|
|
||||||
for (let i = 1; i <= totalPages; i++) {
|
if (currentPageDisplay) currentPageDisplay.textContent = currentPage;
|
||||||
const li = document.createElement("li");
|
if (totalPagesDisplay) totalPagesDisplay.textContent = totalPages;
|
||||||
li.className = "page-item" + (i === currentPage ? " active" : "");
|
|
||||||
li.innerHTML = `<a class="page-link" href="#" onclick="goToPage(${i})">${i}</a>`;
|
if (prevButton) prevButton.disabled = currentPage === 1;
|
||||||
pagination.appendChild(li);
|
if (nextButton) nextButton.disabled = currentPage === totalPages || totalItems === 0;
|
||||||
|
|
||||||
|
if (currentPage > totalPages && totalPages > 0) {
|
||||||
|
currentPage = totalPages;
|
||||||
|
renderTable(currentFilteredData); // Rerender if page changed
|
||||||
|
} else if (totalItems === 0) { // All items gone or no items match search
|
||||||
|
if (currentPageDisplay) currentPageDisplay.textContent = 1; // Reset display
|
||||||
|
if (totalPagesDisplay) totalPagesDisplay.textContent = 1;
|
||||||
|
if (prevButton) prevButton.disabled = true;
|
||||||
|
if (nextButton) nextButton.disabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToPage(page) {
|
function prevPage() {
|
||||||
currentPage = page;
|
if (currentPage > 1) {
|
||||||
search();
|
currentPage--;
|
||||||
window.scrollTo(0, 0);
|
renderTable(currentFilteredData);
|
||||||
|
window.scrollTo(0, 0); // Scroll to top to see the new page's content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function search() {
|
function nextPage() {
|
||||||
|
const totalPages = Math.ceil(currentFilteredData.length / pageSize);
|
||||||
|
if (currentPage < totalPages) {
|
||||||
|
currentPage++;
|
||||||
|
renderTable(currentFilteredData);
|
||||||
|
window.scrollTo(0, 0); // Scroll to top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function performSearch() {
|
||||||
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
||||||
const addressInput = document.getElementById("searchAddress").value.toLowerCase();
|
const addressInput = document.getElementById("searchAddress").value.toLowerCase();
|
||||||
|
|
||||||
const filtered = vendors.filter(v =>
|
currentFilteredData = vendors.filter(v =>
|
||||||
v.name.toLowerCase().includes(nameInput) &&
|
v.name.toLowerCase().includes(nameInput) &&
|
||||||
(v.address ? v.address.toLowerCase().includes(addressInput) : true)
|
(v.address ? v.address.toLowerCase().includes(addressInput) : true)
|
||||||
);
|
);
|
||||||
|
currentPage = 1;
|
||||||
renderTable(filtered);
|
renderTable(currentFilteredData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAll(source) {
|
function toggleAll(source) {
|
||||||
@ -166,28 +184,67 @@
|
|||||||
}
|
}
|
||||||
const idsToDelete = Array.from(selected).map(cb => parseInt(cb.dataset.id));
|
const idsToDelete = Array.from(selected).map(cb => parseInt(cb.dataset.id));
|
||||||
vendors = vendors.filter(v => !idsToDelete.includes(v.id));
|
vendors = vendors.filter(v => !idsToDelete.includes(v.id));
|
||||||
|
|
||||||
|
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
||||||
|
const addressInput = document.getElementById("searchAddress").value.toLowerCase();
|
||||||
|
currentFilteredData = vendors.filter(v =>
|
||||||
|
v.name.toLowerCase().includes(nameInput) &&
|
||||||
|
(v.address ? v.address.toLowerCase().includes(addressInput) : true)
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalPages = Math.ceil(currentFilteredData.length / pageSize) || 1;
|
||||||
|
if (currentPage > totalPages) {
|
||||||
|
currentPage = totalPages;
|
||||||
|
}
|
||||||
|
if (currentFilteredData.length === 0) {
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
search();
|
}
|
||||||
|
|
||||||
|
renderTable(currentFilteredData);
|
||||||
document.getElementById("selectAll").checked = false;
|
document.getElementById("selectAll").checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteVendor(id) {
|
function deleteVendor(id) {
|
||||||
if (!confirm("確定要刪除此筆資料嗎?")) return;
|
if (!confirm("確定要刪除此筆資料嗎?")) return;
|
||||||
vendors = vendors.filter(v => v.id !== id);
|
vendors = vendors.filter(v => v.id !== id);
|
||||||
const totalPages = Math.ceil(vendors.length / pageSize);
|
|
||||||
if (currentPage > totalPages && totalPages > 0) {
|
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
||||||
|
const addressInput = document.getElementById("searchAddress").value.toLowerCase();
|
||||||
|
currentFilteredData = vendors.filter(v =>
|
||||||
|
v.name.toLowerCase().includes(nameInput) &&
|
||||||
|
(v.address ? v.address.toLowerCase().includes(addressInput) : true)
|
||||||
|
);
|
||||||
|
|
||||||
|
const itemsOnCurrentPageAfterDelete = currentFilteredData.slice((currentPage - 1) * pageSize, currentPage * pageSize).length;
|
||||||
|
const totalPages = Math.ceil(currentFilteredData.length / pageSize) || 1;
|
||||||
|
|
||||||
|
if (itemsOnCurrentPageAfterDelete === 0 && currentPage > 1) {
|
||||||
|
currentPage--;
|
||||||
|
} else if (currentPage > totalPages) {
|
||||||
currentPage = totalPages;
|
currentPage = totalPages;
|
||||||
} else if (vendors.length === 0) {
|
}
|
||||||
|
if (currentFilteredData.length === 0) {
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
}
|
}
|
||||||
search();
|
|
||||||
|
renderTable(currentFilteredData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportVendors() {
|
function exportVendors() {
|
||||||
alert("匯出搜尋結果(若無搜尋條件則匯出全部)");
|
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
||||||
|
const addressInput = document.getElementById("searchAddress").value.toLowerCase();
|
||||||
|
let dataToExport = vendors;
|
||||||
|
if (nameInput || addressInput) {
|
||||||
|
dataToExport = vendors.filter(v =>
|
||||||
|
v.name.toLowerCase().includes(nameInput) &&
|
||||||
|
(v.address ? v.address.toLowerCase().includes(addressInput) : true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
alert(`準備匯出 ${dataToExport.length} 筆資料(${nameInput || addressInput ? "依搜尋條件" : "全部"})`);
|
||||||
|
console.log("Data to export:", dataToExport);
|
||||||
}
|
}
|
||||||
|
|
||||||
search(); // 初始載入
|
performSearch(); // Initial load
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
.container.mt-4 {
|
.container.mt-4 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
/* padding-bottom: 70px; Removed as pagination is no longer fixed */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#qrcodeModal .modal-body {
|
#qrcodeModal .modal-body {
|
||||||
@ -24,25 +23,19 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removed nav.pagination-fixed styles */
|
|
||||||
|
|
||||||
/* Custom styles ONLY for buttons that are .btn but NOT .btn-sm or .btn-lg */
|
|
||||||
/* This ensures .btn-sm (like pagination and table action buttons) use Bootstrap's default styling */
|
|
||||||
.btn:not(.btn-sm):not(.btn-lg) {
|
.btn:not(.btn-sm):not(.btn-lg) {
|
||||||
font-weight: 500; /* Custom font-weight for standard-sized buttons */
|
font-weight: 500;
|
||||||
font-size: 1rem; /* Custom font-size for standard-sized buttons */
|
font-size: 1rem;
|
||||||
padding: 0.5rem 0.75rem; /* Custom padding for standard-sized buttons */
|
padding: 0.5rem 0.75rem;
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom hover effect ONLY for buttons that are .btn but NOT .btn-sm or .btn-lg */
|
|
||||||
.btn:not(.btn-sm):not(.btn-lg):hover {
|
.btn:not(.btn-sm):not(.btn-lg):hover {
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
/* Ensure all buttons, including btn-sm, can have rounded-pill if specified by class */
|
|
||||||
.rounded-pill {
|
.rounded-pill {
|
||||||
border-radius: 50rem !important; /* Ensure pill shape if class is present */
|
border-radius: 50rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@ -51,23 +44,26 @@
|
|||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<h2 class="mb-4">未開通居民列表</h2>
|
<h2 class="mb-4">未開通居民列表</h2>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row g-2 mb-3">
|
||||||
<div class="col-md-3">
|
<div class="col-12 col-sm-6 col-md-4 col-lg-2">
|
||||||
<input type="text" id="searchName" class="form-control" placeholder="搜尋姓名">
|
<input type="text" id="searchName" class="form-control" placeholder="搜尋姓名">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-12 col-sm-6 col-md-4 col-lg-2">
|
||||||
<input type="text" id="searchEmail" class="form-control" placeholder="搜尋 Email">
|
<input type="text" id="searchEmail" class="form-control" placeholder="搜尋 Email">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-12 col-sm-12 col-md-4 col-lg-2">
|
||||||
<input type="text" id="searchRoom" class="form-control" placeholder="搜尋房號">
|
<input type="text" id="searchRoom" class="form-control" placeholder="搜尋房號">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 d-flex gap-2">
|
<div class="col-12 col-sm-4 col-md-4 col-lg-2">
|
||||||
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="search()">搜尋</button>
|
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="search()">搜尋</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-3 col-md-3 col-lg-1">
|
||||||
<button class="btn btn-outline-danger w-100 rounded-pill" onclick="deleteSelected()">刪除勾選</button>
|
<button class="btn btn-outline-danger w-100 rounded-pill" onclick="deleteSelected()">刪除勾選</button>
|
||||||
<button class="btn btn-outline-secondary w-100 rounded-pill" onclick="scanResident()">掃描住戶</button>
|
</div>
|
||||||
|
<div class="col-12 col-sm-4 col-md-4 col-lg-3 d-flex justify-content-end">
|
||||||
|
<button class="btn btn-outline-secondary rounded-pill" onclick="scanResident()">掃描住戶</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<thead class="table-dark">
|
<thead class="table-dark">
|
||||||
<tr>
|
<tr>
|
||||||
@ -90,7 +86,9 @@
|
|||||||
<button class="btn btn-sm btn-outline-secondary" id="nextBtn">下一頁</button>
|
<button class="btn btn-sm btn-outline-secondary" id="nextBtn">下一頁</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> <div class="modal fade" id="qrcodeModal" tabindex="-1" aria-labelledby="qrcodeModalLabel" aria-hidden="true">
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="qrcodeModal" tabindex="-1" aria-labelledby="qrcodeModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-sm modal-dialog-centered">
|
<div class="modal-dialog modal-sm modal-dialog-centered">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@ -110,7 +108,7 @@
|
|||||||
<script>
|
<script>
|
||||||
const pageSize = 5;
|
const pageSize = 5;
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
let currentFilteredData = []; // To store the currently filtered data
|
let currentFilteredData = [];
|
||||||
|
|
||||||
let residents = [
|
let residents = [
|
||||||
{ id: 1, name: "王小明", email: "xiaoming@example.com", phone: "0912-345-678", room: "A101" },
|
{ id: 1, name: "王小明", email: "xiaoming@example.com", phone: "0912-345-678", room: "A101" },
|
||||||
@ -127,7 +125,7 @@
|
|||||||
{ id: 12, name: "鄧紫棋", email: "gem@example.com", phone: "0944-444-444", room: "F602" }
|
{ id: 12, name: "鄧紫棋", email: "gem@example.com", phone: "0944-444-444", room: "F602" }
|
||||||
];
|
];
|
||||||
|
|
||||||
function renderTable() { // Removed 'data' parameter, uses currentFilteredData
|
function renderTable() {
|
||||||
const tbody = document.getElementById("residentTable");
|
const tbody = document.getElementById("residentTable");
|
||||||
tbody.innerHTML = "";
|
tbody.innerHTML = "";
|
||||||
|
|
||||||
@ -136,7 +134,6 @@
|
|||||||
|
|
||||||
pageData.forEach(r => {
|
pageData.forEach(r => {
|
||||||
const row = document.createElement("tr");
|
const row = document.createElement("tr");
|
||||||
// The "開通" button is .btn-sm, will use Bootstrap default small styling
|
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td><input type="checkbox" class="row-checkbox" data-id="${r.id}"></td>
|
<td><input type="checkbox" class="row-checkbox" data-id="${r.id}"></td>
|
||||||
<td>${r.id}</td>
|
<td>${r.id}</td>
|
||||||
@ -149,7 +146,6 @@
|
|||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update pagination display
|
|
||||||
const totalItems = currentFilteredData.length;
|
const totalItems = currentFilteredData.length;
|
||||||
const totalPages = Math.ceil(totalItems / pageSize);
|
const totalPages = Math.ceil(totalItems / pageSize);
|
||||||
document.getElementById("currentPageDisplay").textContent = currentPage;
|
document.getElementById("currentPageDisplay").textContent = currentPage;
|
||||||
@ -159,8 +155,6 @@
|
|||||||
document.getElementById("nextBtn").disabled = currentPage === totalPages || totalPages === 0;
|
document.getElementById("nextBtn").disabled = currentPage === totalPages || totalPages === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removed old renderPagination function
|
|
||||||
|
|
||||||
function applyFiltersAndRender() {
|
function applyFiltersAndRender() {
|
||||||
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
const nameInput = document.getElementById("searchName").value.toLowerCase();
|
||||||
const emailInput = document.getElementById("searchEmail").value.toLowerCase();
|
const emailInput = document.getElementById("searchEmail").value.toLowerCase();
|
||||||
@ -199,7 +193,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function search() {
|
function search() {
|
||||||
currentPage = 1; // Reset to page 1 for new search
|
currentPage = 1;
|
||||||
applyFiltersAndRender();
|
applyFiltersAndRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,18 +209,16 @@
|
|||||||
const idsToDelete = Array.from(selected).map(cb => parseInt(cb.dataset.id));
|
const idsToDelete = Array.from(selected).map(cb => parseInt(cb.dataset.id));
|
||||||
|
|
||||||
residents = residents.filter(r => !idsToDelete.includes(r.id));
|
residents = residents.filter(r => !idsToDelete.includes(r.id));
|
||||||
// currentFilteredData will be updated by applyFiltersAndRender
|
|
||||||
// currentPage will be adjusted if necessary by applyFiltersAndRender
|
|
||||||
applyFiltersAndRender();
|
applyFiltersAndRender();
|
||||||
document.getElementById("selectAll").checked = false;
|
document.getElementById("selectAll").checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showQRCode(url) {
|
function showQRCode(url) {
|
||||||
const qrContainer = document.getElementById("qrcode");
|
const qrContainer = document.getElementById("qrcode");
|
||||||
qrContainer.innerHTML = ""; // Clear previous QR code
|
qrContainer.innerHTML = "";
|
||||||
new QRCode(qrContainer, {
|
new QRCode(qrContainer, {
|
||||||
text: url,
|
text: url,
|
||||||
width: 200, // Ensure QR code is reasonably sized
|
width: 200,
|
||||||
height: 200
|
height: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -239,7 +231,6 @@
|
|||||||
alert("這裡可以接掃描裝置或開啟相機功能");
|
alert("這裡可以接掃描裝置或開啟相機功能");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial load
|
|
||||||
search();
|
search();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user