
Pernahkah kamu merasa frustrasi saat ngoding? Aku ingat betul, dulu pernah seharian penuh berkutat hanya karena lupa titik koma di JavaScript atau salah ketik nama variabel. Rasanya seperti mencari jarum di tumpukan jerami digital, padahal masalahnya sepele. Tapi justru dari pengalaman "kecelakaan" kecil itulah, kita belajar memahami bagaimana setiap kepingan kode memiliki perannya masing-masing. Hari ini, kita akan menyelami dunia yang lebih besar, membangun dua aplikasi web yang cukup kompleks tapi sangat memuaskan: sebuah kalkulator fungsional dan sebuah page builder sederhana, semuanya hanya dengan kekuatan HTML, CSS, dan JavaScript "polos" tanpa framework berat.
Bayangkan ini seperti belajar membongkar dan merakit sepeda sendiri. Awalnya mungkin bingung, tapi begitu berhasil, kamu akan paham betul bagaimana setiap mur, baut, rantai, dan pedal bekerja bersama. Dengan HTML, CSS, dan JS, kita tidak hanya merakit sepeda, tapi bahkan bisa membuat "bengkel" kecil kita sendiri untuk menciptakan apa pun yang kita inginkan!
Kenapa Harus Vanilla HTML, CSS, JS? Pondasi Utama Kekuatan Web
Di era serba framework seperti React, Vue, atau Angular, mungkin kamu bertanya, "Kenapa repot-repot pakai vanilla HTML, CSS, JS?" Jawabannya sederhana: untuk memahami dasarnya. Menguasai ketiga pilar ini ibarat menguasai resep dasar masakan. Kamu tahu bagaimana memotong bawang, menumis bumbu, atau mengolah adonan dari nol. Dengan pemahaman dasar ini, kamu bisa berkreasi tanpa batas, bahkan ketika suatu hari nanti kamu beralih ke framework, kamu akan tahu persis apa yang terjadi di balik layar. Kamu tidak sekadar menggunakan instan, tapi mengerti betul prosesnya.
Kalkulator dan page builder ini adalah proyek sempurna untuk mengasah otot-otot dasar kita. Keduanya membutuhkan interaksi pengguna yang kuat, manipulasi DOM (Document Object Model) yang dinamis, dan sedikit sentuhan logika. Siap memulai petualangan ini?
Merancang Kalkulator Sederhana: Otak Matematika Digital Kita
Membangun kalkulator itu seperti merakit mesin hitung sederhana di bengkel. Kita butuh komponen input untuk menampilkan angka, dan serangkaian tombol untuk angka dan operasi. HTML akan jadi kerangka mesinnya.
<div class="calculator">
<input type="text" class="display" readonly>
<div class="buttons">
<button class="btn">7</button>
<button class="btn">8</button>
<button class="btn">9</button>
<button class="btn operator">/</button>
<!-- Lanjutkan dengan tombol lainnya -->
<button class="btn clear">C</button>
<button class="btn equals">=</button>
</div>
</div>
Dengan CSS, kita akan membuat mesin hitung ini terlihat menarik dan mudah digunakan. Menggunakan Flexbox atau Grid akan sangat membantu dalam menata tombol-tombol agar rapi, seperti menata peralatan di rak bengkel agar mudah dijangkau.
.calculator {
width: 300px;
margin: 50px auto;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
padding: 15px;
background-color: #f9f9f9;
}
.display {
width: calc(100% - 20px);
height: 50px;
font-size: 2em;
text-align: right;
margin-bottom: 15px;
padding: 0 10px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #eee;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.btn {
padding: 15px;
font-size: 1.2em;
border: none;
border-radius: 4px;
background-color: #e0e0e0;
cursor: pointer;
transition: background-color 0.2s;
}
.btn:hover {
background-color: #d0d0d0;
}
.operator { background-color: #f0ad4e; color: white; }
.clear { background-color: #d9534f; color: white; }
.equals { background-color: #5cb85c; color: white; grid-column: span 2; }
Dan inilah bagian "otak"nya, JavaScript. Ini adalah montir yang akan membuat semua tombol bereaksi dan melakukan perhitungan. Kita akan mendengarkan setiap klik tombol, memperbarui tampilan, dan melakukan evaluasi ekspresi. Hati-hati dengan penggunaan `eval()` karena bisa punya celah keamanan jika menerima input yang tidak disaring, tapi untuk latihan dasar ini, itu cara tercepat.
const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.btn');
let currentInput = '';
let operator = null;
let previousInput = '';
buttons.forEach(button => {
button.addEventListener('click', (e) => {
const value = e.target.textContent;
if (value === 'C') {
currentInput = '';
operator = null;
previousInput = '';
display.value = '';
return;
}
if (value === '=') {
if (currentInput && previousInput && operator) {
try {
currentInput = eval(previousInput + operator + currentInput).toString();
display.value = currentInput;
previousInput = currentInput;
operator = null;
} catch (error) {
display.value = 'Error';
}
}
return;
}
if (['+', '-', '*', '/'].includes(value)) {
if (currentInput) {
if (previousInput && operator) { // Handle chained operations
try {
previousInput = eval(previousInput + operator + currentInput).toString();
display.value = previousInput;
currentInput = '';
operator = value;
} catch (error) {
display.value = 'Error';
}
} else {
previousInput = currentInput;
currentInput = '';
operator = value;
}
}
return;
}
currentInput += value;
display.value = currentInput;
});
});
Menggali Kreativitas dengan Page Builder: Kanvas Digitalmu
Nah, kalau kalkulator itu ibarat merakit mesin hitung, page builder ini seperti punya studio desain interior sendiri. Kamu bisa memilih perabot (elemen HTML), menyeretnya ke mana pun kamu mau di ruangan (kanvas), dan mengubah warnanya (styling). Ini adalah proyek yang akan benar-benar menguji pemahamanmu tentang DOM dan event JavaScript.
Struktur HTML: Palet dan Kanvas
Kita akan butuh dua area utama: toolbox tempat elemen-elemen yang bisa diseret, dan canvas tempat elemen itu akan diletakkan.
<div class="page-builder-container">
<div class="toolbox">
<h3>Elemen</h3>
<div class="draggable-item" draggable="true" data-type="text">Teks</div>
<div class="draggable-item" draggable="true" data-type="button">Tombol</div>
<div class="draggable-item" draggable="true" data-type="image">Gambar</div>
<!-- Tambahkan elemen lain sesuai kebutuhan -->
</div>
<div class="canvas" id="pageCanvas">
<p>Seret elemen ke sini!</p>
</div>
</div>
CSS: Tampilan Interaktif
Styling-nya akan memastikan toolbox terlihat jelas dan canvas memiliki area yang bisa dijatuhkan (drop zone). Penting juga untuk memberikan umpan balik visual saat elemen diseret.
.page-builder-container {
display: flex;
margin-top: 50px;
gap: 20px;
height: 600px; /* Contoh tinggi */
}
.toolbox {
width: 200px;
border: 1px solid #ddd;
padding: 15px;
background-color: #f4f4f4;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.draggable-item {
padding: 10px 15px;
margin-bottom: 10px;
background-color: #007bff;
color: white;
border-radius: 4px;
cursor: grab;
text-align: center;
}
.canvas {
flex-grow: 1;
border: 2px dashed #ccc;
background-color: #fff;
border-radius: 8px;
padding: 20px;
position: relative; /* Penting untuk posisi elemen yang di-drop */
overflow: auto;
min-height: 100%;
}
.canvas.drag-over {
border-color: #007bff;
background-color: #e6f0ff;
}
/* Styling untuk elemen yang di-drop di canvas */
.canvas > * {
background-color: #f0f8ff;
border: 1px solid #aaddff;
padding: 10px;
margin-bottom: 10px;
cursor: move; /* Untuk nanti jika ingin fitur drag within canvas */
position: relative; /* Agar bisa diatur posisinya di canvas */
}
JavaScript: Otak di Balik Drag and Drop
Di sinilah keajaiban terjadi! Kita akan menggunakan API Drag and Drop dari HTML5. Ini seperti memancing. Kamu "mengambil" ikan (elemen) dari air (toolbox) dan "menjatuhkannya" ke ember (canvas).
const toolboxItems = document.querySelectorAll('.draggable-item');
const pageCanvas = document.getElementById('pageCanvas');
let draggedItem = null;
toolboxItems.forEach(item => {
item.addEventListener('dragstart', (e) => {
draggedItem = e.target;
e.dataTransfer.setData('text/plain', e.target.dataset.type); // Kirim tipe elemen
e.dataTransfer.effectAllowed = 'copy';
});
});
pageCanvas.addEventListener('dragover', (e) => {
e.preventDefault(); // Mencegah perilaku default browser (yaitu tidak mengizinkan drop)
e.dataTransfer.dropEffect = 'copy';
pageCanvas.classList.add('drag-over'); // Beri umpan balik visual
});
pageCanvas.addEventListener('dragleave', () => {
pageCanvas.classList.remove('drag-over');
});
pageCanvas.addEventListener('drop', (e) => {
e.preventDefault();
pageCanvas.classList.remove('drag-over');
const dataType = e.dataTransfer.getData('text/plain');
let newElement;
switch (dataType) {
case 'text':
newElement = document.createElement('p');
newElement.textContent = 'Ini adalah teks baru. Klik dua kali untuk mengedit!';
break;
case 'button':
newElement = document.createElement('button');
newElement.textContent = 'Klik Aku!';
newElement.style.padding = '8px 15px';
newElement.style.backgroundColor = '#28a745';
newElement.style.color = 'white';
newElement.style.border = 'none';
newElement.style.borderRadius = '5px';
break;
case 'image':
newElement = document.createElement('img');
newElement.src = 'https://via.placeholder.com/150'; // Placeholder gambar
newElement.alt = 'Gambar Placeholder';
newElement.style.maxWidth = '100%';
newElement.style.height = 'auto';
break;
default:
return;
}
// Tambahkan fitur edit sederhana (contoh: double click untuk teks)
if (dataType === 'text') {
newElement.setAttribute('contenteditable', 'true'); // Membuat elemen bisa diedit langsung
newElement.addEventListener('dblclick', () => {
alert('Sekarang kamu bisa mengedit teks ini langsung!');
});
}
pageCanvas.appendChild(newElement);
});
Kode di atas adalah fondasi untuk drag and drop. Untuk membuatnya lebih canggih (seperti mengubah properti CSS, menyimpan layout, atau drag and drop di dalam kanvas), kamu perlu menambahkan lebih banyak logika JavaScript, seperti:
- Menyimpan struktur DOM kanvas ke localStorage agar halaman tidak hilang saat di-refresh.
- Menambahkan context menu (klik kanan) pada elemen di kanvas untuk opsi edit (misalnya ganti warna background, ukuran font, dll).
- Membuat elemen di kanvas juga bisa diseret dan diatur ulang posisinya.
Penutup: Dari Nol Menjadi Superhero Web
Selamat! Kamu baru saja membangun dua proyek yang sangat fundamental namun powerful menggunakan HTML, CSS, dan JavaScript murni. Dari kalkulator sederhana yang mengajarkan kita tentang event handling dan logika perhitungan, hingga page builder yang membuka gerbang ke dunia manipulasi DOM dan interaksi drag-and-drop yang dinamis. Ini adalah bukti bahwa dengan memahami dasar-dasarnya, kamu tidak perlu framework canggih untuk menciptakan sesuatu yang luar biasa.
Ingat analogi bengkel di awal? Kita sudah merakit mesin hitung dan mendesain interior digital kita sendiri. Sekarang, tantangan selanjutnya adalah bagaimana kamu bisa mengembangkan kedua aplikasi ini. Mungkin kalkulatormu bisa menghitung akar kuadrat, atau page buildermu bisa menyimpan template yang berbeda? Langit adalah batasnya. Teruslah bereksperimen, teruslah belajar, dan jangan takut untuk "salah ketik" lagi. Karena dari setiap kesalahan, ada pelajaran berharga yang menunggu untuk ditemukan. Selamat berkarya!