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 APIopsi konstruktorintegrasi Storagecontoh 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-sm pada kotak cari): ../assets/css/form.css — dipisah dari Form/form.css lewat pengecekan link[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" }, ], }, },

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 gelap body.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).

Dokumen ini selaras dengan implementasi NexaTables.js di repositori; jika API berubah, sesuaikan cuplikan dengan sumber aktual.