Hasil Akhir: Widget Interaktif yang Berfungsi Penuh
Sebelum kita mulai membuat kode, mari kita lihat hasil akhir dari widget ini. Widget ini dirancang secara responsif dan adaptif. Secara default, ia akan menampilkan jadwal untuk Surabaya. Namun, Anda bisa mengklik tombol untuk menyesuaikannya dengan lokasi Anda saat ini.
Bulan suci Ramadan selalu membawa semangat baru dalam hal perbaikan diri, disiplin, dan manajemen waktu. Bagi umat Islam, mengetahui secara pasti waktu imsak dan buka puasa adalah hal yang sangat krusial. Di era digital saat ini, kemudahan akses informasi tersebut dapat difasilitasi melalui teknologi web. Program Studi S1 Pendidikan Matematika Unesa tidak hanya berfokus pada keilmuan teoritis, tetapi juga bagaimana ilmu algoritma dan komputasi dapat diimplementasikan menjadi produk teknologi terapan yang bermanfaat bagi masyarakat luas, misalnya melalui Mata Kuliah Pemrograman Visual.
Artikel tutorial ini akan membahas secara detail dan komprehensif mengenai cara membangun widget countdown (hitung mundur) jadwal Imsakiyah dan Buka Puasa. Kita akan menyusunnya murni menggunakan HTML (HyperText Markup Language), CSS (Cascading Style Sheets), dan JavaScript yang stabil tanpa memerlukan framework eksternal. Pendekatan ini sangat relevan bagi masyarakat umum yang tertarik pada pemrograman web dasar, maupun bagi mahasiswa calon pendidik yang sedang mendalami Computational Thinking.
Keterkaitan dengan Tujuan Pembangunan Berkelanjutan (SDGs)
Pengembangan proyek teknologi berbasis web seperti ini memiliki kaitan yang kuat dengan agenda global PBB, yaitu Sustainable Development Goals (SDGs):
- SDG 4: Pendidikan Berkualitas. Tutorial ini merupakan bentuk literasi digital dan keterampilan abad ke-21. Mempelajari alur logika pemrograman (computational thinking) memberikan edukasi vokasional yang relevan dengan kebutuhan industri digital saat ini.
- SDG 9: Industri, Inovasi, dan Infrastruktur. Mendorong lahirnya inovator-inovator muda. Kemampuan membuat program aplikasi secara mandiri—seperti mengintegrasikan API lokasi dan waktu—merupakan fondasi dasar dalam membangun infrastruktur teknologi informasi yang adaptif dan tangguh.
Computational Thinking dan Hubungannya dengan Pembelajaran Matematika
Pembuatan widget ini bukan sekadar aktivitas mengetik kode. Di baliknya terdapat penerapan Computational Thinking (CT) atau pemikiran komputasional. CT melibatkan pemecahan masalah dengan cara yang dapat dieksekusi oleh komputer, melalui langkah-langkah seperti dekomposisi, pengenalan pola, abstraksi, dan perancangan algoritma.
Melalui Mata Kuliah Pemrograman Visual di S1 Pendidikan Matematika, pembuatan widget ini menjadi studi kasus yang sangat relevan bagi para mahasiswa calon pendidik. Anda diajak untuk berlatih berpikir logis dan terstruktur. Bagaimana mengubah konsep abstrak "waktu mundur" menjadi serangkaian operasi matematika yang dapat dipahami oleh bahasa pemrograman? Latihan ini mempertajam nalar matematis, bukan lagi sekadar di atas kertas, melainkan ditransformasikan ke dalam bentuk aplikasi nyata yang bisa langsung dimanfaatkan oleh masyarakat.
Dengan menguasai keterampilan komputasi ini, seorang pendidik tidak lagi sekadar menjadi konsumen teknologi, melainkan bertransformasi menjadi seorang pencipta karya. Anda memiliki bekal yang kuat untuk merancang sendiri media pembelajaran matematika yang lebih modern, dinamis, dan relevan dengan generasi masa kini.
Penjelasan Matematis Algoritma Countdown
Inti dari widget ini adalah sebuah fungsi yang menghitung selisih waktu. Secara matematis, kita dapat merumuskannya sebagai berikut:
Selisih Waktu ($\Delta t$) = Waktu Target ($t_1$) - Waktu Saat Ini ($t_0$)
Dalam JavaScript, waktu direpresentasikan dalam milidetik (ms) sejak 1 Januari 1970 (Unix Epoch). Oleh karena itu, selisih waktu yang dihasilkan juga dalam bentuk milidetik. Tugas kita selanjutnya adalah mengonversi nilai milidetik ini menjadi format jam, menit, dan detik yang mudah dipahami manusia.
Di sinilah operasi matematika, khususnya operasi pembagian dan modulo (sisa bagi), memainkan peran penting:
- 1 Detik = 1000 ms
- 1 Menit = 60 detik = 60.000 ms
- 1 Jam = 60 menit = 3.600.000 ms
- 1 Hari = 24 jam = 86.400.000 ms
Untuk mendapatkan sisa Jam, kita mengambil sisa pembagian dari total hari, lalu membaginya dengan jumlah milidetik dalam satu jam. Menggunakan fungsi Math.floor(), kita membulatkan hasilnya ke bawah.
Jam = Math.floor( ( $\Delta t$ % (1000 * 60 * 60 * 24) ) / (1000 * 60 * 60) )
Pola yang sama diterapkan untuk mencari Menit dan Detik. Proses ini terus diulang setiap detik (menggunakan setInterval) sehingga menghasilkan efek "hitung mundur".
Diagram Alur Program
Berikut adalah representasi diagram alur sederhana dari proses kerja widget ini:
Potensi Inovasi Aplikasi & Media Pembelajaran Edukatif
Sebagai mahasiswa calon pendidik matematika atau bagian dari masyarakat umum yang menggemari teknologi, Anda memiliki kebebasan penuh untuk membongkar, menganalisis, dan memodifikasi kode dasar ini menjadi karya yang jauh lebih besar. Berbekal logika waktu dan pemrograman dasar dari tutorial ini, Anda dapat merancang berbagai inovasi media pembelajaran, seperti:
- Kustomisasi Visual: Mengubah antarmuka (UI) dengan tema animasi yang lebih ceria dan ramah anak (child-friendly) agar dapat digunakan secara interaktif di layar proyektor kelas.
- Sistem Reward: Menambahkan baris kode untuk memunculkan fitur suara bel atau animasi pop-up sebagai *reward* saat waktu hitung mundur selesai.
- Gim Berbasis Waktu: Menggunakan struktur perhitungan timer (hitungan mundur detik) ini untuk menciptakan kuis matematika berbatas waktu, kompetisi simulasi hitung cepat antarsiswa, atau aplikasi edukasi numerik mandiri berbasis web.
Inovasi-inovasi seperti inilah yang akan menjembatani teori algoritma matematis dengan dunia aplikasi praktis, sehingga mampu menghadirkan pengalaman belajar yang jauh lebih interaktif, menyenangkan, dan bermakna.
Arsitektur Kode: Bagaimana HTML, CSS, dan JavaScript Bekerja Sama
Sebelum masuk ke penulisan kode, sangat penting untuk memahami peran dari ketiga bahasa utama yang akan kita gunakan. Memahami fondasi ini akan membuat proses modifikasi di masa depan menjadi jauh lebih mudah:
- HTML (Kerangka DOM): Berfungsi menyediakan struktur. Kita akan membuat kotak-kotak penampung angka dengan atribut
idspesifik (sepertiid="h-jam"). Atributidini adalah "nama panggilan" yang akan digunakan oleh JavaScript untuk mencari letak elemen di halaman web dan menyuntikkan data ke dalamnya secara langsung (proses manipulasi DOM). - CSS (Visualisasi): CSS bertugas mempercantik elemen yang sudah dibuat HTML. Kita menggunakan tata letak Flexbox untuk menyejajarkan waktu, serta menggunakan warna-warna kontras tinggi agar widget mudah dibaca oleh siapa saja.
- JavaScript (Otak & Dinamika): Ini adalah bagian yang paling kompleks dan krusial. JavaScript kita bertugas melakukan tiga hal:
- Fetch API: Mengambil jadwal secara nirkabel dari server Aladhan. Sebagai bawaan, widget kita akan diatur untuk memuat jadwal salat untuk lokasi Surabaya terlebih dahulu agar pengunjung tidak melihat kotak kosong saat web baru dimuat.
- Geolocation: Jika pengunjung menekan tombol 'Lokasi', JavaScript akan meminta izin peramban (browser) untuk melacak titik koordinat GPS mereka dan mengganti jadwal Surabaya menjadi jadwal lokal pengunjung tersebut secara real-time.
- SetInterval: Fungsi yang memastikan layar menghitung mundur setiap satu detik (1000 milidetik), mengonversi milidetik menjadi jam, menit, dan detik menggunakan operasi Modulo (sisa pembagian).
Langkah 1: Membuat Kerangka Utama dengan HTML
Silakan salin struktur dasar berikut. Area teks id="location-info" akan otomatis dikelola oleh JavaScript untuk menginformasikan kepada pengguna bahwa sistem sedang memuat jadwal default Surabaya.
<div id="ramadan-widget" class="widget-container">
<!-- Bagian Judul (Teks 'Imsak' atau 'Buka Puasa' akan berubah otomatis) -->
<div class="widget-title">Menuju <span id="event-name">MEMUAT...</span></div>
<!-- Wadah flexbox untuk menyejajarkan kotak waktu -->
<div class="countdown-flex">
<!-- Kotak Jam -->
<div class="time-box">
<span id="h-jam" class="time-value">--</span>
<span class="time-label">Jam</span>
</div>
<!-- Kotak Menit -->
<div class="time-box">
<span id="h-menit" class="time-value">--</span>
<span class="time-label">Menit</span>
</div>
<!-- Kotak Detik -->
<div class="time-box">
<span id="h-detik" class="time-value">--</span>
<span class="time-label">Detik</span>
</div>
</div>
<!-- Tombol interaktif untuk menyesuaikan lokasi GPS -->
<button onclick="dapatkanLokasi()" class="btn-lokasi">📍 Sesuaikan dengan Lokasi Saya</button>
<p id="location-info" class="info-teks">Memuat jadwal otomatis (Surabaya)...</p>
</div>
Langkah 2: Mempercantik Tampilan dengan CSS
Agar antarmuka pengguna (UI) modern dan elegan, letakkan kode ini di dalam tag <style> pada blog Anda. Kami menggunakan satuan fleksibel seperti rem untuk memastikan widget tampil responsif di layar mobile.
/* Desain background dan bentuk kotak utama widget */
.widget-container { background: linear-gradient(135deg, #276749 0%, #22543d 100%); border-radius: 15px; padding: 30px; color: white; text-align: center; box-shadow: 0 10px 25px rgba(0,0,0,0.2); margin: 30px 0; font-family: 'Segoe UI', Tahoma, sans-serif; box-sizing: border-box; }
/* Desain teks judul di atas */
.widget-title { font-size: 1.8rem; font-weight: bold; margin-bottom: 20px; color: #fbd38d; text-transform: uppercase; letter-spacing: 2px; }
/* Pengaturan tata letak agar kotak waktu berjajar rapi ke samping */
.countdown-flex { display: flex; justify-content: center; gap: 15px; flex-wrap: wrap; }
/* Desain masing-masing kotak transparan untuk Jam/Menit/Detik */
.time-box { background-color: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); border-radius: 10px; padding: 15px 20px; min-width: 80px; box-sizing: border-box; }
/* Gaya huruf untuk angka hitung mundur (dibuat besar) */
.time-value { font-size: 2.5rem; font-weight: bold; display: block; }
/* Gaya huruf untuk label 'Jam', 'Menit', 'Detik' */
.time-label { font-size: 1rem; text-transform: uppercase; letter-spacing: 1px; }
/* Desain tombol pelacak lokasi */
.btn-lokasi { background: #48bb78; color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-weight: bold; margin-top: 25px; margin-bottom: 10px; font-size: 1rem; box-shadow: 0 4px 6px rgba(0,0,0,0.1); transition: background 0.3s; }
.btn-lokasi:hover { background: #38a169; }
/* Desain teks keterangan lokasi */
.info-teks { font-size: 1.1rem; margin-top: 10px; color: #c6f6d5; margin-bottom: 0; }
/* Responsivitas untuk layar HP */
@media (max-width: 768px) {
.countdown-flex { gap: 10px; }
.time-box { padding: 10px; min-width: 60px; }
.time-value { font-size: 1.8rem; }
.widget-title { font-size: 1.4rem; }
}
</style>
Langkah 3: Mengelola Data Secara Dinamis dengan JavaScript (Default Surabaya)
Kode di bawah ini dirancang khusus untuk memanggil data wilayah Surabaya secara otomatis saat pertama kali dimuat. Kita menggunakan titik koordinat lintang (Latitude) -7.250445 dan bujur (Longitude) 112.768845 milik Surabaya.
Apabila pengguna mengklik "Sesuaikan dengan Lokasi Saya" namun membatalkan izin (atau gagal terdeteksi), sistem akan otomatis kembali mengandalkan jadwal Surabaya, sehingga widget dijamin stabil, tidak akan error atau berstatus kosong.
// Variabel global untuk menyimpan jam imsak & buka (Aman)
let jamImsak = 4, menitImsak = 15;
let jamBuka = 17, menitBuka = 30;
let dataTersedia = false;
// Fungsi inti untuk memanggil data API Aladhan (Metode 20 = Kemenag RI)
function ambilJadwalAPI(lat, lng, namaLokasi) {
const infoEl = document.getElementById('location-info');
if(infoEl) infoEl.innerText = `Memuat jadwal untuk ${namaLokasi}...`;
fetch(`https://api.aladhan.com/v1/timings?latitude=${lat}&longitude=${lng}&method=20`)
.then(res => {
if(!res.ok) throw new Error("Network response was not ok");
return res.json();
})
.then(data => {
const jadwal = data.data.timings;
jamImsak = parseInt(jadwal.Imsak.split(':')[0]);
menitImsak = parseInt(jadwal.Imsak.split(':')[1]);
jamBuka = parseInt(jadwal.Maghrib.split(':')[0]);
menitBuka = parseInt(jadwal.Maghrib.split(':')[1]);
dataTersedia = true;
if(infoEl) infoEl.innerText = `Jadwal akurat wilayah ${namaLokasi} (Imsak: ${jadwal.Imsak}, Buka: ${jadwal.Maghrib}).`;
jalankanHitungMundur(); // Panggil fungsi agar UI langsung update seketika
})
.catch(() => {
// Fallback jika API gagal (Tetap jalankan widget dengan data default)
dataTersedia = true;
if(infoEl) infoEl.innerText = "Gagal memuat API. Menggunakan jadwal cadangan (Surabaya).";
});
}
// SAAT DIMUAT: Panggil API dengan koordinat default (Surabaya)
ambilJadwalAPI(-7.250445, 112.768845, "Surabaya");
// FUNGSI TOMBOL LOKASI: Jika tombol diklik, minta izin pelacakan lokasi
function dapatkanLokasi() {
const infoEl = document.getElementById('location-info');
if(infoEl) infoEl.innerText = "Mendeteksi lokasi... mohon izinkan akses.";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((pos) => {
// Jika Diizinkan: Panggil API dengan koordinat aktual
ambilJadwalAPI(pos.coords.latitude, pos.coords.longitude, "Lokasi Anda");
}, () => {
// Jika Ditolak: Tetap gunakan lokasi Surabaya
if(infoEl) infoEl.innerText = "Akses lokasi ditolak. Tetap menggunakan jadwal Surabaya.";
ambilJadwalAPI(-7.250445, 112.768845, "Surabaya");
});
} else {
if(infoEl) infoEl.innerText = "Geolokasi tidak didukung. Memakai jadwal Surabaya.";
}
}
// ENGINE HITUNG MUNDUR (Dijalankan setiap 1 detik)
function jalankanHitungMundur() {
if(!dataTersedia) return; // Cegah error sebelum data turun dari API
const waktuSekarang = new Date();
let waktuTarget = new Date();
let namaEvent = "";
const imsakHariIni = new Date();
imsakHariIni.setHours(jamImsak, menitImsak, 0, 0);
const bukaHariIni = new Date();
bukaHariIni.setHours(jamBuka, menitBuka, 0, 0);
if (waktuSekarang < imsakHariIni) {
waktuTarget = imsakHariIni;
namaEvent = "Imsak";
} else if (waktuSekarang < bukaHariIni) {
waktuTarget = bukaHariIni;
namaEvent = "Buka Puasa";
} else {
waktuTarget = imsakHariIni;
waktuTarget.setDate(waktuTarget.getDate() + 1);
namaEvent = "Imsak Besok";
}
const selisih = waktuTarget.getTime() - waktuSekarang.getTime();
let jam = Math.floor((selisih % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let menit = Math.floor((selisih % (1000 * 60 * 60)) / (1000 * 60));
let detik = Math.floor((selisih % (1000 * 60)) / 1000);
document.getElementById('event-name').innerText = namaEvent;
document.getElementById('h-jam').innerText = jam.toString().padStart(2, '0');
document.getElementById('h-menit').innerText = menit.toString().padStart(2, '0');
document.getElementById('h-detik').innerText = detik.toString().padStart(2, '0');
}
setInterval(jalankanHitungMundur, 1000);
</script>
Langkah 4: Panduan Lengkap Memasang Widget di Blog/Website
Kode HTML yang telah kita pelajari di atas sudah dirancang sepenuhnya mandiri (self-contained). Artinya, semua CSS dan JavaScript tidak bergantung pada file lain di server Anda. Anda bisa langsung menempelkannya (paste) ke platform blog mana pun tanpa takut merusak desain utama website.
1. Untuk Pengguna Blogger / Blogspot
- Masuk ke dasbor Blogger Anda.
- Klik tombol Posting Baru (atau edit postingan yang sudah ada).
- Perhatikan ikon pensil di pojok kiri atas (di bawah judul). Klik ikon tersebut, lalu ubah mode dari Tampilan Menulis (Compose view) menjadi Tampilan HTML (HTML view).
- Hapus semua kode yang ada di sana (jika ada), lalu Tempel (Paste) seluruh kode HTML yang telah kita buat.
- Anda bisa mengklik "Pratinjau" untuk melihat hasilnya, lalu klik Publikasikan.
2. Untuk Pengguna WordPress
A. Menggunakan Block Editor (Gutenberg) - Default:
- Buat Post Baru atau edit post yang ada.
- Klik ikon [+] untuk menambahkan blok baru.
- Cari dan pilih blok bernama Custom HTML (HTML Khusus).
- Tempel (Paste) seluruh kode HTML ke dalam kotak blok tersebut.
- Klik tab "Preview" pada blok tersebut untuk melihat hasilnya, lalu Publish.
B. Menggunakan Classic Editor:
- Buka editor postingan.
- Di pojok kanan atas area teks, terdapat dua tab: "Visual" dan "Text". Klik tab Text.
- Tempel (Paste) seluruh kode HTML di area teks tersebut, lalu klik Publish.
3. Untuk Pengguna Google Sites
- Buka halaman Google Sites Anda.
- Di panel sebelah kanan, pilih menu Sematkan (Embed).
- Pilih tab Sematkan kode (Embed code).
- Tempel (Paste) seluruh kode HTML ke dalam kotak yang disediakan.
- Klik Berikutnya (Next), lalu klik Sisipkan (Insert). Sesuaikan ukuran kotak widget dengan menarik ujungnya.
4. Untuk Pengguna Wix
- Buka Wix Editor Anda.
- Klik tombol Add (+) di bilah alat sebelah kiri.
- Pilih menu Embed Code, lalu klik Embed HTML.
- Akan muncul sebuah kotak elemen di halaman Anda. Klik Enter Code di atas kotak tersebut.
- Pilih opsi Code, lalu Tempel (Paste) seluruh kode HTML yang sudah disalin.
- Klik Update dan sesuaikan dimensi/ukuran kotaknya.
5. Untuk Website Native (Custom HTML/PHP)
- Buka file halaman web Anda (misalnya
index.html,sidebar.php, atauartikel.php) menggunakan editor kode. - Cari area konten atau sidebar tempat Anda ingin menampilkan widget ini (biasanya di dalam tag
<main>,<aside>, atau<div class="content">). - Tempel (Paste) kode secara berurutan sesuai panduan di bawah ini.
Agar widget dapat langsung berfungsi di blog/website Anda tanpa error, ikuti urutan ini di editor HTML platform Anda:
- Pertama: Salin seluruh kerangka HTML dari Langkah 1 dan letakkan di area konten Anda.
- Kedua: Salin kode CSS dari Langkah 2 (lengkap dengan tag
<style>) dan letakkan tepat di atas kode HTML tadi. - Ketiga: Beralihlah ke Langkah 3. Salin seluruh blok kode JavaScript beserta tag pembuka
<script>dan penutup</script>. Letakkan tepat di bawah kode HTML yang Anda tempelkan pada urutan Pertama. - Selesai! Simpan (Save) atau Publikasikan. Widget Anda kini akan beroperasi otomatis dan stabil.
Kesimpulan
Membuat widget hitung mundur waktu buka puasa dan imsakiyah bukan sekadar aktivitas mengetik kode secara membabi-buta. Ini adalah proses mengorkestrasi tata letak elemen dengan HTML, menghiasnya agar memanjakan mata dengan CSS, dan meniupkan logika interaktif dinamis menggunakan JavaScript. Dengan menguasai arsitektur Front-End ini, Anda—baik sebagai mahasiswa calon pendidik matematika maupun masyarakat umum—memiliki modal kuat untuk menciptakan inovasi teknologi yang praktis tanpa perlu bergantung pada pihak ketiga. Mari terus bereksperimen dan ciptakan karya digital edukatif yang bermanfaat bagi sekitar!
Glosarium
- API (Application Programming Interface): Sistem perantara yang memungkinkan aplikasi kita (widget) untuk "berbicara" dan menarik data dari aplikasi lain (server Aladhan) secara nirkabel.
- Cascading Style Sheets (CSS): Bahasa yang digunakan untuk mengatur desain, warna, dan tata letak dokumen web.
- Computational Thinking (CT): Proses pemecahan masalah dengan melibatkan formulasi masalah dan solusinya, sedemikian rupa sehingga solusinya disajikan dalam bentuk yang dapat dijalankan oleh agen pemroses informasi (seperti komputer).
- DOM (Document Object Model): Antarmuka pemrograman yang merepresentasikan struktur HTML di layar, sehingga JavaScript dapat memanipulasi teks dan angka di dalamnya secara langsung.
- Fetch: Perintah pada JavaScript modern yang digunakan untuk mengambil data (HTTP Request) dari server lain di internet.
- Geolocation: API khusus pada browser yang meminta perangkat keras (komputer/HP) untuk menyediakan data titik lintang dan bujur lokasi pengguna saat ini.
- HyperText Markup Language (HTML): Bahasa standar yang digunakan untuk membuat kerangka dasar suatu halaman web.
- JavaScript (JS): Bahasa pemrograman tingkat tinggi yang membuat halaman web menjadi interaktif dan dapat mengeksekusi logika secara otomatis.
Daftar Rujukan
- Mozilla Developer Network (MDN) Web Docs. "Fetch API" & "Geolocation API", Referensi standar web modern.
- Islamic Prayer Times API (Aladhan). Dokumentasi pengambilan jadwal waktu salat global.
- Perserikatan Bangsa-Bangsa (PBB). "Sustainable Development Goals (SDGs)", Agenda Pembangunan Berkelanjutan.
- Kurikulum S1 Pendidikan Matematika. Pemrograman Visual dan Literasi Digital.

