/* Urutkan tabel.grid dengan klik header (naik/turun). Tabel di dalam
dilewati (baris berisi isian, urutan tak relevan); baris .total selalu tetap di bawah. */ (function () { "use strict"; function nilaiSel(tr, i) { var td = tr.cells[i]; return td ? td.textContent.trim() : ""; } function sebagaiAngka(t) { // "76,2", "86 %", "18/49" → angka; "—"/kosong → null var m = t.replace(",", ".").match(/-?\d+(\.\d+)?/); return m ? parseFloat(m[0]) : null; } function pasang(tabel) { var thead = tabel.tHead; var tbody = tabel.tBodies[0]; if (!thead || !tbody || thead.rows.length !== 1) return; Array.prototype.forEach.call(thead.rows[0].cells, function (th, i) { th.classList.add("bisa-urut"); th.addEventListener("click", function () { var naik = th.dataset.arah !== "asc"; Array.prototype.forEach.call(thead.rows[0].cells, function (h) { delete h.dataset.arah; h.removeAttribute("aria-sort"); }); th.dataset.arah = naik ? "asc" : "desc"; th.setAttribute("aria-sort", naik ? "ascending" : "descending"); var baris = Array.prototype.slice.call(tbody.rows); var biasa = baris.filter(function (tr) { return !tr.classList.contains("total"); }); var total = baris.filter(function (tr) { return tr.classList.contains("total"); }); biasa.sort(function (a, b) { var ta = nilaiSel(a, i), tb = nilaiSel(b, i); var na = sebagaiAngka(ta), nb = sebagaiAngka(tb); var hasil; if (na !== null && nb !== null) hasil = na - nb; else if (na === null && nb === null) hasil = ta.localeCompare(tb, "id"); else hasil = na === null ? 1 : -1; // sel kosong/— selalu di akhir return naik ? hasil : -hasil; }); biasa.concat(total).forEach(function (tr) { tbody.appendChild(tr); }); }); }); } document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll("table.grid").forEach(function (t) { if (!t.closest("form")) pasang(t); }); }); /* Filter daftar MK saat penugasan dosen (/admin): ketik di .cari-mk menyaring .baris-mk berdasarkan kode/nama MK (data-cari). */ document.addEventListener("input", function (ev) { if (!ev.target.classList.contains("cari-mk")) return; var kata = ev.target.value.trim().toLowerCase(); var wadah = ev.target.nextElementSibling; // .pilih-sub tepat setelah input cari if (!wadah) return; var ada = false; wadah.querySelectorAll(".baris-mk").forEach(function (baris) { var cocok = !kata || baris.dataset.cari.indexOf(kata) !== -1; baris.style.display = cocok ? "" : "none"; if (cocok) ada = true; }); var kosong = wadah.querySelector(".cari-kosong"); if (kosong) kosong.style.display = ada ? "none" : ""; }); /* Tabel rencana mingguan RPS (#tabel-f): kolomnya sempit untuk 9 kolom x 16 baris, jadi textarea-nya kecil sekali. Saat fokus, textarea membesar dan "mengambang" (position:fixed) di atas sel-sel lain tanpa mengubah lebar tabel; kembali normal saat pindah fokus. */ var grAktif = null; function grBesarkan(el) { if (grAktif === el) return; if (grAktif) grKecilkan(grAktif); var r = el.getBoundingClientRect(); el.dataset.grLebar = el.style.width; el.dataset.grTinggi = el.style.height; el.style.position = "fixed"; el.style.left = r.left + "px"; el.style.top = r.top + "px"; el.style.width = Math.max(r.width, 380) + "px"; el.style.height = Math.max(r.height, 140) + "px"; el.style.zIndex = "50"; el.style.boxShadow = "0 6px 18px rgba(0,0,0,.35)"; el.style.background = "#fff"; grAktif = el; } function grKecilkan(el) { el.style.position = ""; el.style.left = ""; el.style.top = ""; el.style.width = el.dataset.grLebar || ""; el.style.height = el.dataset.grTinggi || ""; el.style.zIndex = ""; el.style.boxShadow = ""; el.style.background = ""; if (grAktif === el) grAktif = null; } document.addEventListener("focusin", function (ev) { if (ev.target.matches && ev.target.matches("#tabel-f textarea")) { grBesarkan(ev.target); } }); document.addEventListener("focusout", function (ev) { if (ev.target === grAktif) grKecilkan(ev.target); }); /* Hover di sel (bukan langsung di textarea): elemen