Introduction
Autosaving for file uploads requires a refreshed _nonce value during each file submission. We can implement a custom script that enables background autosave functionality for single-file upload fields in assignment forms (inbox views).
Important Notes
- Supported only in assignment forms (e.g., those accessed from the user’s Inbox).
- Works only with single-file upload fields; multi-file upload fields are not supported.
- Customization required; you must update the form, dropzone, and saveAsDraft element selectors in the script to match the structure of your specific form.
How does it work?
- In Form Builder, identify the single file upload field you wish to autosave.
- Locate the form’s form, dropzone, and Save As Draft button selectors. Please take note down the selector by inspecting your form element and update these selectors in the script. Figure 1: Identify and note the selector used to update the form_id within the script. Figure 2: Identify and note the selector used to update the file upload field_id within the script.
- Drag and drop a Custom HTML element from the palette to the form.
- Insert the following autosave script into the Custom HTML element in your form. Modify the form, dropzone, and saveAsDraft element selectors with the selectors from your form.
var autoSaveJob; $(document).on('page_loaded', function () { clearInterval(autoSaveJob); var fileName = ""; function saveForm() { var form = $('form#request'); //CHANGE THIS - if required const params = new URLSearchParams(window.location.search); const mode = params.get('_mode'); var payload = new FormData(form[0]); var $dropzoneElm = $('#evidence').closest('.dropzone'); //CHANGE THIS dz = Dropzone.forElement($dropzoneElm[0]); if (form.length == 0 || mode != 'assignment') { console.log("autoSaveJob abort"); clearInterval(autoSaveJob); return; } // skip autosave if file upload is empty or filename is same as previous one if (dz.files.length == 0 || dz.files[0].name == fileName) { console.log("autoSaveJob skipped"); return; } // replace filename if newly uploaded if (dz.files.length > 0) { console.log(dz.files[0].name); fileName = dz.files[0].name; } var submitBtn = $('#saveAsDraft'); //CHANGE THIS - the save as draft button payload.append(submitBtn.attr('id'), submitBtn.val()); console.log("autoSaveJob " + new Date()); fetch(form.attr('action') + '&' + ConnectionManager.tokenName + '=' + ConnectionManager.tokenValue, { method: form.attr('method'), body: payload }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.text(); }) .then(html => { match = html.match(/[?&]_nonce=([^&]+)/); if (match) { newValue = match[1]; console.log("found " + newValue); dzOldURL = dz.options.url; console.log("old url " + dzOldURL); dzNewURL = dzOldURL.replace(/([?&]_nonce=)[^&]*/, `$1${newValue}`); console.log("new url " + dzNewURL); dz.options.url = dzNewURL; } else { console.log('_nonce not found'); } }) .catch(error => { console.error('Error saving form:', error); }); } // Autosave form every 10 seconds autoSaveJob = setInterval(saveForm, 10 * 1000); });
- Test the functionality in the assignment (Inbox) view.
The provided script should be embedded in a Custom HTML element within your form. Here's what the script does:
Figure 3: Custom HTML on form with File uploads
- Interval Check: Every 10 seconds, the script checks whether a new file has been added to the upload field.
- Autosave Trigger: If a new, unsaved file is detected, the script automatically submits the form in the background using a fetch call to the form’s action URL.
- Nonce Refresh: After the save is completed, the _nonce value is refreshed to ensure the file upload component (dropzone) remains functional and secure.