Mengukir Dunia Digital: Membangun Kalkulator dan Page Builder Sendiri dengan HTML, CSS, JS

PintarApp • September 24, 2026
Mengukir Dunia Digital: Membangun Kalkulator dan Page Builder Sendiri dengan HTML, CSS, JS
Pernahkah Anda merasa seperti ada sepasang sarung tangan yang tiba-tiba melayang di udara saat mencoba memegang obeng di bengkel? Begitulah rasanya saat pertama kali saya mencoba membuat kalkulator digital. Saya kira, "Ah, cuma tambah kurang kali bagi!" Tapi ternyata, membuat logika di baliknya agar angka-angka tidak malah jadi 'string' yang bertumpuk (misalnya '2' + '2' jadi '22' bukannya '4') itu butuh kesabaran dan trik khusus. Namun, di situlah letak serunya, bukan? Transformasi dari kebingungan menjadi 'Aha!' adalah momen paling memuaskan bagi seorang programmer. Hari ini, kita akan menyelami dunia sihir HTML, CSS, dan JavaScript untuk menciptakan dua alat web yang mungkin terlihat sederhana, tapi menyimpan kekuatan fundamental: sebuah kalkulator dan sebuah page builder sederhana.

Mungkin Anda berpikir, "Untuk apa repot-repot membuat kalkulator atau page builder sendiri? Kan sudah banyak!" Betul, tapi ibarat belajar memasak, Anda tidak akan benar-benar memahami rasa dan tekstur masakan sebelum Anda meracik bumbu dan mengaduknya sendiri dari nol. Dengan membangun aplikasi ini, kita akan menggali fondasi web development, mengasah logika, dan merasakan sensasi menciptakan sesuatu yang interaktif dari ketiadaan. Siap untuk petualangan merakit kode?

Kalkulator: Otak Cepat di Balik Angka

Membangun kalkulator mungkin terdengar sepele, tetapi ini adalah latihan yang bagus untuk memahami bagaimana JavaScript menangani interaksi pengguna dan manipulasi data. Anggap saja kalkulator ini adalah mesin kasir mini Anda, yang setiap tombolnya harus bereaksi secara presisi.

1. Fondasi HTML: Papan Tombol Kalkulator Kita

Kalkulator yang baik dimulai dengan tata letak yang jelas. Saya ingat dulu, saat pertama kali mencoba membuat tombol-tombolnya, hasilnya malah seperti tumpukan buku yang mau rubuh, tidak rapi dan tidak sejajar. Solusinya? Struktur HTML yang rapi seperti menyiapkan kerangka meja kerja sebelum mulai merakit komponen elektronik. Kita butuh sebuah layar untuk menampilkan hasil dan sekumpulan tombol untuk angka dan operator.


<div class="calculator">
<input type="text" class="display" value="0" disabled>
<div class="buttons">
<button class="button" data-value="C">C</button>
<button class="button" data-value="/">/</button>
<button class="button" data-value="*">*</button>
<button class="button" data-value="DEL">DEL</button>
<button class="button" data-value="7">7</button>
<button class="button" data-value="8">8</button>
<button class="button" data-value="9">9</button>
<button class="button" data-value="-">-</button>
<button class="button" data-value="4">4</button>
<button class="button" data-value="5">5</button>
<button class="button" data-value="6">6</button>
<button class="button" data-value="+">+</button>
<button class="button" data-value="1">1</button>
<button class="button" data-value="2">2</button>
<button class="button" data-value="3">3</button>
<button class="button equals" data-value="=">=</button>
<button class="button zero" data-value="0">0</button>
<button class="button" data-value=".">.</button>
</div>
</div>

Setiap tombol memiliki atribut data-value yang akan sangat berguna saat kita mulai menambahkan logika JavaScript. Ini seperti memberikan label identitas pada setiap komponen agar mesin bisa tahu komponen mana yang sedang dioperasikan.

