
Dulu, waktu saya baru mulai ngoding, ada momen epik di mana saya habis begadang semalaman cuma buat nyari tahu kenapa tombol kalkulator saya enggak mau jalan. Ternyata cuma typo di nama ID, rasanya kayak lagi bongkar mesin motor seharian, eh yang rusak cuma businya kendor. Pengalaman seperti itu yang bikin kita makin paham, fundamental itu penting banget. Hari ini, kita akan ngobrolin gimana caranya membangun dua aplikasi web yang cukup kompleks tapi sangat mendasar: kalkulator dan page builder, hanya dengan modal HTML, CSS, dan JavaScript murni. Ini bukan cuma tentang koding, tapi tentang bagaimana kita bisa "merakit" ide menjadi kenyataan digital di browser. Siap? Yuk, kita mulai!
Membuat Kalkulator Interaktif: Jantung Operasi Matematika Anda
Membangun kalkulator di web itu ibarat kita merakit jam tangan. Setiap komponen harus presisi, dan semua roda gigi harus berputar sinkron. Kalau ada satu saja yang meleset, bisa-bisa hasil hitungannya melenceng jauh. Mari kita mulai dari dasarnya.
Rangka HTML: Tulang Belakang Kalkulator
Kita perlu struktur dasar untuk menampilkan angka dan tombol. Anggap saja ini cetakan sasis untuk motor kita. Tanpa struktur yang jelas, ibarat mencoba menumpuk komponen mesin tanpa kerangka yang kokoh.
<div class="calculator">
<input type="text" class="calculator-screen" value="0" disabled />
<div class="calculator-buttons">
<button class="operator" data-action="add">+</button>
<button class="operator" data-action="subtract">-</button>
<button class="operator" data-action="multiply">×</button>
<button class="operator" data-action="divide">÷</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button class="decimal" data-action="decimal">.</button>
<button>0</button>
<button class="all-clear" data-action="clear">AC</button>
<button class="equal-sign" data-action="calculate">=</button>
</div>
</div>
Gaya CSS: Mempercantik Tampilan
Setelah sasis jadi, kita perlu sentuhan cat dan jok yang nyaman. CSS akan membuat kalkulator kita terlihat profesional dan mudah digunakan. Ini bukan cuma soal estetika, tapi juga ergonomi, memastikan pengguna tidak bingung mencari tombol atau membaca angka. Ibarat mobil balap, performa saja tidak cukup, tampilannya juga harus menawan.
.calculator {
border: 1px solid #ccc;
border-radius: 5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
max-width: 90%; /* Responsive adjustment */
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.calculator-screen {
width: 100%;
height: 80px;
background-color: #252525;
color: #fff;
text-align: right;
font-size: 4em;
border: none;
padding: 0 20px;
box-sizing: border-box;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
font-family: 'Roboto Mono', monospace; /* Contoh font monospace */
}
.calculator-buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1px;
background-color: #999;
}
.calculator-buttons button {
height: 70px;
background-color: #e0e0e0;
border: 1px solid #999;
font-size: 2em;
cursor: pointer;
outline: none;
transition: background-color 0.2s ease;
}
.calculator-buttons button:hover {
background-color: #d0d0d0;
}
.operator {
background-color: #f69906;
color: #fff;
}
.operator:hover {
background-color: #e08b05;
}
.equal-sign {
background-color: #2e86c1;
color: #fff;
grid-column: -2 / -1;
grid-row: 2 / span 4;
height: auto;
}
.equal-sign:hover {
background-color: #2770a1;
}
Logika JavaScript: Otak di Balik Kalkulator
Ini dia bagian paling seru, tempat kita "memasang mesin" dan "wiring" agar semua tombol berfungsi. Pernah suatu ketika, saya bingung kenapa hasil hitungan kalkulator saya jadi aneh, ternyata lupa nambahin parseFloat(). Angkanya jadi dianggap string, bukan angka. Rasanya kayak lagi masak, semua bumbu sudah lengkap, tapi lupa masukin garam. JavaScript akan menghandle semua interaksi pengguna, dari menekan angka hingga melakukan perhitungan kompleks.
const calculator = document.querySelector('.calculator');
const keys = calculator.querySelector('.calculator-buttons');
const display = document.querySelector('.calculator-screen');
let firstValue = null;
let operator = null;
let waitingForSecondValue = false; // Flag untuk menunggu input angka kedua
keys.addEventListener('click', e => {
if (e.target.matches('button')) {
const key = e.target;
const action = key.dataset.action;
const keyContent = key.textContent;
// Jika tombol bukan operator atau aksi khusus
if (!action) {
if (display.value === '0' || waitingForSecondValue) {
display.value = keyContent;
waitingForSecondValue = false;
} else {
display.value += keyContent;
}
}
// Jika tombol adalah operator
if (action === 'add' || action === 'subtract' || action === 'multiply' || action === 'divide') {
firstValue = parseFloat(display.value);
operator = action;
waitingForSecondValue = true;
}
// Jika tombol adalah titik desimal
if (action === 'decimal') {
if (!display.value.includes('.')) {
display.value += '.';
}
// Jika sedang menunggu angka kedua, mulai dengan '0.'
if (waitingForSecondValue) {
display.value = '0.';
waitingForSecondValue = false;
}
}
// Jika tombol adalah 'AC' (All Clear)
if (action === 'clear') {
display.value = '0';
firstValue = null;
operator = null;
waitingForSecondValue = false;
}
// Jika tombol adalah '=' (Calculate)
if (action === 'calculate') {
const secondValue = parseFloat(display.value);
if (firstValue !== null && operator !== null && !waitingForSecondValue) {
let result;
if (operator === 'add') result = firstValue + secondValue;
if (operator === 'subtract') result = firstValue - secondValue;
if (operator === 'multiply') result = firstValue * secondValue;
if (operator === 'divide') {
result = firstValue / secondValue;
if (secondValue === 0) result = 'Error'; // Hindari pembagian nol
}
display.value = result;
firstValue = null; // Reset setelah perhitungan
operator = null;
waitingForSecondValue = false;
}
}
}
});
Kalkulator ini hanyalah dasar. Anda bisa mengembangkannya lagi dengan fungsi memori, persentase, atau bahkan operasi yang lebih kompleks. Intinya, JavaScript adalah nyawa yang menghidupkan interaksi di aplikasi web Anda.
Membangun Page Builder Sederhana: Kanvas Digital untuk Kreativitas
Sekarang, mari kita beralih ke proyek yang lebih ambisius tapi tak kalah seru: page builder. Membangun page builder itu seperti menyediakan bengkel lengkap dengan alat-alatnya, lalu mempersilakan orang lain merakit mobil impian mereka sendiri. Kita akan fokus pada fungsionalitas dasar drag-and-drop dan editing teks. Ini adalah esensi dari frontend development yang interaktif.
Struktur HTML: Palet dan Kanvas
Kita butuh area untuk elemen-elemen yang bisa ditarik (palet) dan area di mana elemen tersebut akan dijatuhkan (kanvas). Ini adalah pondasi rumah yang akan kita bangun.
<div class="page-builder-container">
<div class="sidebar">
<h3>Elements</h3>
<div class="draggable-element" draggable="true" data-type="heading">Heading</div>
<div class="draggable-element" draggable="true" data-type="paragraph">Paragraph</div>
<div class="draggable-element" draggable="true" data-type="image">Image Placeholder</div>
<div class="draggable-element" draggable="true" data-type="button">Button</div>
</div>
<div class="canvas" id="drop-zone">
<h2 class="initial-placeholder-text">Drag & Drop Elements Here</h2>
</div>
</div>
Gaya CSS: Memberi Identitas Visual
CSS akan membuat elemen-elemen ini terlihat jelas, dan memberikan umpan balik visual saat kita melakukan drag-and-drop. Bayangkan ini seperti mengatur tata letak ruangan agar semua barang mudah dijangkau dan terlihat rapi. Ini juga memastikan desain web kita responsif dan intuitif.
.page-builder-container {
display: flex;
height: 80vh;
border: 1px solid #eee;
margin-top: 20px;
font-family: Arial, sans-serif;
min-height: 500px;
}
.sidebar {
width: 250px;
background-color: #f5f5f5;
padding: 15px;
border-right: 1px solid #ddd;
overflow-y: auto;
}
.draggable-element {
background-color: #fff;
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
cursor: grab;
text-align: center;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
border-radius: 4px;
}
.draggable-element:active {
cursor: grabbing;
}
.canvas {
flex-grow: 1;
background-color: #fff;
padding: 20px;
border: 2px dashed #ccc;
display: flex;
flex-direction: column;
gap: 10px;
align-items: flex-start;
overflow-y: auto;
}
.canvas.drag-over {
border-color: #2e86c1;
background-color: #eaf6ff;
}
.editable {
padding: 5px;
border: 1px dashed transparent;
cursor: text;
min-height: 20px; /* Agar mudah diklik/diedit saat kosong */
}
.editable:hover {
border: 1px dashed #aaa;
}
.editable:focus {
border: 1px dashed #2e86c1;
outline: none;
background-color: #fcfdff;
}
.canvas img {
max-width: 100%;
height: auto;
display: block; /* Menghilangkan ruang kosong di bawah gambar */
}
.canvas button {
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1em;
}
.canvas button:hover {
background-color: #0056b3;
}
Logika JavaScript: Menghidupkan Interaksi Drag-and-Drop dan Edit
Bagian ini yang paling menantang, tapi juga paling memuaskan. Saya pernah seharian nyari kenapa elemen yang saya drag enggak mau "nempel" di kanvas, ternyata event preventDefault() di dragover-nya kelupaan. Rasanya kayak lagi mancing tapi umpannya enggak digigit-gigit, padahal umpannya sudah tepat. JavaScript akan menangani semua logika drag-and-drop, penambahan elemen, dan kemampuan mengedit teks langsung di kanvas. Ini adalah JavaScript interaktif yang sebenarnya.
const sidebar = document.querySelector('.sidebar');
const dropZone = document.getElementById('drop-zone');
let draggedElement = null;
sidebar.addEventListener('dragstart', e => {
if (e.target.classList.contains('draggable-element')) {
draggedElement = e.target;
e.dataTransfer.setData('text/plain', e.target.dataset.type); // Kirim tipe elemen
e.dataTransfer.effectAllowed = 'copy';
}
});
dropZone.addEventListener('dragover', e => {
e.preventDefault(); // Penting! Ini yang bikin elemen bisa di-drop
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', e => {
e.preventDefault();
dropZone.classList.remove('drag-over');
const dataType = e.dataTransfer.getData('text/plain');
let newElement;
if (dataType === 'heading') {
newElement = document.createElement('h2');
newElement.textContent = 'New Heading';
} else if (dataType === 'paragraph') {
newElement = document.createElement('p');
newElement.textContent = 'This is a new paragraph.';
} else if (dataType === 'image') {
newElement = document.createElement('img');
newElement.src = 'https://via.placeholder.com/200'; // Placeholder image
newElement.alt = 'Placeholder Image';
newElement.style.maxWidth = '100%';
} else if (dataType === 'button') {
newElement = document.createElement('button');
newElement.textContent = 'Click Me';
}
if (newElement) {
newElement.classList.add('editable');
// Hanya elemen teks yang bisa di-contenteditable
if (dataType !== 'image') {
newElement.setAttribute('contenteditable', 'true');
}
dropZone.appendChild(newElement);
// Hapus teks placeholder awal jika ada
const initialPlaceholder = dropZone.querySelector('.initial-placeholder-text');
if (initialPlaceholder) {
initialPlaceholder.remove();
}
}
draggedElement = null;
});
// Opsional: Tambahkan fungsi hapus dengan klik kanan untuk elemen di kanvas
dropZone.addEventListener('contextmenu', e => {
// Pastikan yang diklik adalah elemen yang bisa dihapus
if (e.target.classList.contains('editable') || e.target.tagName === 'IMG' || e.target.tagName === 'BUTTON') {
e.preventDefault(); // Mencegah menu konteks default browser
if (confirm('Are you sure you want to delete this element?')) {
e.target.remove();
}
}
});
Dengan kode di atas, Anda sudah memiliki dasar untuk sebuah page builder. Tentu saja, ini bisa dikembangkan lebih jauh lagi: menambahkan opsi gaya (warna, font), menyimpan tata letak, atau menambahkan lebih banyak jenis elemen. Potensinya sangat luas untuk membangun aplikasi web kreatif!
Mengapa HTML, CSS, dan JavaScript Adalah Tiga Serangkai yang Tak Terkalahkan?
Melihat dua contoh di atas, kita bisa sadar betapa fundamental dan kuatnya kombinasi HTML, CSS, dan JavaScript. Mereka adalah fondasi dari hampir semua aplikasi web modern.
- HTML (HyperText Markup Language): Ibarat kerangka bangunan. Tanpanya, tidak ada struktur, tidak ada fondasi untuk meletakkan konten. Ini adalah struktur semantik web Anda, seperti pondasi rumah.
- CSS (Cascading Style Sheets): Ini adalah arsitek dan desainer interior. Bertanggung jawab untuk tampilan, warna, layout, dan responsivitas. CSS mengubah kerangka polos menjadi tampilan yang menarik dan fungsional, layaknya sentuhan cat dan furnitur yang indah.
- JavaScript (JS): Ini adalah otak dan otot. Memberikan interaktivitas, logika bisnis di sisi klien, dan membuat aplikasi Anda "hidup". Dari animasi kecil hingga manipulasi data kompleks, semua adalah tugas JavaScript. Ini adalah sistem kelistrikan dan otomasi yang membuat rumah itu berfungsi.
Belajar dan menguasai trio ini adalah investasi terbaik bagi siapa saja yang ingin serius di dunia pengembangan web frontend. Anda akan memiliki kemampuan untuk mewujudkan ide-ide kreatif Anda menjadi aplikasi yang bisa diakses siapa saja, di mana saja.
Penutup: Terus Bereksplorasi dan Berkarya!
Membangun kalkulator dan page builder sederhana adalah langkah awal yang fantastis. Keduanya mengajarkan Anda konsep-konsep inti seperti manipulasi DOM (Document Object Model), penanganan event, dan manajemen state sederhana di browser. Ingat, dunia koding itu seperti bermain LEGO, Anda mulai dari balok-balok kecil, lalu lambat laun Anda akan bisa membangun kastil megah atau kota impian. Jangan pernah takut mencoba, membuat kesalahan, dan yang paling penting, jangan pernah berhenti belajar. Selamat berkarya dan sampai jumpa di artikel teknis selanjutnya! Jangan lupa, keahlian HTML CSS JS Anda adalah kunci untuk masa depan web development yang cerah!