Update script.js
Browse files
script.js
CHANGED
|
@@ -10,6 +10,9 @@ const COLUMNS = [
|
|
| 10 |
{ key: "اسم المسح", label: "اسم المسح" },
|
| 11 |
];
|
| 12 |
|
|
|
|
|
|
|
|
|
|
| 13 |
function normalize(value){
|
| 14 |
return String(value ?? "")
|
| 15 |
.toLowerCase()
|
|
@@ -21,6 +24,9 @@ function normalize(value){
|
|
| 21 |
.replace(/\s+/g," ");
|
| 22 |
}
|
| 23 |
|
|
|
|
|
|
|
|
|
|
| 24 |
function esc(value){
|
| 25 |
return String(value ?? "")
|
| 26 |
.replace(/&/g,"&")
|
|
@@ -30,36 +36,41 @@ function esc(value){
|
|
| 30 |
.replace(/'/g,"'");
|
| 31 |
}
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
if(!q || q.length < 2) return text;
|
| 38 |
-
|
| 39 |
-
const safeQ = q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
| 40 |
-
const regex = new RegExp(`(${safeQ})`, "gi");
|
| 41 |
-
|
| 42 |
-
return text.replace(regex, `<mark>$1</mark>`);
|
| 43 |
-
}
|
| 44 |
-
|
| 45 |
function getStatusClass(status){
|
| 46 |
const s = normalize(status);
|
| 47 |
|
| 48 |
-
if(s.includes("
|
| 49 |
return "status success";
|
| 50 |
}
|
| 51 |
|
| 52 |
-
if(s.includes("
|
| 53 |
return "status warning";
|
| 54 |
}
|
| 55 |
|
| 56 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
return "status danger";
|
| 58 |
}
|
| 59 |
|
| 60 |
return "status";
|
| 61 |
}
|
| 62 |
|
|
|
|
|
|
|
|
|
|
| 63 |
function getScore(row, q){
|
| 64 |
const name = normalize(row["إسم المنشأة"]);
|
| 65 |
const cr = normalize(row["السجل التجاري"]);
|
|
@@ -71,7 +82,10 @@ function getScore(row, q){
|
|
| 71 |
return 99;
|
| 72 |
}
|
| 73 |
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
| 75 |
const total = Array.isArray(DATA) ? DATA.length : 0;
|
| 76 |
counter.textContent = `${rows.length} نتيجة من أصل ${total}`;
|
| 77 |
|
|
@@ -96,9 +110,13 @@ function render(rows, query){
|
|
| 96 |
<tbody>
|
| 97 |
${rows.map(row => `
|
| 98 |
<tr>
|
| 99 |
-
<td>${
|
| 100 |
-
<td>${
|
| 101 |
-
<td>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
<td>${esc(row["اسم المسح"] || "—")}</td>
|
| 103 |
</tr>
|
| 104 |
`).join("")}
|
|
@@ -110,14 +128,16 @@ function render(rows, query){
|
|
| 110 |
${rows.map(row => `
|
| 111 |
<article class="resultCard">
|
| 112 |
<div class="cardTop">
|
| 113 |
-
<h3>${
|
| 114 |
-
<span class="${getStatusClass(row["حالة العينة"])}">
|
|
|
|
|
|
|
| 115 |
</div>
|
| 116 |
|
| 117 |
<div class="cardInfo">
|
| 118 |
<div>
|
| 119 |
<span>السجل التجاري</span>
|
| 120 |
-
<strong>${
|
| 121 |
</div>
|
| 122 |
<div>
|
| 123 |
<span>اسم المسح</span>
|
|
@@ -137,11 +157,11 @@ function render(rows, query){
|
|
| 137 |
`;
|
| 138 |
}
|
| 139 |
|
|
|
|
|
|
|
|
|
|
| 140 |
function search(){
|
| 141 |
-
const
|
| 142 |
-
const q = normalize(rawQuery);
|
| 143 |
-
|
| 144 |
-
localStorage.setItem("lastSearchEQ2026", rawQuery);
|
| 145 |
|
| 146 |
if(!q){
|
| 147 |
counter.textContent = "النتائج: 0";
|
|
@@ -161,24 +181,29 @@ function search(){
|
|
| 161 |
const cr = normalize(row["السجل التجاري"]);
|
| 162 |
const status = normalize(row["حالة العينة"]);
|
| 163 |
|
| 164 |
-
// استبعاد
|
| 165 |
if(status.includes("جديد")) return false;
|
| 166 |
|
| 167 |
return name.includes(q) || cr.includes(q);
|
| 168 |
})
|
| 169 |
.sort((a,b) => getScore(a,q) - getScore(b,q));
|
| 170 |
|
| 171 |
-
render(filtered
|
| 172 |
}
|
| 173 |
|
|
|
|
|
|
|
|
|
|
| 174 |
function clearSearch(){
|
| 175 |
input.value = "";
|
| 176 |
-
localStorage.removeItem("lastSearchEQ2026");
|
| 177 |
counter.textContent = "النتائج: 0";
|
| 178 |
results.innerHTML = `<div class="empty">ابدأ بكتابة اسم المنشأة أو السجل التجاري.</div>`;
|
| 179 |
input.focus();
|
| 180 |
}
|
| 181 |
|
|
|
|
|
|
|
|
|
|
| 182 |
let debounceTimer;
|
| 183 |
|
| 184 |
input.addEventListener("input", () => {
|
|
@@ -188,14 +213,9 @@ input.addEventListener("input", () => {
|
|
| 188 |
|
| 189 |
clearBtn.addEventListener("click", clearSearch);
|
| 190 |
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
input.value = lastSearch;
|
| 195 |
-
search();
|
| 196 |
-
}
|
| 197 |
-
});
|
| 198 |
-
|
| 199 |
if(!Array.isArray(DATA)){
|
| 200 |
results.innerHTML = `<div class="empty">ملف data.js غير صحيح.</div>`;
|
| 201 |
}
|
|
|
|
| 10 |
{ key: "اسم المسح", label: "اسم المسح" },
|
| 11 |
];
|
| 12 |
|
| 13 |
+
// =========================
|
| 14 |
+
// تنظيف النص
|
| 15 |
+
// =========================
|
| 16 |
function normalize(value){
|
| 17 |
return String(value ?? "")
|
| 18 |
.toLowerCase()
|
|
|
|
| 24 |
.replace(/\s+/g," ");
|
| 25 |
}
|
| 26 |
|
| 27 |
+
// =========================
|
| 28 |
+
// حماية النص
|
| 29 |
+
// =========================
|
| 30 |
function esc(value){
|
| 31 |
return String(value ?? "")
|
| 32 |
.replace(/&/g,"&")
|
|
|
|
| 36 |
.replace(/'/g,"'");
|
| 37 |
}
|
| 38 |
|
| 39 |
+
// =========================
|
| 40 |
+
// لون الحالة (بدون تغيير النص)
|
| 41 |
+
// =========================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
function getStatusClass(status){
|
| 43 |
const s = normalize(status);
|
| 44 |
|
| 45 |
+
if(s.includes("اعطت كامل البيانات")){
|
| 46 |
return "status success";
|
| 47 |
}
|
| 48 |
|
| 49 |
+
if(s.includes("اعطت بعض البيانات") || s.includes("استيفاء ذاتي")){
|
| 50 |
return "status warning";
|
| 51 |
}
|
| 52 |
|
| 53 |
+
if(
|
| 54 |
+
s.includes("رفض") ||
|
| 55 |
+
s.includes("مغلق") ||
|
| 56 |
+
s.includes("لم يعثر") ||
|
| 57 |
+
s.includes("انتقلت") ||
|
| 58 |
+
s.includes("تحولت") ||
|
| 59 |
+
s.includes("خارج نطاق") ||
|
| 60 |
+
s.includes("لم تمارس") ||
|
| 61 |
+
s.includes("غير متاح") ||
|
| 62 |
+
s.includes("يطالب") ||
|
| 63 |
+
s.includes("اخري")
|
| 64 |
+
){
|
| 65 |
return "status danger";
|
| 66 |
}
|
| 67 |
|
| 68 |
return "status";
|
| 69 |
}
|
| 70 |
|
| 71 |
+
// =========================
|
| 72 |
+
// ترتيب النتائج
|
| 73 |
+
// =========================
|
| 74 |
function getScore(row, q){
|
| 75 |
const name = normalize(row["إسم المنشأة"]);
|
| 76 |
const cr = normalize(row["السجل التجاري"]);
|
|
|
|
| 82 |
return 99;
|
| 83 |
}
|
| 84 |
|
| 85 |
+
// =========================
|
| 86 |
+
// عرض النتائج
|
| 87 |
+
// =========================
|
| 88 |
+
function render(rows){
|
| 89 |
const total = Array.isArray(DATA) ? DATA.length : 0;
|
| 90 |
counter.textContent = `${rows.length} نتيجة من أصل ${total}`;
|
| 91 |
|
|
|
|
| 110 |
<tbody>
|
| 111 |
${rows.map(row => `
|
| 112 |
<tr>
|
| 113 |
+
<td>${esc(row["إسم المنشأة"] || "—")}</td>
|
| 114 |
+
<td>${esc(row["السجل التجاري"] || "—")}</td>
|
| 115 |
+
<td>
|
| 116 |
+
<span class="${getStatusClass(row["حالة العينة"])}">
|
| 117 |
+
${esc(row["حالة العينة"] || "—")}
|
| 118 |
+
</span>
|
| 119 |
+
</td>
|
| 120 |
<td>${esc(row["اسم المسح"] || "—")}</td>
|
| 121 |
</tr>
|
| 122 |
`).join("")}
|
|
|
|
| 128 |
${rows.map(row => `
|
| 129 |
<article class="resultCard">
|
| 130 |
<div class="cardTop">
|
| 131 |
+
<h3>${esc(row["إسم المنشأة"] || "—")}</h3>
|
| 132 |
+
<span class="${getStatusClass(row["حالة العينة"])}">
|
| 133 |
+
${esc(row["حالة العينة"] || "—")}
|
| 134 |
+
</span>
|
| 135 |
</div>
|
| 136 |
|
| 137 |
<div class="cardInfo">
|
| 138 |
<div>
|
| 139 |
<span>السجل التجاري</span>
|
| 140 |
+
<strong>${esc(row["السجل التجاري"] || "—")}</strong>
|
| 141 |
</div>
|
| 142 |
<div>
|
| 143 |
<span>اسم المسح</span>
|
|
|
|
| 157 |
`;
|
| 158 |
}
|
| 159 |
|
| 160 |
+
// =========================
|
| 161 |
+
// البحث
|
| 162 |
+
// =========================
|
| 163 |
function search(){
|
| 164 |
+
const q = normalize(input.value);
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
if(!q){
|
| 167 |
counter.textContent = "النتائج: 0";
|
|
|
|
| 181 |
const cr = normalize(row["السجل التجاري"]);
|
| 182 |
const status = normalize(row["حالة العينة"]);
|
| 183 |
|
| 184 |
+
// استبعاد "جديدة"
|
| 185 |
if(status.includes("جديد")) return false;
|
| 186 |
|
| 187 |
return name.includes(q) || cr.includes(q);
|
| 188 |
})
|
| 189 |
.sort((a,b) => getScore(a,q) - getScore(b,q));
|
| 190 |
|
| 191 |
+
render(filtered);
|
| 192 |
}
|
| 193 |
|
| 194 |
+
// =========================
|
| 195 |
+
// مسح
|
| 196 |
+
// =========================
|
| 197 |
function clearSearch(){
|
| 198 |
input.value = "";
|
|
|
|
| 199 |
counter.textContent = "النتائج: 0";
|
| 200 |
results.innerHTML = `<div class="empty">ابدأ بكتابة اسم المنشأة أو السجل التجاري.</div>`;
|
| 201 |
input.focus();
|
| 202 |
}
|
| 203 |
|
| 204 |
+
// =========================
|
| 205 |
+
// الأحداث
|
| 206 |
+
// =========================
|
| 207 |
let debounceTimer;
|
| 208 |
|
| 209 |
input.addEventListener("input", () => {
|
|
|
|
| 213 |
|
| 214 |
clearBtn.addEventListener("click", clearSearch);
|
| 215 |
|
| 216 |
+
// =========================
|
| 217 |
+
// تحقق من البيانات
|
| 218 |
+
// =========================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
if(!Array.isArray(DATA)){
|
| 220 |
results.innerHTML = `<div class="empty">ملف data.js غير صحيح.</div>`;
|
| 221 |
}
|