Skip to content

Time Management & Spinner — Debounce Pattern

Tujuan

  • Tunggu user selesai mengetik (~750-2000ms) sebelum kirim request
  • Tampilkan spinner loading saat menunggu
  • Jangan kirim request untuk setiap keystroke

Konsep: Debounce

User types: B → I → O → L → O → G → Y → [pause 800ms] → KIRIM REQUEST

Setiap keystroke:
  1. Clear timer sebelumnya
  2. Mulai timer baru (800ms)
  3. Jika user tekan key lagi sebelum timer habis → kembali ke langkah 1
  4. Jika timer habis (user berhenti typing) → jalankan function

Implementasi

Constructor — Properti Baru

js
constructor() {
  // ... properti element
  this.searchField = $("#search-term");
  this.resultsDiv = $("#search-overlay__results");
  this.typingTimer;               // Timer reference
  this.isSpinnerVisible = false;  // State spinner
  this.previousValue;             // Nilai search sebelumnya
  this.isOverlayOpen = false;
  this.events();
}

Events — Tambah Keyup pada Search Field

js
events() {
  // ... event lain
  this.searchField.on("keyup", this.typingLogic.bind(this));
}

⚠️ Gunakan keyup (bukan keydown) untuk typing logic. keydown fire sebelum browser update nilai input, sehingga previousValue tidak akurat.

typingLogic — Debounce Method

js
typingLogic() {
  if (this.searchField.val() != this.previousValue) {
    clearTimeout(this.typingTimer);

    if (this.searchField.val()) {
      // Field tidak kosong — mulai proses
      if (!this.isSpinnerVisible) {
        this.resultsDiv.html('<div class="spinner-loader"></div>');
        this.isSpinnerVisible = true;
      }
      this.typingTimer = setTimeout(this.getResults.bind(this), 750);
    } else {
      // Field kosong — clear everything
      this.resultsDiv.html('');
      this.isSpinnerVisible = false;
    }
  }

  this.previousValue = this.searchField.val();
}

getResults — Placeholder (akan diisi di chapter berikutnya)

js
getResults() {
  this.resultsDiv.html("Imagine real search results here.");
  this.isSpinnerVisible = false;
}

Alur Lengkap

┌─ User buka overlay (S key / click) ─────────────────┐
│                                                       │
│  User mulai typing: "bio"                            │
│  ├─ Keystroke "b" → clearTimeout → show spinner      │
│  │                 → setTimeout(getResults, 750ms)    │
│  ├─ Keystroke "i" → clearTimeout → timer reset       │
│  │                 → setTimeout(getResults, 750ms)    │
│  ├─ Keystroke "o" → clearTimeout → timer reset       │
│  │                 → setTimeout(getResults, 750ms)    │
│  │                                                    │
│  [user berhenti mengetik 750ms]                      │
│  │                                                    │
│  └─ getResults() berjalan → kirim request ke WP      │
│                           → tampilkan hasil           │
└───────────────────────────────────────────────────────┘

State Management Properties

PropertyDefaultFungsi
typingTimerundefinedReference ke setTimeout, agar bisa di-clear
isSpinnerVisiblefalseMencegah spinner di-reset setiap keystroke
previousValueundefinedMembandingkan: apakah keystroke mengubah value?
isOverlayOpenfalseGuard untuk open/close — mencegah repeated calls

Kenapa Cek previousValue?

Tombol seperti Arrow keys, Shift, Ctrl memicu keyup event tapi tidak mengubah isi input field. Tanpa pengecekan ini, setiap tekan arrow key akan memicu spinner + timer baru padahal search string tidak berubah.