CVNSS commited on
Commit
72f48b7
·
verified ·
1 Parent(s): 370ee24

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +81 -114
index.html CHANGED
@@ -2,129 +2,96 @@
2
  <html lang="vi">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Tra cứu lịch sử sáp nhập xã phường 2025</title>
6
- <meta name="viewport" content="width=device-width, initial-scale=1">
7
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/>
9
  <style>
10
- body { background: #f8fafc; }
11
- .choices__inner { min-height: 42px !important; }
 
 
 
 
 
 
 
12
  </style>
13
  </head>
14
  <body>
15
- <div class="container py-5">
16
- <h2 class="mb-4 text-primary">🔎 Tra cứu lịch sử sáp nhập xã/phường (2025)</h2>
17
- <div class="card shadow p-4 mb-4">
18
- <form id="searchForm" autocomplete="off">
19
- <div class="row mb-3">
20
- <div class="col-md-6 mb-2">
21
- <label for="ward_new" class="form-label">Chọn xã/phường mới</label>
22
- <select class="form-select" id="ward_new">
23
- <option value="">-- Chọn hoặc gõ tên xã/phường mới --</option>
24
- </select>
25
- </div>
26
- <div class="col-md-6 mb-2">
27
- <label for="province" class="form-label">Tỉnh/Thành phố</label>
28
- <select class="form-select" id="province">
29
- <option value="">-- Chọn tỉnh/thành phố --</option>
30
- </select>
31
- </div>
32
- </div>
33
- <button class="btn btn-primary" type="submit">Tra cứu</button>
34
- <button class="btn btn-outline-secondary ms-2" type="button" id="resetBtn">Làm mới</button>
35
- </form>
36
- </div>
37
- <div id="resultArea"></div>
38
- </div>
39
- <script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
40
- <script>
41
- let allData = [];
42
- const dataUrl = "vn_wards_2025.json"; // đổi tên nếu file khác
43
 
44
- const wardNewSel = document.getElementById("ward_new");
45
- const provinceSel = document.getElementById("province");
46
- const resultArea = document.getElementById("resultArea");
47
- const searchForm = document.getElementById("searchForm");
48
- const resetBtn = document.getElementById("resetBtn");
 
 
 
 
 
49
 
50
- let wardChoices = new Choices(wardNewSel, { searchEnabled: true, itemSelectText: '', shouldSort: false });
51
- let provinceChoices = new Choices(provinceSel, { searchEnabled: true, itemSelectText: '', shouldSort: false });
 
 
 
 
 
 
 
 
 
 
52
 
53
- async function loadData() {
54
- let res = await fetch(dataUrl);
55
- allData = await res.json();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- // Lấy danh sách xã/phường mới duy nhất
58
- let wards = [...new Set(allData.map(e => e.ward_new))].sort();
59
- wardChoices.setChoices([{ value: '', label: '-- Chọn hoặc gõ tên xã/phường mới --', selected: true, disabled: true }, ...wards.map(w => ({value: w, label: w}))], 'value', 'label', true);
60
-
61
- // Lấy danh sách tỉnh duy nhất
62
- let provinces = [...new Set(allData.map(e => e.province))].sort();
63
- provinceChoices.setChoices([{ value: '', label: '-- Chọn tỉnh/thành phố --', selected: true, disabled: true }, ...provinces.map(p => ({value: p, label: p}))], 'value', 'label', true);
64
- }
65
-
66
- // Khi chọn xã/phường mới → tự động lọc tỉnh gợi ý
67
- wardNewSel.addEventListener("change", function() {
68
- if (!this.value) return;
69
- let provs = allData.filter(e => e.ward_new === this.value).map(e => e.province);
70
- provs = [...new Set(provs)];
71
- provinceChoices.setChoices([{ value: '', label: '-- Chọn tỉnh/thành phố --', selected: true, disabled: true }, ...provs.map(p => ({value: p, label: p}))], 'value', 'label', true);
72
- });
73
-
74
- provinceSel.addEventListener("change", function() {
75
- if (!this.value) return;
76
- let wards = allData.filter(e => e.province === this.value).map(e => e.ward_new);
77
- wards = [...new Set(wards)];
78
- wardChoices.setChoices([{ value: '', label: '-- Chọn hoặc gõ tên xã/phường mới --', selected: true, disabled: true }, ...wards.map(w => ({value: w, label: w}))], 'value', 'label', true);
79
- });
80
-
81
- searchForm.addEventListener("submit", function(e) {
82
- e.preventDefault();
83
- resultArea.innerHTML = "";
84
- let rs = allData.filter(e =>
85
- (!provinceSel.value || e.province === provinceSel.value) &&
86
- (!wardNewSel.value || e.ward_new === wardNewSel.value)
87
- );
88
- if (rs.length === 0) showError("Không tìm thấy dữ liệu.");
89
- else renderResult(rs);
90
- });
91
-
92
- resetBtn.addEventListener("click", function() {
93
- provinceChoices.setChoiceByValue('');
94
- wardChoices.setChoiceByValue('');
95
- resultArea.innerHTML = "";
96
- });
97
-
98
- function renderResult(list) {
99
- resultArea.innerHTML = `
100
- <div class="card shadow p-3 mt-2">
101
- <h5 class="mb-3 text-success">Kết quả: <span class="text-dark small">${list.length} xã/phường</span></h5>
102
- <div style="max-height:400px;overflow:auto;">
103
- <table class="table table-bordered table-hover align-middle small">
104
- <thead class="table-light"><tr>
105
- <th>Tỉnh/Thành</th>
106
- <th>Phường/Xã mới</th>
107
- <th>Phường/Xã trước sáp nhập</th>
108
- </tr></thead>
109
- <tbody>
110
- ${list.map(d=>`
111
  <tr>
112
- <td>${d.province||''}</td>
113
- <td>${d.ward_new||''}</td>
114
- <td>${d.ward_old||''}</td>
115
  </tr>
116
- `).join('')}
117
- </tbody>
118
- </table>
119
- </div>
120
- </div>
121
- `;
122
- }
123
- function showError(msg) {
124
- resultArea.innerHTML = `<div class="alert alert-danger"><b>Lỗi:</b> ${msg}</div>`;
125
- }
126
-
127
- loadData();
128
- </script>
129
  </body>
130
  </html>
 
2
  <html lang="vi">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>Tra cứu xã/phường mới - đối chiếu xã/phường trước sáp nhập (2025)</title>
 
 
 
6
  <style>
7
+ body { font-family: Arial, sans-serif; margin: 24px; }
8
+ h2 { color: #006e54; }
9
+ label { font-weight: bold; }
10
+ select, input[type="text"] { margin: 0 12px 12px 0; padding: 6px; }
11
+ table { border-collapse: collapse; margin-top: 18px; width: 100%; }
12
+ th, td { border: 1px solid #ccc; padding: 8px; }
13
+ th { background: #f7f7f7; }
14
+ #result { margin-top: 20px; }
15
+ .note { color: #888; font-size: 0.9em; margin-top: 8px;}
16
  </style>
17
  </head>
18
  <body>
19
+ <h2>Tra cứu Xã/Phường mới → Xã/Phường trước sáp nhập (2025)</h2>
20
+ <label for="province">Tỉnh/Thành:</label>
21
+ <select id="province">
22
+ <option value="">-- Chọn Tỉnh/Thành --</option>
23
+ </select>
24
+ <label for="ward_new">Phường/Xã mới:</label>
25
+ <select id="ward_new" disabled>
26
+ <option value="">-- Chọn Phường/Xã mới --</option>
27
+ </select>
28
+ <div id="result"></div>
29
+ <div class="note">Nguồn dữ liệu: <b>vn_wards_2025.json</b> - bản cập nhật sáp nhập hành chính 2025.</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ <script>
32
+ let DATA = [];
33
+ // NÊN: nhúng file JSON nhỏ vào trong code hoặc dùng fetch nếu host file ngoài
34
+ // Demo: Nhúng trực tiếp (copy đoạn JSON rút gọn nếu cần tối ưu tải trang)
35
+ fetch('vn_wards_2025.json')
36
+ .then(r => r.json())
37
+ .then(data => {
38
+ DATA = data;
39
+ initProvinces();
40
+ });
41
 
42
+ // Khởi tạo dropdown tỉnh/thành
43
+ function initProvinces() {
44
+ const provinces = [...new Set(DATA.map(d => d.province))].sort();
45
+ const selProvince = document.getElementById('province');
46
+ provinces.forEach(p => {
47
+ const opt = document.createElement('option');
48
+ opt.value = p; opt.textContent = p;
49
+ selProvince.appendChild(opt);
50
+ });
51
+ selProvince.addEventListener('change', updateWards);
52
+ document.getElementById('ward_new').addEventListener('change', showResult);
53
+ }
54
 
55
+ // Cập nhật danh sách phường/xã mới khi chọn tỉnh
56
+ function updateWards() {
57
+ const province = this.value;
58
+ const wardSel = document.getElementById('ward_new');
59
+ wardSel.innerHTML = '<option value="">-- Chọn Phường/Xã mới --</option>';
60
+ wardSel.disabled = !province;
61
+ if (province) {
62
+ const wards = DATA.filter(d => d.province === province)
63
+ .map(d => d.ward_new)
64
+ .filter((v,i,a) => v && a.indexOf(v) === i)
65
+ .sort((a,b) => a.localeCompare(b));
66
+ wards.forEach(w => {
67
+ const opt = document.createElement('option');
68
+ opt.value = w; opt.textContent = w;
69
+ wardSel.appendChild(opt);
70
+ });
71
+ }
72
+ document.getElementById('result').innerHTML = "";
73
+ }
74
 
75
+ // Hiển thị kết quả
76
+ function showResult() {
77
+ const province = document.getElementById('province').value;
78
+ const ward_new = this.value;
79
+ const div = document.getElementById('result');
80
+ if (!province || !ward_new) { div.innerHTML = ""; return; }
81
+ const found = DATA.find(d => d.province === province && d.ward_new === ward_new);
82
+ if (found) {
83
+ div.innerHTML = `<table>
84
+ <tr><th>Tỉnh/Thành</th><th>Phường/Xã mới</th><th>Phường/Xã trước sáp nhập</th></tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  <tr>
86
+ <td>${found.province}</td>
87
+ <td>${found.ward_new}</td>
88
+ <td>${found.ward_old ? found.ward_old : "<i>Không rõ</i>"}</td>
89
  </tr>
90
+ </table>`;
91
+ } else {
92
+ div.innerHTML = "<i>Không tìm thấy thông tin!</i>";
93
+ }
94
+ }
95
+ </script>
 
 
 
 
 
 
 
96
  </body>
97
  </html>