Skip to content

Congrats/Sorry Messages, Icons & Callbacks

Logika Benar/Salah di guessAttempt

If/Else di view.js

js
store("create-block", {
  actions: {
    guessAttempt: () => {
      const context = getContext();
      
      if (!context.solved) {
        if (context.index === context.correctAnswer) {
          // Jawaban BENAR
          context.showCongrats = true;
          context.solved = true;
        } else {
          // Jawaban SALAH
          context.showSorry = true;
          setTimeout(() => {
            context.showSorry = false;
          }, 2600);
        }
      }
    },
  },
});

Logika:

  1. Cek !context.solved → hanya proses jika belum terjawab
  2. Bandingkan context.index (jawaban diklik) dengan context.correctAnswer
  3. Benar: set showCongrats = true dan solved = true
  4. Salah: set showSorry = true, lalu setTimeout 2.6 detik untuk menghilangkan

Directive: data-wp-class--[className]

Toggle CSS Class Berdasarkan Context

html
<!-- Pesan SALAH -->
<div class="incorrect-message"
     data-wp-class--incorrect-message--visible="context.showSorry">
  <svg><!-- X icon merah --></svg>
  <p>Sorry, that is not correct!</p>
</div>

<!-- Pesan BENAR -->
<div class="correct-message"
     data-wp-class--correct-message--visible="context.showCongrats">
  <svg><!-- Checkmark icon hijau --></svg>
  <p>That's correct!</p>
</div>

Cara kerja data-wp-class--:

  • data-wp-class--incorrect-message--visible="context.showSorry"
  • Jika context.showSorry bernilai true → tambahkan class incorrect-message--visible
  • Jika false → hapus class tersebut
  • CSS class --visible mengontrol animasi muncul/hilang

Animasi Otomatis

css
.incorrect-message { 
  opacity: 0; 
  transition: opacity 0.5s; 
}
.incorrect-message--visible { 
  opacity: 1; 
}

Directive: data-wp-bind--hidden

html
<li>
  <!-- Wrapper span: tampil hanya setelah solved -->
  <span data-wp-bind--hidden="!context.solved">
    
    <!-- Green checkmark: hanya untuk jawaban benar -->
    <span data-wp-bind--hidden="!context.correct">
      <svg class="correct-icon"><!-- ✓ hijau --></svg>
    </span>
    
    <!-- Red X: hanya untuk jawaban salah -->
    <span data-wp-bind--hidden="context.correct">
      <svg class="incorrect-icon"><!-- ✗ merah --></svg>
    </span>
    
  </span>
  <?php echo esc_html($answer['text']); ?>
</li>

Cara kerja data-wp-bind--hidden:

  • Menambahkan/menghapus attribute HTML hidden pada elemen
  • "!context.solved" → hidden jika belum solved (icon tersembunyi sampai quiz selesai)
  • "!context.correct" → checkmark hidden jika bukan jawaban benar
  • "context.correct" → red X hidden jika jawaban benar

Timing: Delay Tampilnya Icon

js
// Di view.js — jangan langsung set solved = true
// Tunggu 1 detik agar congrats message muncul dulu
if (context.index === context.correctAnswer) {
  context.showCongrats = true;
  setTimeout(() => {
    context.solved = true;
  }, 1000);
}

Alur: congrats message muncul → 1 detik → icon muncul (setelah congrats fade out)

Callbacks: Logika Kompleks untuk Class Management

Masalah: data-wp-class tidak bisa terima expression

html
<!-- ❌ TIDAK BISA — expression langsung di directive -->
<li data-wp-class--fade-incorrect="!context.correct && context.solved">

<!-- ❌ Error JavaScript! -->

Solusi: Gunakan Callback

html
<!-- ✅ Gunakan callback untuk logika kompleks -->
<li data-wp-on--click="actions.guessAttempt"
    data-wp-class--fade-incorrect="callbacks.fadedClass"
    data-wp-class--no-click="callbacks.noClickClass"
    <?php echo wp_interactivity_data_wp_context($answer); ?>>

Definisi Callbacks di view.js

js
store("create-block", {
  actions: {
    guessAttempt: () => { /* ... */ },
  },
  callbacks: {
    fadedClass: () => {
      const context = getContext();
      // Fade jawaban SALAH setelah quiz solved
      return context.solved && !context.correct;
    },
    noClickClass: () => {
      const context = getContext();
      // Hilangkan hover effect pada jawaban BENAR setelah solved
      return context.solved && context.correct;
    },
  },
});

Apa Itu Callback?

  • Action = fungsi yang dijalankan saat event terjadi (click, keyup, dll.)
  • Callback = fungsi yang return true/false untuk mengontrol directive secara reaktif

Kapan gunakan callback:

  • Ketika directive butuh lebih dari satu kondisi (AND/OR logic)
  • Ketika butuh logic kompleks yang tidak bisa ditulis dalam satu expression
  • Bisa mengecek 50 faktor berbeda lalu return satu boolean

CSS Classes yang Dikelola

css
/* Fade jawaban salah */
.fade-incorrect {
  opacity: 0.4;
  cursor: default;
}
.fade-incorrect svg { fill: red; }

/* Hilangkan hover pada jawaban benar yang sudah solved */
.no-click {
  cursor: default;
}
.no-click:hover {
  background-color: transparent;
}

Alur Lengkap Quiz

Page Load
  → context: { solved: false, showCongrats: false, showSorry: false }
  → Semua jawaban tampil normal, icon tersembunyi

User Klik Jawaban SALAH
  → showSorry = true → "Sorry" message muncul (opacity 1)
  → 2.6 detik → showSorry = false → message hilang
  → Bisa mencoba lagi

User Klik Jawaban BENAR  
  → showCongrats = true → "Correct!" message muncul
  → 1 detik → solved = true → icon muncul
    → callbacks.fadedClass → jawaban salah di-fade + red ✗
    → callbacks.noClickClass → jawaban benar no-hover + green ✓
  → Klik selanjutnya tidak diproses (!context.solved = false)

Ringkasan Directive Baru

DirectiveFungsiNilai
data-wp-class--[name]Toggle CSS classcontext.prop atau callbacks.fn
data-wp-bind--hiddenToggle attribute hiddencontext.prop (true = hidden)

Tips: Extra Credit

Nested span untuk icon bisa disederhanakan dengan callback langsung di SVG:

html
<!-- Daripada nested spans, gunakan callback per SVG -->
<svg data-wp-bind--hidden="callbacks.hideCheckmark"><!-- ✓ --></svg>
<svg data-wp-bind--hidden="callbacks.hideRedX"><!-- ✗ --></svg>

Dengan callback yang mengecek solved && correct atau solved && !correct.