Update: All works pretty smoothly already! :
The above example only needed the following html_template
and javascript
config:
<button class="custom-button" onClick="updateText()">
👇 Text to uppercase
</button>
<br />
<strong>{{text}}</strong>
let upper = false;
function updateText() {
const text = window.prodigy.content.text;
const newText = !upper ? text.toUpperCase() : text.toLowerCase();
window.prodigy.update({ text: newText });
upper = !upper;
document.querySelector('.custom-button').textContent = '👇 Text to ' + (upper ? 'lowercase' : 'uppercase')
}
Things I tested in the above example that already work:
- Dynamic update of the annotation task’s content in the HTML template.
- Keeping arbitrary state within the custom JavaScript – pretty rudimentary here, but could easily be expanded. (Still need to test ways to keep cross-task state.)
- Accessing elements in custom HTML components via the DOM – alternatively, I think you could also pass
this
toupdateText()
, but working with query selectors is often cleaner. (Nice plus: class names are unlikely to conflict with built-ins, because Styled Components mangles them when the Prodigy app is compiled.)
I’ve also added a user_config
option to the config parameters passed in via the recipe and prodigy.json
. This allows custom interfaces to refer to arbitrary config via window.prodigy.config.userConfig
.
Edit: Dispatching custom events works as well. So you’ll also be able to do this:
document.addEventListener('prodigyanswer', ev => {
console.log('The answer was: ', ev.detail)
});
I didn’t realise you couldn’t write to the top-level event
and had to use event.detail
. So we might want to change it slightly to always expose an object here.