setup()
setup() runs once when the sketch loads. It prepares the entire DOM structure by either finding existing HTML elements or creating them dynamically. Notice the pattern: select() an element by id, then check if (!element) to decide whether to create it. This makes the code flexible—it works whether elements exist in index.html or need to be created from scratch. The function also stores a reference to the textarea in a global variable so other functions can access it later.
🔬 This block creates the inbox container and its child heading and list. What happens if you change 'Surat Masuk' to 'Surat Diterima'? How many places would you need to change to rename it everywhere?
let inboxContainer = select('#inbox-container');
if (!inboxContainer) {
inboxContainer = createDiv().id('inbox-container').addClass('letter-box-container');
inboxContainer.child(createElement('h2', 'Surat Masuk'));
inboxContainer.child(createDiv().id('inbox').addClass('letter-list'));
}
function setup() {
// Tidak perlu canvas p5.js untuk aplikasi ini karena sepenuhnya berbasis DOM
noCanvas();
// Dapatkan elemen-elemen DOM yang sudah ada di index.html
// Atau buat jika belum ada (untuk fleksibilitas)
let app = select('#app');
if (!app) app = createDiv().id('app');
let header = select('#header');
if (!header) {
header = createDiv().id('header');
header.child(createElement('h1', 'Aplikasi Surat Masuk & Keluar'));
}
let mainContent = select('#main-content');
if (!mainContent) mainContent = createDiv().id('main-content');
let controls = select('#controls');
if (!controls) {
controls = createDiv().id('controls');
controls.child(createElement('h2', 'Buat & Kirim Surat'));
letterContentInput = createElement('textarea').id('letter-content').attribute('placeholder', 'Tulis isi surat di sini...');
controls.child(letterContentInput);
controls.child(createButton('Surat Baru').id('new-letter-btn').mousePressed(createNewLetter));
controls.child(createButton('Kirim Surat').id('send-letter-btn').mousePressed(sendLetter));
controls.child(createButton('Terima Surat (Simulasi)').id('receive-letter-btn').mousePressed(receiveLetter));
} else {
// Jika #controls sudah ada, dapatkan referensi ke textarea
letterContentInput = select('#letter-content');
select('#new-letter-btn').mousePressed(createNewLetter);
select('#send-letter-btn').mousePressed(sendLetter);
select('#receive-letter-btn').mousePressed(receiveLetter);
}
let inboxContainer = select('#inbox-container');
if (!inboxContainer) {
inboxContainer = createDiv().id('inbox-container').addClass('letter-box-container');
inboxContainer.child(createElement('h2', 'Surat Masuk'));
inboxContainer.child(createDiv().id('inbox').addClass('letter-list'));
}
let outboxContainer = select('#outbox-container');
if (!outboxContainer) {
outboxContainer = createDiv().id('outbox-container').addClass('letter-box-container');
outboxContainer.child(createElement('h2', 'Surat Keluar'));
outboxContainer.child(createDiv().id('outbox').addClass('letter-list'));
}
// Pastikan semua kontainer ditambahkan ke main-content jika mereka baru
if (!mainContent.child('#controls')) mainContent.child(controls);
if (!mainContent.child('#inbox-container')) mainContent.child(inboxContainer);
if (!mainContent.child('#outbox-container')) mainContent.child(outboxContainer);
// Pastikan main-content ditambahkan ke app jika itu baru
if (!app.child('#main-content')) app.child(mainContent);
// Perbarui UI untuk menampilkan surat-surat awal
updateUI();
}
Line-by-line explanation (7 lines)
🔧 Subcomponents:
noCanvas();
Tells p5.js not to create a graphics canvas since this is a DOM-only app
let app = select('#app');
if (!app) app = createDiv().id('app');
Checks if an element already exists in the HTML; if not, creates it dynamically for flexibility
let controls = select('#controls');
if (!controls) {
controls = createDiv().id('controls');
controls.child(createElement('h2', 'Buat & Kirim Surat'));
letterContentInput = createElement('textarea').id('letter-content').attribute('placeholder', 'Tulis isi surat di sini...');
controls.child(letterContentInput);
controls.child(createButton('Surat Baru').id('new-letter-btn').mousePressed(createNewLetter));
controls.child(createButton('Kirim Surat').id('send-letter-btn').mousePressed(sendLetter));
controls.child(createButton('Terima Surat (Simulasi)').id('receive-letter-btn').mousePressed(receiveLetter));
}
Creates the textarea input and three buttons, attaching callback functions to each button click
noCanvas();- Tells p5.js not to create a default drawing canvas because this app uses only DOM elements and HTML
let app = select('#app');- Searches the existing HTML for an element with id='app'; returns null if it doesn't exist
if (!app) app = createDiv().id('app');- If no #app element exists, creates a new div and assigns it the id 'app' for future reference
letterContentInput = createElement('textarea').id('letter-content').attribute('placeholder', 'Tulis isi surat di sini...');- Creates a textarea element, assigns it an id, adds placeholder text, and stores a reference in the global variable letterContentInput so other functions can read and clear it
controls.child(createButton('Surat Baru').id('new-letter-btn').mousePressed(createNewLetter));- Creates a button labeled 'Surat Baru', gives it an id, attaches the createNewLetter function to run when clicked, and adds it as a child of the controls container
if (!mainContent.child('#controls')) mainContent.child(controls);- Checks if the controls element is already a child of mainContent; if not, adds it to prevent duplicates
updateUI();- Calls the updateUI() function to render the current state of the inbox and outbox arrays to the screen