Save values edited by user in custom HTML / JS recipes

When I save annotations made with the custom html recipe, it seems that ProdiGy only records the “accept/reject”, the “text” field of the input jsonl file, “meta” tag, and task hashes. Any other values passed along in the input jsonl file just get passed to the database as is, it doesn’t seem to be possible to access them from the interface.

How can I pass some other value from my custom html interface, for example the contents of a div element that the annotator somehow modified?

document.addEventListener('prodigymount', event => {
    var r = document.querySelector('test_id').innerHTML;
    // get r and store in custom database   
}

with open("index.html") as txt:
    template_text = txt.read()

with open("src/js/main.js") as java:
    js = java.read()

@prodigy.recipe('my_recipe')
def test(dataset, source):

    db = connect('mysql')
    db.add_dataset(dataset)

    return {
        'dataset': dataset,                 
        'stream': JSONL(source),            
        'view_id': 'html',                  
        'db': db,                           
        'config': {'html_template': template_text,
                   "javascript"   : js }
    }

Yes, if you’re using a custom HTML template, you can decide how you want to format the data and what you want to show were. Each field in your data is available as a Mustache variable, so you can do something like this:

<div class="test">{{test_id}}</div>

This will render whatever is in the "test_id" field in your data.

The prodigy.update function lets you update the current task data with any object and will perform a shallow merge. The app never explicitly “stores” anything in the database – this happens later when the annotations are sent back to the server. So you want to update the data that’s currently displayed, so the new value is sent back to the back-end when you hit accept or reject. For example, overwriting the value of the "test_id" field in your data would look like this:

window.prodigy.update({ test_id: 'hello world' })

If your annotators are going to modify what’s displayed on the screen, you likely also want to add an event listener that listens for change events or similar (depending on the element), so you can update the task when it’s changed. I’d also recommend using a trigger element like a button to save the modifications, so you don’t have to manage the state (and potentially performance) yourself.

My comments on this thread have some examples of interactive HTML templates with JavaScript :slightly_smiling_face: