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
attributes: {
question: { type: 'string' },
answers: { type: 'array', default: [''] },
correctAnswer: { type: 'number', default: undefined }
}Default
undefined: Digunakan agar bisa dibedakan dari0(index pertama). Angka0bersifat falsy di JavaScript, sehingga pembandingan denganundefinedlebih jelas.
2. Mark As Correct Function
function markAsCorrect(index) {
props.setAttributes({ correctAnswer: index });
}Hook ke Button:
<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:
// Syntax: condition ? valueIfTrue : valueIfFalse
icon={props.attributes.correctAnswer == index ? "star-filled" : "star-empty"}- Jika
correctAnswersama denganindexsaat 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:
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:
wp.data.select('core/block-editor').getBlocks()
// Returns: Array of all blocks on the current pageSetiap block object berisi:
name— tipe block (misal:'ourplugin/are-you-paying-attention')attributes— semua attribute values
Implementasi: IIFE + wp.data.subscribe
// 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
callbacksetiap 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
correctAnswermasihundefined
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)
// 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 IIFE | Penjelasan |
|---|---|
| Scope isolation | Variabel tidak bocor ke global scope |
| Tidak perlu nama unik | Tidak konflik dengan fungsi WordPress lain |
| Auto-execute | Langsung 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 ✅