2. Gaya CSS: Mempercantik Tampilan

Setelah kerangka HTML siap, saatnya membuat kalkulator kita terlihat profesional. Pernah mencoba merakit furniture tanpa membaca instruksi? Hasilnya mungkin berdiri, tapi miring atau goyang. CSS berfungsi seperti instruksi perakitan untuk estetika. Kita akan menggunakan Flexbox atau Grid untuk menata tombol-tombol agar rapi dan responsif, tidak peduli dibuka di layar HP atau monitor besar.


.calculator {
background-color: #333;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
width: 320px;
}
.display {
width: calc(100% - 20px);
height: 60px;
background-color: #eee;
border: none;
font-size: 2.5em;
text-align: right;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.button {
background-color: #555;
color: white;
border: none;
padding: 20px;
font-size: 1.5em;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.2s;
}
.button:hover {
background-color: #777;
}
.equals {
grid-column: span 1; /* Adjust as needed for specific layout */
background-color: #f7a047;
}
.zero {
grid-column: span 2;
}

3. Logika JavaScript: Otak di Balik Setiap Ketukan

Ini dia bagian terseru, di mana kalkulator kita mulai "hidup". Dulu, saya pernah mengira bisa menghitung semuanya hanya dengan eval(), tapi ternyata hasilnya kacau balau, terutama saat berhadapan dengan operasi berantai atau tanda desimal. JavaScript di sini adalah montir cerdas yang tahu bagaimana merangkai setiap input, memprosesnya, dan memberikan output yang benar.


const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.button');
let currentInput = '';
let operator = null;
let previousInput = '';
let resultDisplayed = false;
buttons.forEach(button => {
button.addEventListener('click', () => {
const value = button.dataset.value;
if (value === 'C') {
currentInput = '';
operator = null;
previousInput = '';
display.value = '0';
resultDisplayed = false;
return;
}
if (value === 'DEL') {
if (currentInput.length > 0) {
currentInput = currentInput.slice(0, -1);
display.value = currentInput === '' ? '0' : currentInput;
}
return;
}
if (['+', '-', '*', '/'].includes(value)) {
if (currentInput !== '' && previousInput !== '') {
calculate();
}
if (currentInput !== '') {
operator = value;
previousInput = currentInput;
currentInput = '';
}
resultDisplayed = false;
return;
}
if (value === '=') {
if (currentInput !== '' && previousInput !== '' && operator !== null) {
calculate();
resultDisplayed = true;
operator = null; // Reset operator after calculation
}
return;
}
if (resultDisplayed) { // Start new calculation after displaying result
currentInput = value;
resultDisplayed = false;
} else {
if (value === '.' && currentInput.includes('.')) return; // Prevent multiple decimals
currentInput += value;
}
display.value = currentInput;
});
});
function calculate() {
let calculation;
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (operator) {
case '+':
calculation = prev + current;
break;
case '-':
calculation = prev - current;
break;
case '*':
calculation = prev * current;
break;
case '/':
calculation = prev / current;
break;
default:
return;
}
currentInput = calculation.toString();
previousInput = '';
display.value = currentInput;
}

Logika di atas menangani alur input, operator, dan perhitungan. Kami mengelola variabel currentInput, previousInput, dan operator untuk melacak status kalkulator. Fungsi calculate() adalah intinya, tempat semua operasi matematika dilakukan. Ini seperti mengontrol aliran bahan bakar, busi, dan transmisi di sebuah mobil agar mesin bekerja harmonis.

Page Builder Sederhana: Merakit Halaman Sesuai Keinginan

Nah, setelah berhasil membuat otak kecil untuk angka, kini kita akan beralih ke proyek yang lebih "visual" dan interaktif: sebuah page builder sederhana. Bayangkan ini seperti bermain LEGO digital, di mana Anda bisa menyeret dan meletakkan balok-balok (komponen) untuk membangun istana Anda (halaman web).

1. Fondasi HTML: Kanvas Kosong dan Palet Komponen

Pada awalnya, saya pernah berpikir kalau semua bisa langsung di-JavaScript. Lalu saya sadar, tanpa kerangka HTML yang jelas, JavaScript akan bingung mau menaruh elemennya di mana. Ini seperti mencoba membangun rumah tanpa pondasi dan dinding penopang. Kita memerlukan area untuk komponen yang bisa diseret (palet) dan area di mana komponen tersebut bisa dijatuhkan (kanvas atau area desain).


<div class="page-builder">
<div class="sidebar">
<h3>Komponen</h3>
<div class="component-item" draggable="true" data-type="header">Header</div>
<div class="component-item" draggable="true" data-type="paragraph">Paragraf</div>
<div class="component-item" draggable="true" data-type="button">Tombol</div>
<div class="component-item" draggable="true" data-type="image">Gambar</div>
</div>
<div class="design-area" id="designArea">
<p class="placeholder">Seret komponen ke sini...</p>
</div>
</div>

Perhatikan atribut draggable="true" pada setiap komponen. Ini adalah kunci yang memberitahu browser bahwa elemen ini bisa diseret. Atribut data-type akan membantu kita mengidentifikasi jenis komponen saat diseret.

2. Gaya CSS: Membentuk Antarmuka yang Intuitif

Agar page builder kita nyaman digunakan, tampilannya harus bersih dan responsif. Dulu, saya pernah mengabaikan styling untuk drag-and-drop, dan hasilnya, elemen yang diseret malah "menghilang" di bawah kursor atau area drop tidak terlihat jelas. CSS di sini bertindak sebagai arsitek interior yang merancang ruang kerja agar semua terlihat jelas dan fungsional.


.page-builder {
display: flex;
min-height: 80vh;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
}
.sidebar {
width: 200px;
background-color: #f4f4f4;
padding: 15px;
border-right: 1px solid #ddd;
}
.component-item {
background-color: #e0e0e0;
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
cursor: grab;
text-align: center;
border-radius: 4px;
}
.design-area {
flex-grow: 1;
background-color: #fff;
padding: 20px;
border: 2px dashed #eee; /* Visual cue for drop target */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.design-area.dragging-over {
border-color: #6c7bff; /* Highlight when dragging over */
background-color: #f0f3ff;
}
.design-area > *:not(.placeholder) { /* Styling for dropped components */
margin-bottom: 10px;
padding: 10px;
border: 1px solid #a0a0a0;
width: 90%;
background-color: #ffffff;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

3. Logika JavaScript: Membangun dengan Seret & Jatuhkan

Inilah jantung dari page builder kita: fungsionalitas drag-and-drop. Dulu, saya sering lupa menambahkan event.preventDefault() pada event dragover, yang membuat elemen tidak bisa dijatuhkan sama sekali! Itu seperti mencoba memasukkan kunci ke lubang kunci yang tidak mau menerima. JavaScript di sini adalah operator crane yang mengangkat dan memindahkan balok-balok, lalu menempatkannya di posisi yang Anda inginkan di kanvas desain.


const sidebarComponents = document.querySelectorAll('.component-item');
const designArea = document.getElementById('designArea');
let draggedComponent = null;
sidebarComponents.forEach(comp => {
comp.addEventListener('dragstart', (e) => {
draggedComponent = e.target;
e.dataTransfer.setData('text/plain', e.target.dataset.type); // Store component type
e.target.style.opacity = '0.5'; // Visual feedback
});
comp.addEventListener('dragend', (e) => {
e.target.style.opacity = '1';
draggedComponent = null;
});
});
designArea.addEventListener('dragover', (e) => {
e.preventDefault(); // Crucial! Allows us to drop
designArea.classList.add('dragging-over');
});
designArea.addEventListener('dragleave', () => {
designArea.classList.remove('dragging-over');
});
designArea.addEventListener('drop', (e) => {
e.preventDefault();
designArea.classList.remove('dragging-over');
if (draggedComponent) {
const componentType = e.dataTransfer.getData('text/plain');
const newElement = createComponent(componentType);
designArea.appendChild(newElement);
// Remove placeholder if it exists
const placeholder = designArea.querySelector('.placeholder');
if (placeholder) {
placeholder.remove();
}
}
});
function createComponent(type) {
let element;
switch (type) {
case 'header':
element = document.createElement('h2');
element.textContent = 'Ini Header Anda';
break;
case 'paragraph':
element = document.createElement('p');
element.textContent = 'Ini adalah paragraf baru. Klik untuk edit.';
break;
case 'button':
element = document.createElement('button');
element.textContent = 'Klik Saya';
element.style.padding = '10px 20px';
element.style.backgroundColor = '#6c7bff';
element.style.color = 'white';
element.style.border = 'none';
element.style.borderRadius = '5px';
element.style.cursor = 'pointer';
break;
case 'image':
element = document.createElement('img');
element.src = 'https://via.placeholder.com/150'; // Placeholder image
element.alt = 'Gambar Placeholder';
element.style.maxWidth = '100%';
element.style.height = 'auto';
break;
default:
element = document.createElement('div');
element.textContent = 'Komponen Tidak Dikenal';
}
// Make dropped elements also draggable for reordering (optional advanced feature)
element.draggable = true;
return element;
}
// Optional: Add drag/drop for reordering within designArea
// This requires more complex logic, storing index, and reinserting

Kita menggunakan event dragstart, dragover, dragleave, dan drop untuk mengelola proses seret dan jatuhkan. Fungsi createComponent() adalah pabrik mini kita yang akan membuat elemen HTML sesuai dengan tipe komponen yang diseret. Ini adalah dasar yang bisa Anda kembangkan jauh lebih kompleks, misalnya dengan menambahkan fitur edit teks inline atau mengubah properti elemen.

Mengapa Repot-repot Membuat Ini Sendiri?

Mungkin Anda akan bertanya, "Apa gunanya menghabiskan waktu membuat ini semua jika sudah ada tool yang lebih canggih?" Jawabannya sederhana: pemahaman mendalam. Saat Anda membangun kalkulator, Anda belajar tentang manajemen state, event handling, dan parsing string. Saat Anda merancang page builder, Anda memahami DOM manipulation, event drag-and-drop, dan bagaimana sebuah UI interaktif benar-benar bekerja.

Ini seperti memahami mesin mobil dari nol sebelum Anda mengendarai mobil sport. Anda akan tahu persis mengapa pedal gas bekerja, bagaimana rem berfungsi, dan apa yang harus dilakukan jika ada masalah. Keterampilan dasar ini adalah batu loncatan untuk menguasai framework modern seperti React, Vue, atau Angular, yang pada dasarnya menyederhanakan konsep-konsep yang baru saja kita bangun secara manual.

Penutup: Mari Berkreasi!

Jadi, begitulah! Dengan sedikit HTML untuk struktur, CSS untuk gaya, dan JavaScript untuk otak, kita berhasil menciptakan dua aplikasi web yang cukup menarik. Dari kalkulator yang menghitung setiap digit dengan presisi, hingga page builder yang memungkinkan kita menyusun elemen sesuka hati, Anda telah melihat sendiri kekuatan trio web fundamental ini.

Jangan berhenti di sini! Anggap artikel ini sebagai titik awal. Kembangkan kalkulator Anda dengan fungsi-fungsi ilmiah, atau buat page builder Anda lebih canggih dengan fitur resize, edit teks, atau simpan/muat layout. Dunia web development itu luas, dan setiap baris kode yang Anda tulis adalah langkah menuju penguasaan. Selamat ngoding, para insinyur digital!