stat2025 commited on
Commit
cd250b5
·
verified ·
1 Parent(s): b5f43fe

Update script.js

Browse files
Files changed (1) hide show
  1. script.js +153 -54
script.js CHANGED
@@ -1,76 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
1
  let data = [];
2
  let filtered = [];
 
 
3
 
4
- const searchBox = document.getElementById("searchBox");
5
- const tableBody = document.getElementById("tableBody");
6
- const counter = document.getElementById("counter");
7
- const loading = document.getElementById("loading");
8
- const toggleTheme = document.getElementById("toggleTheme");
9
 
10
- // --- تحميل البيانات
11
- fetch("data.json")
12
- .then(r=>r.json())
13
- .then(json=>{
14
- data=json;
15
- filtered=data;
16
- loading.style.display="none";
17
- updateView();
18
- })
19
- .catch(()=> loading.textContent="تعذر تحميل البيانات.");
 
 
 
 
 
20
 
21
- // --- تحديث العرض
22
- function updateView(){
23
- const q=searchBox.value.trim();
24
- filtered=data.filter(it=>{
25
- return matches(it.code,q) || matches(it.activity,q);
26
- });
27
- counter.textContent="عدد الأنشطة الاقتصادية: "+filtered.length;
28
- renderTable();
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  function renderTable(){
32
- tableBody.innerHTML="";
33
- filtered.forEach(it=>{
34
- const tr=document.createElement("tr");
35
- tr.innerHTML=`<td>${it.code}</td><td>${it.activity}</td>`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  tableBody.appendChild(tr);
37
  });
38
  }
39
 
40
- function matches(text, query){
41
- if(!query) return true;
42
- return text.toString().toLowerCase().includes(query.toLowerCase());
 
 
 
 
 
43
  }
44
 
45
- searchBox.addEventListener("input", updateView);
46
-
47
- // --- نسخ الرمز عند النقر
48
- tableBody.addEventListener("click", async (e)=>{
49
- const cell = e.target.closest("td");
50
- if(!cell) return;
51
- const colIndex = [...cell.parentElement.children].indexOf(cell);
52
- if(colIndex === 0){ // أول عمود (الرمز)
53
- const text = cell.innerText.trim();
54
- try{ await navigator.clipboard.writeText(text); showToast("تم نسخ الرمز: "+text); }
55
- catch{ showToast("تعذر النسخ"); }
56
- }
57
  });
58
 
59
- function showToast(msg){
60
- let t=document.getElementById("toast");
61
- if(!t){ t=document.createElement("div"); t.id="toast"; document.body.appendChild(t); }
62
- t.textContent=msg;
63
- t.className="show";
64
- setTimeout(()=> t.className="",1500);
65
- }
66
 
67
- // --- الوضع الليلي
68
- if(localStorage.getItem("theme")==="dark"){ document.documentElement.classList.add("dark"); }
 
 
 
 
69
 
 
 
 
 
 
 
 
70
  toggleTheme.addEventListener("click", ()=>{
71
  document.documentElement.classList.toggle("dark");
72
- const mode=document.documentElement.classList.contains("dark")?"dark":"light";
73
  localStorage.setItem("theme", mode);
74
- toggleTheme.textContent= mode==="dark" ? "الوضع الفاتح ☀️" : "الوضع الليلي 🌙";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  });
76
- toggleTheme.textContent=document.documentElement.classList.contains("dark") ? "الوضع الفاتح ☀️" : "الوضع الليلي 🌙";
 
1
+ // عناصر الواجهة
2
+ const searchBox = document.getElementById("searchBox");
3
+ const clearSearch = document.getElementById("clearSearch");
4
+ const pageSizeEl = document.getElementById("pageSize");
5
+ const toggleTheme = document.getElementById("toggleTheme");
6
+ const tableBody = document.getElementById("tableBody");
7
+ const pagination = document.getElementById("pagination");
8
+ const counter = document.getElementById("counter");
9
+ const loading = document.getElementById("loading");
10
+
11
+ // حالة البيانات
12
  let data = [];
13
  let filtered = [];
14
+ let currentPage = 1;
15
+ let rowsPerPage = parseInt(pageSizeEl.value, 10);
16
 
17
+ // ألوان جانبية للعمود الثالث
18
+ const colors = ["#00bcd4","#4caf50","#f44336","#ff9800","#9c27b0","#e91e63","#009688","#3f51b5","#607d8b","#795548"];
 
 
 
19
 
20
+ // تطبيع عربي للبحث (يتجاهل التشكيل ويُوحّد الألفات/الياء/الهاء المربوطة)
21
+ function normalizeArabic(str=""){
22
+ return str
23
+ .replace(/[\u064B-\u0652]/g, "") // التشكيل
24
+ .replace(/[أإآا]/g,"ا")
25
+ .replace(/ى/g,"ي")
26
+ .replace(/ؤ/g,"و")
27
+ .replace(/ئ/g,"ي")
28
+ .replace(/ة/g,"ه")
29
+ .toLowerCase();
30
+ }
31
+ function matches(text, q){
32
+ if(!q) return true;
33
+ return normalizeArabic(String(text)).includes(normalizeArabic(q));
34
+ }
35
 
36
+ // تمييز الكلمة داخل النص
37
+ function highlight(text, q){
38
+ if(!q) return text;
39
+ const esc = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
40
+ return String(text).replace(new RegExp(esc, 'gi'), m => `<mark class="hl">${m}</mark>`);
 
 
 
41
  }
42
 
43
+ // ترقيم الصفحات
44
+ function renderPagination(){
45
+ const pages = Math.ceil(filtered.length / rowsPerPage);
46
+ pagination.innerHTML = "";
47
+ if (pages <= 1) return;
48
+
49
+ const makeBtn = (label, page, active=false, disabled=false)=>{
50
+ const b = document.createElement("button");
51
+ b.textContent = label;
52
+ b.className = "page-btn" + (active ? " active" : "");
53
+ b.disabled = disabled;
54
+ b.addEventListener("click", ()=>{ currentPage = page; updateView(); window.scrollTo({top:0, behavior:"smooth"}); });
55
+ return b;
56
+ };
57
+
58
+ pagination.appendChild(makeBtn("‹ السابق", Math.max(1, currentPage-1), false, currentPage===1));
59
+
60
+ const windowSize = 5;
61
+ const total = pages;
62
+ let start = Math.max(1, currentPage - Math.floor(windowSize/2));
63
+ let end = Math.min(total, start + windowSize - 1);
64
+ if (end - start + 1 < windowSize) start = Math.max(1, end - windowSize + 1);
65
+
66
+ if (start > 1) pagination.appendChild(makeBtn("1", 1, currentPage===1));
67
+ if (start > 2) pagination.appendChild(Object.assign(document.createElement("span"), {className:"dots", textContent:"..."}));
68
+ for (let p=start; p<=end; p++) pagination.appendChild(makeBtn(String(p), p, p===currentPage));
69
+ if (end < total - 1) pagination.appendChild(Object.assign(document.createElement("span"), {className:"dots", textContent:"..."}));
70
+ if (end < total) pagination.appendChild(makeBtn(String(total), total, currentPage===total));
71
+
72
+ pagination.appendChild(makeBtn("التالي ›", Math.min(total, currentPage+1), false, currentPage===total));
73
+ }
74
+
75
+ // عرض الجدول لصفحة واحدة
76
  function renderTable(){
77
+ const q = searchBox.value.trim();
78
+ tableBody.innerHTML = "";
79
+
80
+ const start = (currentPage - 1) * rowsPerPage;
81
+ const pageItems = filtered.slice(start, start + rowsPerPage);
82
+
83
+ if (pageItems.length === 0) {
84
+ const tr = document.createElement("tr");
85
+ const td = document.createElement("td");
86
+ td.colSpan = 3;
87
+ td.textContent = "لا توجد نتائج مطابقة.";
88
+ td.style.textAlign = "center";
89
+ td.style.color = "#888";
90
+ tr.appendChild(td);
91
+ tableBody.appendChild(tr);
92
+ return;
93
+ }
94
+
95
+ pageItems.forEach((it, i)=>{
96
+ const tr = document.createElement("tr");
97
+
98
+ const codeTd = document.createElement("td");
99
+ codeTd.innerHTML = highlight(it.code ?? "", q);
100
+
101
+ const actTd = document.createElement("td");
102
+ actTd.innerHTML = highlight(it.activity ?? "", q);
103
+
104
+ const colorTd = document.createElement("td");
105
+ const colorBar = document.createElement("div");
106
+ colorBar.className = "color-bar";
107
+ colorBar.style.backgroundColor = colors[i % colors.length];
108
+ colorTd.appendChild(colorBar);
109
+
110
+ tr.appendChild(codeTd);
111
+ tr.appendChild(actTd);
112
+ tr.appendChild(colorTd);
113
  tableBody.appendChild(tr);
114
  });
115
  }
116
 
117
+ // تحديث العرض (تصفية + عداد + جدول + ترقيم)
118
+ function updateView(){
119
+ const q = searchBox.value.trim();
120
+ filtered = data.filter(it => matches(it.code, q) || matches(it.activity, q));
121
+ counter.textContent = `عدد الأنشطة الاقتصادية: ${filtered.length.toLocaleString()}`;
122
+ loading.style.display = "none";
123
+ renderTable();
124
+ renderPagination();
125
  }
126
 
127
+ // زر مسح البحث
128
+ clearSearch.addEventListener("click", ()=>{
129
+ searchBox.value = "";
130
+ searchBox.focus();
131
+ currentPage = 1;
132
+ updateView();
 
 
 
 
 
 
133
  });
134
 
135
+ // بحث بتأخير بسيط (يقلل الضغط على الجوال)
136
+ function debounce(fn, delay=200){ let t; return (...a)=>{ clearTimeout(t); t=setTimeout(()=>fn(...a), delay); }; }
137
+ searchBox.addEventListener("input", debounce(()=>{
138
+ currentPage = 1;
139
+ updateView();
140
+ }, 180));
 
141
 
142
+ // تغيير حجم الصفحة
143
+ pageSizeEl.addEventListener("change", ()=>{
144
+ rowsPerPage = parseInt(pageSizeEl.value, 10);
145
+ currentPage = 1;
146
+ updateView();
147
+ });
148
 
149
+ // الوضع الليلي اختياري (لا تشغيل تلقائي)
150
+ if (localStorage.getItem("theme")==="dark") {
151
+ document.documentElement.classList.add("dark");
152
+ toggleTheme.textContent = "الوضع الفاتح ☀️";
153
+ } else {
154
+ toggleTheme.textContent = "الوضع الليلي 🌙";
155
+ }
156
  toggleTheme.addEventListener("click", ()=>{
157
  document.documentElement.classList.toggle("dark");
158
+ const mode = document.documentElement.classList.contains("dark") ? "dark" : "light";
159
  localStorage.setItem("theme", mode);
160
+ toggleTheme.textContent = mode==="dark" ? "الوضع الفاتح ☀️" : "الوضع الليلي 🌙";
161
+ });
162
+
163
+ // تحميل البيانات مرة واحدة
164
+ fetch("data.json")
165
+ .then(r=>r.json())
166
+ .then(json=>{
167
+ data = json;
168
+ updateView();
169
+ })
170
+ .catch(()=>{ if(loading) loading.textContent="تعذر تحميل البيانات."; });
171
+
172
+ // اختصار لوحة مفاتيح لسهولة الوصول للبحث
173
+ document.addEventListener("keydown", (e)=>{
174
+ if(e.key==="/"){ e.preventDefault(); searchBox.focus(); }
175
  });