NX.NexaTables
— NexaTables
Panduan komponen tabel data di NXDOM: NexaTables menampilkan array objek (misalnya dari
NX.Storage) dengan pencarian teks, sort kolom, dan
paginasi, berlapis styling table.css.
Bukan plugin jQuery DataTables pihak ketiga; filter/sort/halaman diimplementasikan di NexaTables
dengan kelas CSS proyek (nx-table, nx-table-pagination, dll.).
Alur belajar: akses API → opsi konstruktor → integrasi Storage → contoh rute. Grid layout: NexaGrid; data API: Storage().
1. Akses API
Setelah assets/modules/nxdom.js dimuat, komponen tersedia di NX:
| Akses | Keterangan |
|---|---|
NX.NexaTables |
Kelas utama |
NX.Tables |
Alias ke NexaTables |
NX.ensureTableStylesheet |
Memuat table.css sekali |
NX.rowsFromStorageResponse |
Helper normalisasi respons → array baris |
Import modul (tanpa NX):
import {
NexaTables,
ensureTableStylesheet,
rowsFromStorageResponse,
} from "/assets/modules/Tables/NexaTables.js";2. Stylesheet (ensureTableStylesheet)
table.css, assets/modules/assets/css/pagination.css, dan
assets/modules/assets/css/form.css direferensikan dengan URL stabil lewat
import.meta.url:
- Tabel:
new URL("./table.css", import.meta.url).href - Paginasi (
.pagination,.page-item,.page-link):../assets/css/pagination.css - Form (mis.
.form-nexa-control-smpada kotak cari):../assets/css/form.css— dipisah dariForm/form.csslewat pengecekanlink[href*="assets/css/form.css"]
ensureTableStylesheet() menunggu NX.NexaStylesheet.Dom, lalu memuat hanya file yang
belum ada di DOM (deduplikasi lewat link[href*="…"]).
mount() pada instance otomatis await ensureTableStylesheet() terlebih dahulu. Manual:
await NX.ensureTableStylesheet();Modul juga menjalankan prefetch ringan saat dievaluasi (setTimeout + catch kosong), mirip pola form/modal.
3. Opsi konstruktor
| Properti | Tipe / default | Keterangan |
|---|---|---|
container |
string | Element — wajib |
Selector atau elemen induk; isinya diganti saat mount() |
data |
Array<object> — [] |
Baris tabel; biasanya objek datar |
columns |
{ key, title? }[] — otomatis |
Jika kosong, kunci dari gabungan kunci objek pada data |
pageSize |
number — 10 |
Baris per halaman (min 1) |
searchable |
boolean — true |
Kotak pencarian (substring pada nilai sel) |
sortable |
boolean — true |
Klik header untuk sort; kelas nx-table-sortable |
tableClass |
string | Gabungan kelas pada <table> |
wrapperClass |
string — "" |
Pembungkus luar opsional |
caption |
string — "" |
Teks <caption> |
formatCell |
(value, key, row) => string |
Override render teks sel; aman untuk textContent |
paginationActiveBg / Border / Color |
string | null | Override tampilan tombol halaman aktif (pagination.css) |
export |
object | false | Tombol download: enabled, types (csv/json/xlsx/pdf), include (filtered/all/page), fileName |
pageSizeOptions |
number[] — [10,25,50,100] |
Dropdown entries per page |
spinner |
object | false | Saat load storage.model di mount(); bentuk mirip spinner NexaDom |
columnMenu |
boolean — true |
Dropdown per kolom: filter Contains, sort, clear |
actions |
object | false | Dropdown aksi per baris: view, add, edit, delete, export, import, print, share |
actionsColumnTitle |
string — "Actions" |
Judul kolom aksi |
onAction |
(action, row) => void | null |
Callback aksi baris |
editing |
object | Inline editing per kolom — lihat §3.4 |
onEdit |
(key, value, row) => void | null |
Hanya saat nilai benar-benar berubah setelah inline edit |
rowNumberColumn |
boolean — false |
Kolom pertama penomoran per halaman |
rowNumberColumnTitle |
string — "No." |
Judul kolom nomor |
hideColumnKeys |
string[] — [] |
Kunci disembunyikan di tabel & ekspor (nilai tetap di objek baris) |
3.1 Contoh opsi export
const t = new NX.NexaTables({
container: "#wrap",
data: rows,
caption: "Inventori",
pageSize: 10,
export: {
enabled: true,
types: ["csv", "json", "xlsx", "pdf"],
include: "filtered",
fileName: "Inventori",
},
});
await t.mount();3.2 Column menu (filter dropdown)
Jika columnMenu: true (default), header sortable menampilkan ikon menu per kolom: filter
Contains, sort naik/turun, Clear sort.
Praktik: untuk data besar dari API, batasi jumlah baris di klien (mis. .slice(0, 50))
sebelum data.
3.3 Row actions (dropdown)
Jika actions aktif, kolom terakhir dengan judul actionsColumnTitle. Tanpa
onAction, event nexa-table-action di-dispatch dari container dengan
detail: { action, row }.
const t = new NX.NexaTables({
container: "#wrap",
data: rows,
caption: "User",
actions: { edit: true, delete: true, view: true },
onAction: (action, row) => {
console.log("action:", action, "row:", row);
},
});
await t.mount();3.4 Inline editing (editing + onEdit)
Klik sel → editor sesuai tipe; setelah Enter / blur / pilih opsi, onEdit hanya jika nilai berubah.
Tipe editor: text, number (+ min/max/step), checkbox,
select (+ options; Select2 jika NX.initSelect2 tersedia),
textarea (+ rows), search (Select2 seperti select; opsi default = nilai unik kolom),
email, password, tel, url, date,
datetime-local, time, color, range.
Untuk select dan search, komit saat value berubah; dengan Select2, handler memastikan
onEdit terpanggil saat select2:select.
const t = new NX.NexaTables({
container: "#wrap",
data: [{ id: 1, text: "Halo", number: 10, role: "admin", /* … */ }],
columns: [
{ key: "id", title: "ID" },
{ key: "text", title: "text" },
{ key: "number", title: "number" },
{ key: "role", title: "select" },
],
editing: {
text: { type: "text" },
number: { type: "number", min: 0, max: 100, step: 1 },
role: { type: "select", options: ["admin", "editor", "viewer"] },
},
onEdit: (key, value, row) => {
console.log("NexaTables row edit:", key, value, row);
},
});
await t.mount();Cuplikan select
editing: {
role: {
type: "select",
options: ["admin", "editor", "viewer"],
},
kategori: {
type: "select",
options: [
{ value: "1", label: "Elektronik" },
{ value: "2", label: "Furniture" },
],
},
},Cuplikan search
Bukan <input type="search">; <select> + Select2. Tanpa options, opsi = nilai unik kolom dari data.
editing: {
tag: { type: "search" },
},
// atau override:
editing: {
tag: { type: "search", options: ["query 1", "query 2", "lainnya"] },
},4. Data dari NX.Storage
Helper mengubah berbagai bentuk respons menjadi satu array untuk data:
| Input | Hasil |
|---|---|
| Array | Apa adanya |
{ data: [...] } |
data |
{ response: [...] } |
response |
{ rows: [...] } |
rows |
| Lain / null | [] |
const res = await NX.Storage().example().news({ news: 1 });
const rows = NX.rowsFromStorageResponse(res);
const t = new NX.NexaTables({
container: "#wrap",
data: rows,
caption: "News",
});
await t.mount();
// Factory static:
const t2 = await NX.NexaTables.fromStorageResponse("#wrap", res, {
caption: "News",
pageSize: 8,
});4.1 fromStorage — GET / POST / api
load.method |
Pemanggilan |
|---|---|
get (default) |
Storage().get(load.url || load.path, load.options || load.query) |
post |
Storage().post(load.path || load.url, load.body, load.fetchOptions) |
api |
Storage().api(load.path || load.apiPath, load.body || load.apiBody) — POST ke baseAPI |
acceptObjectAsRow: jika true dan array baris kosong, satu objek di data
dibungkus jadi satu baris — berguna untuk { status, data: { … } }.
const t = await NX.NexaTables.fromStorage(
"#wrap",
{ method: "get", url: NEXA.typicode },
{ caption: "Typicode", pageSize: 25 }
);
const t2 = await NX.NexaTables.fromStorage(
"#wrap2",
{
method: "api",
path: "test",
body: { title: "Halo", slug: "halo" },
acceptObjectAsRow: true,
},
{ caption: "API test" }
);
vs NexaDom (storage: { model, query }): NexaDom memuat data + merender HTML
lewat render; NexaTables memakai array baris dan komponen tabel bawaan.
Contoh spinner saat load model (opsi spinner di konstruktor + storage.model + query) — lihat templates/tables.js.
4.2 fromBuckets — query app
Federated / bucket dengan objek app (alias, aliasNames,
tabelName, operasi, …): NexaTables.fromBuckets(container, app, getOptions?, tableOptions?)
memanggil NX.Storage().buckets(app).get(getOptions), lalu fromStorageResponse.
Di NexaDom dengan fromBuckets definisi join ada di app; tidak ada
query: (q) => … di opsi NexaTables untuk jalur ini.
const app = {
alias: ["user.status AS status", "user.nama AS nama", /* … */],
aliasNames: ["status", "nama", "jabatan", "avatar", "id"],
tabelName: ["user"],
where: false,
group: false,
order: false,
operasi: { /* … */ },
access: "public",
id: 1,
};
const t = await NX.NexaTables.fromBuckets("#wrap", app, { limit: 50 }, {
caption: "User (buckets)",
pageSize: 8,
columns: [
{ key: "id", title: "ID" },
{ key: "nama", title: "Nama" },
{ key: "status", title: "Status" },
],
});Lihat templates/tables.js (demo nomor 4).
5. Metode instance
5.1 mount
Async: stylesheet, kosongkan container, filter (jika searchable), <table>, paginasi, event. Panggil sekali setelah konstruktor.
5.2 fromStorageResponse (static)
NexaTables.fromStorageResponse(container, storageResult, options?) — rowsFromStorageResponse + new NexaTables + mount(). Mengembalikan Promise<NexaTables>.
5.3 setData
setData(rows) mengganti dataset, reset sort default, halaman 0, re-render tanpa rebuild DOM luar.
5.4 destroy
destroy() melepas listener, kosongkan container. Penting untuk SPA / navigasi route.
6. Contoh referensi di proyek
| Lokasi | Isi |
|---|---|
templates/tables.js |
Rute /tables: statis, fromStorage, storage.model + query, fromBuckets, columns + formatCell |
templates/about.js |
fromStorageResponse untuk hasil Storage / model |
Pastikan App.js menyertakan rute ke template tersebut (mis. 'tables').
7. Kelas CSS utama (table.css)
- Dasar:
.nx-table,.nx-table-bordered,.nx-table-striped,.nx-table-hover - Ukuran:
.nx-table-compact,.nx-table-sm,.nx-table-md, … - Komponen:
.nx-table-filter,.form-nexa-group.form-nexa-icon,.nx-table-sortable th.sortable,.nx-table-pagination,.pagination - Tema:
:root; mode gelapbody.dark-mode-grid …
Override: tableClass / wrapperClass di konstruktor.
8. Checklist troubleshooting
| Gejala | Yang dicek |
|---|---|
| Container kosong / tidak ditemukan | Selector ada di DOM setelah innerHTML; isi HTML dulu, baru new NexaTables |
| Tanpa gaya | nxdom.js sudah load; await ensureTableStylesheet() atau await mount() |
| Kolom salah / kosong | Objek baris konsisten; set columns eksplisit jika kunci beda antar-baris |
| Sort/filter aneh pada objek bersarang | Non-primitif di-stringkan; pakai formatCell untuk tampilan |
| Performa lambat | Kurangi baris di klien; pertimbangkan paginasi server |
| Duplikat event setelah pindah halaman | destroy() pada instance lama di handler route |
Berkas implementasi
assets/modules/Tables/NexaTables.js, stylesheet assets/modules/Tables/table.css (+
pagination.css, form.css lewat ensureTableStylesheet).
NexaTables.js di repositori; jika API berubah, sesuaikan
cuplikan dengan sumber aktual.