I am making a website with Quarto. I can add Javascript and HTML code in the quarto document (.qmd file). I am not well-versed in Javascript, but found the following:
<button class="show-answer" onclick="showAnswer('answer1')"> Show answer</button>
<p id="answer1" style="display: none;">Secret answer 1</p>
<button class="show-answer" onclick="showAnswer('answer2')"> Show answer</button>
<p id="answer2" style="display: none;">Secret answer 2</p>
<script>
function showAnswer(answerId) {
var answer = document.getElementById(answerId);
if (answer.style.display === "none") {
answer.style.display = "block";
} else {
answer.style.display = "none";
}
}
</script>
This works. The webpage, however, requires this button many times. Is it possible to make some kind of template, so I can write in the Quarto document (for example)
[answer] Secret answer [/answer]
The Javascript also seems to require some id, e.g. id="answer1"
. Is it possible to automate this id generation if I am using a template?
You can write a JS function that will replace a div element (created with pandoc divs ::: {.class}
) with answers or a span element (created with pandoc spans []{.class}
) with answers with the structure below,
<button class="show-answer" onclick="showAnswer('answer1')"> Show answer</button>
<p id="answer1" style="display: none;">Secret answer 1</p>
add-answer-button.html
<script>
function addAnswerWithButton(answerClass, buttonText, answerText) {
const divElement = document.querySelector(`.${answerClass}`);
const randomId = "answer-" + Math.floor(Math.random() * 1000000);
// Create the new button element
const buttonElement = document.createElement("button");
buttonElement.className = "show-answer";
buttonElement.textContent = buttonText;
buttonElement.onclick = function() {
showAnswer(randomId);
};
// Create the new answer element
const answerElement = document.createElement("p");
answerElement.id = randomId;
answerElement.style.display = "none";
answerElement.innerHTML = answerText;
// Replace the div element with the new button and answer elements
divElement.parentNode.replaceChild(buttonElement, divElement);
buttonElement.insertAdjacentElement("afterend", answerElement);
}
function showAnswer(answerId) {
var answer = document.getElementById(answerId);
if (answer.style.display === "none") {
answer.style.display = "block";
} else {
answer.style.display = "none";
}
}
function addAnswerButton() {
var answers = document.querySelectorAll(".answer")
answers.forEach(e => {
addAnswerWithButton("answer", " Show Answer", e.innerHTML);
});
}
window.document.addEventListener("DOMContentLoaded", function (event) {
addAnswerButton();
});
</script>
test.qmd
---
title: Answer Button
format: html
include-in-header: add-answer-button.html
---
## Exercise
Question1: What is 1 + 1? [Answer: 2]{.answer}
Question2: Some question?
[This is some answer to question 2]{.answer}
Question3: Some more question?
::: {.answer}
This is some answer to question 3
:::
Here you can write answers within squares bracket and then assign the .answer
class to it (e.g. [some answer]{.answer}
and it will be replaced with a button (See the rendered output below), and also you can write the answers wrapped within the :::
and assign the class .answer
to the div.