NX.Modal — Modal
NX.Modal membangun DOM modal (implementasi modalHTML di
assets/modules/modal/NexaModalHtml.js); NX.Modal.open /
NX.Modal.close membuka dan menutup. Minimize, restore, dan API lanjutan pada
instance: NX.nexaModal. Stylesheet inti: NexaModal.js,
modal.css (lewat nxdom.js).
Form di modal: HTML statis (content) atau floating (NexaFloating —
sama seperti NX.Form). Validasi footer:
setDataBy.form + onclick.validation. Wizard di modal:
NexaWizard § modal.
1. Peran modul
| Sumber | Fungsi |
|---|---|
nxdom.js |
Menggabungkan API ke window.NX (NX.Modal + .open /
.close, NX.nexaModal, NX.ensureModalStylesheet) dan ekspor ESM.
|
modal/NexaModalHtml.js |
modalHTML(data): DOM modal (body content atau floating), footer +
NexaValidation, collectFormData lokal.
|
modal/NexaModal.js |
Instance nexaModal: buka/tutup, minimize/restore, taskbar, IndexedDB state minimasi, helper
global redModal, closeModal, dll.
|
2. Prasyarat halaman
nxdom.jsdimuat sehinggawindow.NX(dan biasanyawindow.nx) tersedia.-
Untuk penempatan modal sebelum konten utama, sediakan
#nexa_main. Tanpa itu, modal disisipkan kedocument.body. -
ID modal harus unik di dokumen (mis.
"setModal_" + id→setModal_modal1).
3. Alur standar (buka modal dinamis)
await NX.Modal({ … })denganelementById= ID root.nx-modal.await NX.Modal.open(elementById)dengan ID yang sama.
Tanpa langkah (2), elemen ada di DOM tetapi belum dalam state “terbuka” yang dikelola sistem modal.
const modalID = "setModal_modal1";
await NX.Modal({
elementById: modalID,
styleClass: "w-500px",
minimize: true,
label: "Modal",
content: "<div><p>Konten HTML</p></div>",
setDataBy: false,
getFormBy: false,
getValidationBy: false,
onclick: {
title: "Save Settings",
cancel: "Cancel",
send: "saveGroupByModal",
},
});
await NX.Modal.open(modalID);4. Integrasi dengan route Nexa
4.1 Mendaftarkan halaman
Di modul route, route.register(…) + container.innerHTML. Contoh resmi:
templates/modal.js (rute /modal) — floating +
setDataBy.form (selaras templates/form.js).
4.2 Handler di nx (Proxy Nexa)
Fungsi di nx.* disinkronkan ke window.*. Di templates/modal.js:
nx.openModalFloatingDemo, nx.saveModalFormSubmit, alias nx.redModal agar
pemanggilan lama seperti redModal('modal1') tetap jalan.
4.3 Handler submit footer
onclick.send adalah string nama fungsi. Urutan resolusi (sama NexaForm):
window → NX → nx → nx._global.
nx.saveModalFormSubmit = async function (modalId, formData, setDataBy) {
console.log({ modalId, formData, setDataBy });
await NX.Modal.close(modalId);
};Signature: (modalId, formData, setDataBy) — argumen ketiga dari setDataBy di konfigurasi NX.Modal({ … }).
5. API NX yang relevan
| API | Deskripsi |
|---|---|
NX.Modal(data) |
async — buat/perbarui DOM modal ber-ID data.elementById, muat CSS bila perlu. |
NX.Modal.open(id, data?) |
async — buka modal (delegasi ke instance internal). |
NX.Modal.close(id, force?) |
async — tutup modal. |
NX.nexaModal |
Instance penuh NexaModal — minimize, restore, toggleMinimize, dll. |
NX.ensureModalStylesheet() |
async — pastikan modal.css terpasang. |
import { Modal, ensureModalStylesheet } from ".../nxdom.js";6. Objek konfigurasi NX.Modal(…)
6.1 Properti utama
| Properti | Deskripsi |
|---|---|
elementById |
Wajib disarankan. ID root .nx-modal. Default internal "myModal". |
content |
HTML body jika floating tidak diisi. |
floating |
Skema NexaFloating (form, variables, id / modalid). Lihat §6.3. |
label |
Judul header (h5.nx-modal-title). |
styleClass |
Kelas tambahan pada .nx-modal-dialog (mis. w-500px). |
minimize |
true → tombol minimize di header. |
showMinimize |
Hanya jika minimize: true — modal langsung minimized (taskbar) saat dibuat. |
minimizedBg, paddingTop, bodyPadding |
Layout / styling taskbar & body. |
setDataBy |
Diteruskan ke callback submit (argumen ketiga). Untuk validasi floating: sertakan setDataBy.form. |
getFormBy |
false atau array (["id"], ["name"], …) untuk collectFormData. |
getValidationBy |
Bersama NexaValidation bila validasi footer aktif. |
footer |
HTML opsional kiri footer (.nx-footer-custom). |
onclick |
Jika ada dan onclick.send terisi → footer Cancel + Save. |
callback |
{ method?, data? } → atribut data-callback-* pada elemen modal. |
wizard |
Alih-alih floating: body wizard; footer modal default tidak dibuat — lihat NexaWizard. |
6.2 Objek onclick (footer)
| Field | Deskripsi |
|---|---|
cancel |
Label batal (closeModal). |
title |
Label tombol utama (save). |
send |
String nama handler (bukan referensi fungsi). |
validation |
Aturan validasi; digabung dengan setDataBy.form / storage.form; key bentrok ditimpa onclick.validation. Truthy atau getValidationBy mengaktifkan NexaValidation. |
Tanpa onclick atau tanpa onclick.send, footer default tidak dibuat.
6.3 Body: content atau floating
Prioritas di NexaModalHtml.js (sama NexaForm):
- Jika
floatingada →new NexaFloating(data.floating, { formById: …, mode: "insert" })→innerHTML = template.html(). - Jika tidak →
content(string HTML) atau kosong.
Struktur floating: form, variables, id, settings, dll. — mengikuti NexaFloating.js.
6.4 Validasi setDataBy.form / storage.form
Objek validasi untuk Validation() digabung dari storage.form atau
setDataBy.form (hanya condition: true) + onclick.validation (override).
Pola disarankan: floating + setDataBy.form + onclick.validation: {} —
selaras templates/form.js dan templates/modal.js.
7. Global helper dari NexaModal.js (window)
| Global | Peran |
|---|---|
redModal(modalId, data?) |
Bisa di-hook via window.redModal; default memicu pembuka modal. |
closeModal(modalId) |
Tutup modal. |
closeAllModals() |
Tutup semua modal aktif. |
minimizeModal / restoreModal / toggleMinimizeModal |
Kontrol minimize. |
window.nexaModal |
Sama dengan NX.nexaModal. |
Event kustom: nexaModalOpened, nexaModalRestored, dll. — lihat NexaModal.js.
8. Fitur perilaku sistem modal
- Buka/tutup & animasi: z-index, backdrop, multi-modal sesuai opsi.
- Minimize & taskbar: item di
#minimized-modals; klik restore; close pada item. - Persistensi: state minimized bisa ke IndexedDB (restore setelah refresh) sesuai opsi.
-
Validasi: jika
onclick.validationtruthy ataugetValidationByaktif → NexaValidation; setelah suksescollectFormData→ handlersend(perilaku modal saat ini, bukanresult.responseseperti variasi NexaForm tertentu — ikuti implementasi aktual). - Tanpa validasi: save memanggil
collectFormData(modalId, getFormBy). - Duplikat ID: elemen lama dengan ID sama dihapus sebelum modal baru ditambahkan.
- Stylesheet:
ensureModalStylesheetmenungguNexaStylesheet.Dombila ada.
9. Checklist debugging
- Error di
NX.Modal→try/catch; sering HTML tidak valid atau dependensi validasi. - Modal tidak terlihat setelah
Modal({…})→ panggilModal.open(id); id harus sama denganelementById. - Save tidak memanggil handler → nama
onclick.sendada dinx/NX/window. getFormBy: falsemengubah koleksi default — sesuaikan atau pakai array eksplisit.
10. Contoh kode
10.1 Layout dengan #nexa_main
<main>
<div id="nexa_main"></div>
</main>Modal disisipkan sebelum #nexa_main jika ada; jika tidak, ke body.
10.2 Modal tanpa footer
await NX.Modal({
elementById: "setModal_info",
styleClass: "w-400px",
minimize: false,
label: "Informasi",
content: "<div><p>Hanya tombol tutup (X) di header.</p></div>",
});
await NX.Modal.open("setModal_info");10.3 Form + getFormBy: ["id"]
nx.openContactForm = async function () {
const modalID = "setModal_contact";
await NX.Modal({
elementById: modalID,
styleClass: "w-560px",
minimize: true,
label: "Edit kontak",
setDataBy: null,
getFormBy: ["id"],
getValidationBy: false,
onclick: { title: "Simpan", cancel: "Batal", send: "saveContactModal" },
content: `… input id="contact_name" … id="contact_email" …`,
});
await NX.Modal.open(modalID);
};
nx.saveContactModal = async function (modalId, formData, setDataBy) {
console.log("Data:", formData);
await NX.Modal.close(modalId);
};10.4 Buka / tutup / minimize
await NX.Modal.open("setModal_modal1");
await NX.Modal.close("setModal_modal1");
window.minimizeModal("setModal_modal1");
window.restoreModal("setModal_modal1");10.5 Import ESM
import { Modal, nexaModal } from "/modules/nxdom.js";
await Modal({ elementById: id, styleClass: "w-480px", label: "Dari ESM", content: "<p>Halo.</p>" });
await Modal.open(id);10.6 Langsung minimized (taskbar)
await NX.Modal({
elementById: "setModal_bg",
styleClass: "w-400px",
minimize: true,
showMinimize: true,
label: "Background task",
minimizedBg: "#0d6efd",
content: "<p>Langsung ke taskbar.</p>",
onclick: { title: "OK", cancel: "Tutup", send: "ackBackgroundModal" },
});
await NX.Modal.open("setModal_bg");10.7 floating + NexaValidation (/modal)
Satu objek form untuk floating.form dan setDataBy.form;
getFormBy / getValidationBy ["name"]; onclick.validation: {}.
Angka validation: lihat NexaForm.
const formDef = {
nama: { condition: true, type: "text", label: "Nama", name: "nama", id: "nama", validation: 2 },
email: { condition: true, type: "email", label: "Email", name: "email", id: "email", validation: 2 },
};
const floatingConfig = {
id: "form_modal_modal1_nexa",
label: "Kontak",
variables: ["nama", "email"],
form: formDef,
settings: { floating: true, layout: "vertical" },
};
await NX.Modal({
elementById: "setModal_modal1",
styleClass: "w-500px",
minimize: true,
label: "Modal — data kontak",
floating: floatingConfig,
setDataBy: { form: formDef, source: "templates/modal.js", modalKey: "modal1" },
getFormBy: ["name"],
getValidationBy: ["name"],
onclick: { title: "Simpan", cancel: "Batal", send: "saveModalFormSubmit", validation: {} },
});
await NX.Modal.open("setModal_modal1");11. Referensi file
assets/modules/modal/NexaModalHtml.js— DOM +floating/ validasiassets/modules/modal/NexaModal.js— state & taskbarassets/modules/modal/modal.cssassets/modules/nxdom.js— agregasi APItemplates/modal.js— demo/modal- NexaForm,
templates/form.js