Skip to content

Correct Answer & Lock Post Saving

Gambaran Umum

Video ini membahas cara menandai jawaban yang benar, ternary operator di JSX, dan fitur lock/unlock post saving agar user tidak bisa menyimpan post tanpa memilih jawaban yang benar.


1. Attribute correctAnswer

jsx
attributes: {
  question: { type: 'string' },
  answers: { type: 'array', default: [''] },
  correctAnswer: { type: 'number', default: undefined }
}

Default undefined: Digunakan agar bisa dibedakan dari 0 (index pertama). Angka 0 bersifat falsy di JavaScript, sehingga pembandingan dengan undefined lebih jelas.


2. Mark As Correct Function

jsx
function markAsCorrect(index) {
  props.setAttributes({ correctAnswer: index });
}

Hook ke Button:

jsx
<Button onClick={() => markAsCorrect(index)}>
  <Icon 
    icon={props.attributes.correctAnswer == index ? "star-filled" : "star-empty"} 
    className="mark-as-correct" 
  />
</Button>

Ternary Operator di JSX

JSX tidak mengizinkan if statement (hanya expressions). Gunakan ternary operator:

jsx
// Syntax: condition ? valueIfTrue : valueIfFalse
icon={props.attributes.correctAnswer == index ? "star-filled" : "star-empty"}
  • Jika correctAnswer sama dengan index saat ini → icon bintang penuh (star-filled)
  • Jika tidak → icon bintang kosong (star-empty)

3. Handle Delete: Reset correctAnswer

Saat user menghapus jawaban yang ditandai sebagai benar, correctAnswer harus di-reset ke undefined:

jsx
function deleteAnswer(indexToDelete) {
  const newAnswers = props.attributes.answers.filter(function(x, index) {
    return index != indexToDelete;
  });
  props.setAttributes({ answers: newAnswers });

  // Reset jika jawaban yang dihapus adalah yang benar
  if (indexToDelete == props.attributes.correctAnswer) {
    props.setAttributes({ correctAnswer: undefined });
  }
}

4. Lock Post Saving — Disable Tombol Save

Konsep

Jika ada instance quiz block yang belum memiliki jawaban benar, tombol Update/Save harus di-disable.

Masalah: Multiple Block Instances

Satu post bisa punya beberapa instance quiz block. Kita tidak bisa hanya cek satu block — harus cek semua instance.

WordPress Data API

Dari browser console, bisa melihat semua blocks di halaman:

javascript
wp.data.select('core/block-editor').getBlocks()
// Returns: Array of all blocks on the current page

Setiap block object berisi:

  • name — tipe block (misal: 'ourplugin/are-you-paying-attention')
  • attributes — semua attribute values

Implementasi: IIFE + wp.data.subscribe

jsx
// Immediately Invoked Function Expression (IIFE)
// Menghindari polusi global scope
(function() {
  let locked = false;

  wp.data.subscribe(function() {
    // Dijalankan setiap kali DATA APAPUN berubah di block editor

    const results = wp.data
      .select('core/block-editor')
      .getBlocks()
      .filter(function(block) {
        return block.name == 'ourplugin/are-you-paying-attention' 
            && block.attributes.correctAnswer == undefined;
      });

    // results = array quiz blocks yang BELUM punya correctAnswer

    if (results.length && !locked) {
      // Ada masalah DAN belum terkunci → LOCK
      locked = true;
      wp.data.dispatch('core/editor').lockPostSaving('no-answer');
    }

    if (!results.length && locked) {
      // Semua sudah punya jawaban DAN masih terkunci → UNLOCK
      locked = false;
      wp.data.dispatch('core/editor').unlockPostSaving('no-answer');
    }
  });
})();

Penjelasan Step-by-Step:

wp.data.subscribe(callback)

  • WordPress memanggil callback setiap kali data di block editor berubah
  • Ini termasuk mengetik, menambah/menghapus block, mengubah settings, dll.

getBlocks().filter(...)

  • Ambil semua blocks di halaman
  • Filter hanya block quiz yang correctAnswer masih undefined

lockPostSaving('no-answer')

  • Disable tombol Update/Save
  • Argumen 'no-answer' = identifier unik untuk alasan lock ini
  • Bisa ada beberapa lock dari sumber berbeda (WordPress mengelola semua)

unlockPostSaving('no-answer')

  • Enable kembali tombol Update/Save
  • Harus menggunakan identifier yang sama dengan saat lock

Variable locked

  • Menghindari pemanggilan lockPostSaving() berulang kali
  • Tanpa tracking ini, setiap perubahan data akan memanggil lock/unlock terus-menerus

IIFE (Immediately Invoked Function Expression)

javascript
// Sebelum (perlu nama unik):
function ourStartFunction() { ... }
ourStartFunction();

// Sesudah (IIFE — tanpa nama, langsung dieksekusi):
(function() {
  // Variabel di sini terisolasi dari global scope
  let locked = false;
  // ...
})();
Kelebihan IIFEPenjelasan
Scope isolationVariabel tidak bocor ke global scope
Tidak perlu nama unikTidak konflik dengan fungsi WordPress lain
Auto-executeLangsung jalan tanpa perlu dipanggil

Alur Kerja Lock/Unlock

User menambah quiz block baru (tanpa correctAnswer)
  → wp.data.subscribe() terpanggil
    → filter menemukan block tanpa correctAnswer
      → results.length > 0 && !locked
        → lockPostSaving('no-answer')
        → Tombol Save DISABLED ❌

User memilih correctAnswer
  → wp.data.subscribe() terpanggil
    → filter tidak menemukan masalah
      → results.length == 0 && locked
        → unlockPostSaving('no-answer')
        → Tombol Save ENABLED ✅